aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/attrib.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs/attrib.c')
-rw-r--r--fs/ntfs/attrib.c719
1 files changed, 633 insertions, 86 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 1ff7f90a18b0..3f9a4ff42ee5 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * attrib.c - NTFS attribute operations. Part of the Linux-NTFS project. 2 * attrib.c - NTFS attribute operations. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2004 Anton Altaparmakov 4 * Copyright (c) 2001-2005 Anton Altaparmakov
5 * Copyright (c) 2002 Richard Russon 5 * Copyright (c) 2002 Richard Russon
6 * 6 *
7 * This program/include file is free software; you can redistribute it and/or 7 * This program/include file is free software; you can redistribute it and/or
@@ -21,88 +21,233 @@
21 */ 21 */
22 22
23#include <linux/buffer_head.h> 23#include <linux/buffer_head.h>
24#include <linux/swap.h>
24 25
25#include "attrib.h" 26#include "attrib.h"
26#include "debug.h" 27#include "debug.h"
27#include "layout.h" 28#include "layout.h"
29#include "lcnalloc.h"
30#include "malloc.h"
28#include "mft.h" 31#include "mft.h"
29#include "ntfs.h" 32#include "ntfs.h"
30#include "types.h" 33#include "types.h"
31 34
32/** 35/**
33 * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode 36 * 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 37 * @ni: ntfs inode for which to map (part of) a runlist
35 * @vcn: map runlist part containing this vcn 38 * @vcn: map runlist part containing this vcn
36 * 39 *
37 * Map the part of a runlist containing the @vcn of the ntfs inode @ni. 40 * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
38 * 41 *
39 * Return 0 on success and -errno on error. 42 * Return 0 on success and -errno on error. There is one special error code
43 * which is not an error as such. This is -ENOENT. It means that @vcn is out
44 * of bounds of the runlist.
40 * 45 *
41 * Locking: - The runlist must be unlocked on entry and is unlocked on return. 46 * Note the runlist can be NULL after this function returns if @vcn is zero and
42 * - This function takes the lock for writing and modifies the runlist. 47 * the attribute has zero allocated size, i.e. there simply is no runlist.
48 *
49 * Locking: - The runlist must be locked for writing.
50 * - This function modifies the runlist.
43 */ 51 */
44int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) 52int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
45{ 53{
54 VCN end_vcn;
46 ntfs_inode *base_ni; 55 ntfs_inode *base_ni;
56 MFT_RECORD *m;
57 ATTR_RECORD *a;
47 ntfs_attr_search_ctx *ctx; 58 ntfs_attr_search_ctx *ctx;
48 MFT_RECORD *mrec; 59 runlist_element *rl;
60 unsigned long flags;
49 int err = 0; 61 int err = 0;
50 62
51 ntfs_debug("Mapping runlist part containing vcn 0x%llx.", 63 ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
52 (unsigned long long)vcn); 64 (unsigned long long)vcn);
53
54 if (!NInoAttr(ni)) 65 if (!NInoAttr(ni))
55 base_ni = ni; 66 base_ni = ni;
56 else 67 else
57 base_ni = ni->ext.base_ntfs_ino; 68 base_ni = ni->ext.base_ntfs_ino;
58 69 m = map_mft_record(base_ni);
59 mrec = map_mft_record(base_ni); 70 if (IS_ERR(m))
60 if (IS_ERR(mrec)) 71 return PTR_ERR(m);
61 return PTR_ERR(mrec); 72 ctx = ntfs_attr_get_search_ctx(base_ni, m);
62 ctx = ntfs_attr_get_search_ctx(base_ni, mrec);
63 if (unlikely(!ctx)) { 73 if (unlikely(!ctx)) {
64 err = -ENOMEM; 74 err = -ENOMEM;
65 goto err_out; 75 goto err_out;
66 } 76 }
67 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 77 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
68 CASE_SENSITIVE, vcn, NULL, 0, ctx); 78 CASE_SENSITIVE, vcn, NULL, 0, ctx);
69 if (unlikely(err)) 79 if (unlikely(err)) {
70 goto put_err_out; 80 if (err == -ENOENT)
81 err = -EIO;
82 goto err_out;
83 }
84 a = ctx->attr;
85 /*
86 * Only decompress the mapping pairs if @vcn is inside it. Otherwise
87 * we get into problems when we try to map an out of bounds vcn because
88 * we then try to map the already mapped runlist fragment and
89 * ntfs_mapping_pairs_decompress() fails.
90 */
91 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
92 if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) {
93 read_lock_irqsave(&ni->size_lock, flags);
94 end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
95 read_unlock_irqrestore(&ni->size_lock, flags);
96 }
97 if (unlikely(vcn >= end_vcn)) {
98 err = -ENOENT;
99 goto err_out;
100 }
101 rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl);
102 if (IS_ERR(rl))
103 err = PTR_ERR(rl);
104 else
105 ni->runlist.rl = rl;
106err_out:
107 if (likely(ctx))
108 ntfs_attr_put_search_ctx(ctx);
109 unmap_mft_record(base_ni);
110 return err;
111}
112
113/**
114 * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode
115 * @ni: ntfs inode for which to map (part of) a runlist
116 * @vcn: map runlist part containing this vcn
117 *
118 * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
119 *
120 * Return 0 on success and -errno on error. There is one special error code
121 * which is not an error as such. This is -ENOENT. It means that @vcn is out
122 * of bounds of the runlist.
123 *
124 * Locking: - The runlist must be unlocked on entry and is unlocked on return.
125 * - This function takes the runlist lock for writing and modifies the
126 * runlist.
127 */
128int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
129{
130 int err = 0;
71 131
72 down_write(&ni->runlist.lock); 132 down_write(&ni->runlist.lock);
73 /* Make sure someone else didn't do the work while we were sleeping. */ 133 /* Make sure someone else didn't do the work while we were sleeping. */
74 if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <= 134 if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
75 LCN_RL_NOT_MAPPED)) { 135 LCN_RL_NOT_MAPPED))
76 runlist_element *rl; 136 err = ntfs_map_runlist_nolock(ni, vcn);
137 up_write(&ni->runlist.lock);
138 return err;
139}
77 140
78 rl = ntfs_mapping_pairs_decompress(ni->vol, ctx->attr, 141/**
79 ni->runlist.rl); 142 * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode
80 if (IS_ERR(rl)) 143 * @ni: ntfs inode of the attribute whose runlist to search
81 err = PTR_ERR(rl); 144 * @vcn: vcn to convert
82 else 145 * @write_locked: true if the runlist is locked for writing
83 ni->runlist.rl = rl; 146 *
147 * Find the virtual cluster number @vcn in the runlist of the ntfs attribute
148 * described by the ntfs inode @ni and return the corresponding logical cluster
149 * number (lcn).
150 *
151 * If the @vcn is not mapped yet, the attempt is made to map the attribute
152 * extent containing the @vcn and the vcn to lcn conversion is retried.
153 *
154 * If @write_locked is true the caller has locked the runlist for writing and
155 * if false for reading.
156 *
157 * Since lcns must be >= 0, we use negative return codes with special meaning:
158 *
159 * Return code Meaning / Description
160 * ==========================================
161 * LCN_HOLE Hole / not allocated on disk.
162 * LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds.
163 * LCN_ENOMEM Not enough memory to map runlist.
164 * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc).
165 *
166 * Locking: - The runlist must be locked on entry and is left locked on return.
167 * - If @write_locked is FALSE, i.e. the runlist is locked for reading,
168 * the lock may be dropped inside the function so you cannot rely on
169 * the runlist still being the same when this function returns.
170 */
171LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
172 const BOOL write_locked)
173{
174 LCN lcn;
175 unsigned long flags;
176 BOOL is_retry = FALSE;
177
178 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
179 ni->mft_no, (unsigned long long)vcn,
180 write_locked ? "write" : "read");
181 BUG_ON(!ni);
182 BUG_ON(!NInoNonResident(ni));
183 BUG_ON(vcn < 0);
184 if (!ni->runlist.rl) {
185 read_lock_irqsave(&ni->size_lock, flags);
186 if (!ni->allocated_size) {
187 read_unlock_irqrestore(&ni->size_lock, flags);
188 return LCN_ENOENT;
189 }
190 read_unlock_irqrestore(&ni->size_lock, flags);
84 } 191 }
85 up_write(&ni->runlist.lock); 192retry_remap:
193 /* Convert vcn to lcn. If that fails map the runlist and retry once. */
194 lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
195 if (likely(lcn >= LCN_HOLE)) {
196 ntfs_debug("Done, lcn 0x%llx.", (long long)lcn);
197 return lcn;
198 }
199 if (lcn != LCN_RL_NOT_MAPPED) {
200 if (lcn != LCN_ENOENT)
201 lcn = LCN_EIO;
202 } else if (!is_retry) {
203 int err;
86 204
87put_err_out: 205 if (!write_locked) {
88 ntfs_attr_put_search_ctx(ctx); 206 up_read(&ni->runlist.lock);
89err_out: 207 down_write(&ni->runlist.lock);
90 unmap_mft_record(base_ni); 208 if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
91 return err; 209 LCN_RL_NOT_MAPPED)) {
210 up_write(&ni->runlist.lock);
211 down_read(&ni->runlist.lock);
212 goto retry_remap;
213 }
214 }
215 err = ntfs_map_runlist_nolock(ni, vcn);
216 if (!write_locked) {
217 up_write(&ni->runlist.lock);
218 down_read(&ni->runlist.lock);
219 }
220 if (likely(!err)) {
221 is_retry = TRUE;
222 goto retry_remap;
223 }
224 if (err == -ENOENT)
225 lcn = LCN_ENOENT;
226 else if (err == -ENOMEM)
227 lcn = LCN_ENOMEM;
228 else
229 lcn = LCN_EIO;
230 }
231 if (lcn != LCN_ENOENT)
232 ntfs_error(ni->vol->sb, "Failed with error code %lli.",
233 (long long)lcn);
234 return lcn;
92} 235}
93 236
94/** 237/**
95 * ntfs_find_vcn - find a vcn in the runlist described by an ntfs inode 238 * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
96 * @ni: ntfs inode describing the runlist to search 239 * @ni: ntfs inode describing the runlist to search
97 * @vcn: vcn to find 240 * @vcn: vcn to find
98 * @need_write: if false, lock for reading and if true, lock for writing 241 * @write_locked: true if the runlist is locked for writing
99 * 242 *
100 * Find the virtual cluster number @vcn in the runlist described by the ntfs 243 * Find the virtual cluster number @vcn in the runlist described by the ntfs
101 * inode @ni and return the address of the runlist element containing the @vcn. 244 * inode @ni and return the address of the runlist element containing the @vcn.
102 * The runlist is left locked and the caller has to unlock it. If @need_write 245 *
103 * is true, the runlist is locked for writing and if @need_write is false, the 246 * If the @vcn is not mapped yet, the attempt is made to map the attribute
104 * runlist is locked for reading. In the error case, the runlist is not left 247 * extent containing the @vcn and the vcn to lcn conversion is retried.
105 * locked. 248 *
249 * If @write_locked is true the caller has locked the runlist for writing and
250 * if false for reading.
106 * 251 *
107 * Note you need to distinguish between the lcn of the returned runlist element 252 * Note you need to distinguish between the lcn of the returned runlist element
108 * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on 253 * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on
@@ -118,34 +263,38 @@ err_out:
118 * -ENOMEM - Not enough memory to map runlist. 263 * -ENOMEM - Not enough memory to map runlist.
119 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). 264 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
120 * 265 *
121 * Locking: - The runlist must be unlocked on entry. 266 * Locking: - The runlist must be locked on entry and is left locked on return.
122 * - On failing return, the runlist is unlocked. 267 * - If @write_locked is FALSE, i.e. the runlist is locked for reading,
123 * - On successful return, the runlist is locked. If @need_write us 268 * the lock may be dropped inside the function so you cannot rely on
124 * true, it is locked for writing. Otherwise is is locked for 269 * the runlist still being the same when this function returns.
125 * reading.
126 */ 270 */
127runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn, 271runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
128 const BOOL need_write) 272 const BOOL write_locked)
129{ 273{
274 unsigned long flags;
130 runlist_element *rl; 275 runlist_element *rl;
131 int err = 0; 276 int err = 0;
132 BOOL is_retry = FALSE; 277 BOOL is_retry = FALSE;
133 278
134 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, lock for %sing.", 279 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
135 ni->mft_no, (unsigned long long)vcn, 280 ni->mft_no, (unsigned long long)vcn,
136 !need_write ? "read" : "writ"); 281 write_locked ? "write" : "read");
137 BUG_ON(!ni); 282 BUG_ON(!ni);
138 BUG_ON(!NInoNonResident(ni)); 283 BUG_ON(!NInoNonResident(ni));
139 BUG_ON(vcn < 0); 284 BUG_ON(vcn < 0);
140lock_retry_remap: 285 if (!ni->runlist.rl) {
141 if (!need_write) 286 read_lock_irqsave(&ni->size_lock, flags);
142 down_read(&ni->runlist.lock); 287 if (!ni->allocated_size) {
143 else 288 read_unlock_irqrestore(&ni->size_lock, flags);
144 down_write(&ni->runlist.lock); 289 return ERR_PTR(-ENOENT);
290 }
291 read_unlock_irqrestore(&ni->size_lock, flags);
292 }
293retry_remap:
145 rl = ni->runlist.rl; 294 rl = ni->runlist.rl;
146 if (likely(rl && vcn >= rl[0].vcn)) { 295 if (likely(rl && vcn >= rl[0].vcn)) {
147 while (likely(rl->length)) { 296 while (likely(rl->length)) {
148 if (likely(vcn < rl[1].vcn)) { 297 if (unlikely(vcn < rl[1].vcn)) {
149 if (likely(rl->lcn >= LCN_HOLE)) { 298 if (likely(rl->lcn >= LCN_HOLE)) {
150 ntfs_debug("Done."); 299 ntfs_debug("Done.");
151 return rl; 300 return rl;
@@ -161,30 +310,41 @@ lock_retry_remap:
161 err = -EIO; 310 err = -EIO;
162 } 311 }
163 } 312 }
164 if (!need_write)
165 up_read(&ni->runlist.lock);
166 else
167 up_write(&ni->runlist.lock);
168 if (!err && !is_retry) { 313 if (!err && !is_retry) {
169 /* 314 /*
170 * The @vcn is in an unmapped region, map the runlist and 315 * The @vcn is in an unmapped region, map the runlist and
171 * retry. 316 * retry.
172 */ 317 */
173 err = ntfs_map_runlist(ni, vcn); 318 if (!write_locked) {
319 up_read(&ni->runlist.lock);
320 down_write(&ni->runlist.lock);
321 if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
322 LCN_RL_NOT_MAPPED)) {
323 up_write(&ni->runlist.lock);
324 down_read(&ni->runlist.lock);
325 goto retry_remap;
326 }
327 }
328 err = ntfs_map_runlist_nolock(ni, vcn);
329 if (!write_locked) {
330 up_write(&ni->runlist.lock);
331 down_read(&ni->runlist.lock);
332 }
174 if (likely(!err)) { 333 if (likely(!err)) {
175 is_retry = TRUE; 334 is_retry = TRUE;
176 goto lock_retry_remap; 335 goto retry_remap;
177 } 336 }
178 /* 337 /*
179 * -EINVAL and -ENOENT coming from a failed mapping attempt are 338 * -EINVAL coming from a failed mapping attempt is equivalent
180 * equivalent to i/o errors for us as they should not happen in 339 * to i/o error for us as it should not happen in our code
181 * our code paths. 340 * paths.
182 */ 341 */
183 if (err == -EINVAL || err == -ENOENT) 342 if (err == -EINVAL)
184 err = -EIO; 343 err = -EIO;
185 } else if (!err) 344 } else if (!err)
186 err = -EIO; 345 err = -EIO;
187 ntfs_error(ni->vol->sb, "Failed with error code %i.", err); 346 if (err != -ENOENT)
347 ntfs_error(ni->vol->sb, "Failed with error code %i.", err);
188 return ERR_PTR(err); 348 return ERR_PTR(err);
189} 349}
190 350
@@ -393,6 +553,11 @@ int load_attribute_list(ntfs_volume *vol, runlist *runlist, u8 *al_start,
393 block_size_bits = sb->s_blocksize_bits; 553 block_size_bits = sb->s_blocksize_bits;
394 down_read(&runlist->lock); 554 down_read(&runlist->lock);
395 rl = runlist->rl; 555 rl = runlist->rl;
556 if (!rl) {
557 ntfs_error(sb, "Cannot read attribute list since runlist is "
558 "missing.");
559 goto err_out;
560 }
396 /* Read all clusters specified by the runlist one run at a time. */ 561 /* Read all clusters specified by the runlist one run at a time. */
397 while (rl->length) { 562 while (rl->length) {
398 lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn); 563 lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn);
@@ -870,15 +1035,14 @@ int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
870static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx, 1035static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
871 ntfs_inode *ni, MFT_RECORD *mrec) 1036 ntfs_inode *ni, MFT_RECORD *mrec)
872{ 1037{
873 ctx->mrec = mrec; 1038 *ctx = (ntfs_attr_search_ctx) {
874 /* Sanity checks are performed elsewhere. */ 1039 .mrec = mrec,
875 ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset)); 1040 /* Sanity checks are performed elsewhere. */
876 ctx->is_first = TRUE; 1041 .attr = (ATTR_RECORD*)((u8*)mrec +
877 ctx->ntfs_ino = ni; 1042 le16_to_cpu(mrec->attrs_offset)),
878 ctx->al_entry = NULL; 1043 .is_first = TRUE,
879 ctx->base_ntfs_ino = NULL; 1044 .ntfs_ino = ni,
880 ctx->base_mrec = NULL; 1045 };
881 ctx->base_attr = NULL;
882} 1046}
883 1047
884/** 1048/**
@@ -945,6 +1109,8 @@ void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
945 return; 1109 return;
946} 1110}
947 1111
1112#ifdef NTFS_RW
1113
948/** 1114/**
949 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file 1115 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
950 * @vol: ntfs volume to which the attribute belongs 1116 * @vol: ntfs volume to which the attribute belongs
@@ -1024,27 +1190,21 @@ int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPE type,
1024 * Check whether the attribute of @type on the ntfs volume @vol is allowed to 1190 * Check whether the attribute of @type on the ntfs volume @vol is allowed to
1025 * be non-resident. This information is obtained from $AttrDef system file. 1191 * be non-resident. This information is obtained from $AttrDef system file.
1026 * 1192 *
1027 * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, or 1193 * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, and
1028 * -ENOENT if the attribute is not listed in $AttrDef. 1194 * -ENOENT if the attribute is not listed in $AttrDef.
1029 */ 1195 */
1030int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type) 1196int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1031{ 1197{
1032 ATTR_DEF *ad; 1198 ATTR_DEF *ad;
1033 1199
1034 /*
1035 * $DATA is always allowed to be non-resident even if $AttrDef does not
1036 * specify this in the flags of the $DATA attribute definition record.
1037 */
1038 if (type == AT_DATA)
1039 return 0;
1040 /* Find the attribute definition record in $AttrDef. */ 1200 /* Find the attribute definition record in $AttrDef. */
1041 ad = ntfs_attr_find_in_attrdef(vol, type); 1201 ad = ntfs_attr_find_in_attrdef(vol, type);
1042 if (unlikely(!ad)) 1202 if (unlikely(!ad))
1043 return -ENOENT; 1203 return -ENOENT;
1044 /* Check the flags and return the result. */ 1204 /* Check the flags and return the result. */
1045 if (ad->flags & CAN_BE_NON_RESIDENT) 1205 if (ad->flags & ATTR_DEF_RESIDENT)
1046 return 0; 1206 return -EPERM;
1047 return -EPERM; 1207 return 0;
1048} 1208}
1049 1209
1050/** 1210/**
@@ -1067,9 +1227,9 @@ int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1067 */ 1227 */
1068int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type) 1228int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1069{ 1229{
1070 if (type != AT_INDEX_ALLOCATION && type != AT_EA) 1230 if (type == AT_INDEX_ALLOCATION || type == AT_EA)
1071 return 0; 1231 return -EPERM;
1072 return -EPERM; 1232 return 0;
1073} 1233}
1074 1234
1075/** 1235/**
@@ -1117,6 +1277,381 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
1117} 1277}
1118 1278
1119/** 1279/**
1280 * ntfs_resident_attr_value_resize - resize the value of a resident attribute
1281 * @m: mft record containing attribute record
1282 * @a: attribute record whose value to resize
1283 * @new_size: new size in bytes to which to resize the attribute value of @a
1284 *
1285 * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
1286 * If the value is made bigger, the newly allocated space is cleared.
1287 *
1288 * Return 0 on success and -errno on error. The following error codes are
1289 * defined:
1290 * -ENOSPC - Not enough space in the mft record @m to perform the resize.
1291 *
1292 * Note: On error, no modifications have been performed whatsoever.
1293 *
1294 * Warning: If you make a record smaller without having copied all the data you
1295 * are interested in the data may be overwritten.
1296 */
1297int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
1298 const u32 new_size)
1299{
1300 u32 old_size;
1301
1302 /* Resize the resident part of the attribute record. */
1303 if (ntfs_attr_record_resize(m, a,
1304 le16_to_cpu(a->data.resident.value_offset) + new_size))
1305 return -ENOSPC;
1306 /*
1307 * The resize succeeded! If we made the attribute value bigger, clear
1308 * the area between the old size and @new_size.
1309 */
1310 old_size = le32_to_cpu(a->data.resident.value_length);
1311 if (new_size > old_size)
1312 memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
1313 old_size, 0, new_size - old_size);
1314 /* Finally update the length of the attribute value. */
1315 a->data.resident.value_length = cpu_to_le32(new_size);
1316 return 0;
1317}
1318
1319/**
1320 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
1321 * @ni: ntfs inode describing the attribute to convert
1322 *
1323 * Convert the resident ntfs attribute described by the ntfs inode @ni to a
1324 * non-resident one.
1325 *
1326 * Return 0 on success and -errno on error. The following error return codes
1327 * are defined:
1328 * -EPERM - The attribute is not allowed to be non-resident.
1329 * -ENOMEM - Not enough memory.
1330 * -ENOSPC - Not enough disk space.
1331 * -EINVAL - Attribute not defined on the volume.
1332 * -EIO - I/o error or other error.
1333 * Note that -ENOSPC is also returned in the case that there is not enough
1334 * space in the mft record to do the conversion. This can happen when the mft
1335 * record is already very full. The caller is responsible for trying to make
1336 * space in the mft record and trying again. FIXME: Do we need a separate
1337 * error return code for this kind of -ENOSPC or is it always worth trying
1338 * again in case the attribute may then fit in a resident state so no need to
1339 * make it non-resident at all? Ho-hum... (AIA)
1340 *
1341 * NOTE to self: No changes in the attribute list are required to move from
1342 * a resident to a non-resident attribute.
1343 *
1344 * Locking: - The caller must hold i_sem on the inode.
1345 */
1346int ntfs_attr_make_non_resident(ntfs_inode *ni)
1347{
1348 s64 new_size;
1349 struct inode *vi = VFS_I(ni);
1350 ntfs_volume *vol = ni->vol;
1351 ntfs_inode *base_ni;
1352 MFT_RECORD *m;
1353 ATTR_RECORD *a;
1354 ntfs_attr_search_ctx *ctx;
1355 struct page *page;
1356 runlist_element *rl;
1357 u8 *kaddr;
1358 unsigned long flags;
1359 int mp_size, mp_ofs, name_ofs, arec_size, err, err2;
1360 u32 attr_size;
1361 u8 old_res_attr_flags;
1362
1363 /* Check that the attribute is allowed to be non-resident. */
1364 err = ntfs_attr_can_be_non_resident(vol, ni->type);
1365 if (unlikely(err)) {
1366 if (err == -EPERM)
1367 ntfs_debug("Attribute is not allowed to be "
1368 "non-resident.");
1369 else
1370 ntfs_debug("Attribute not defined on the NTFS "
1371 "volume!");
1372 return err;
1373 }
1374 /*
1375 * FIXME: Compressed and encrypted attributes are not supported when
1376 * writing and we should never have gotten here for them.
1377 */
1378 BUG_ON(NInoCompressed(ni));
1379 BUG_ON(NInoEncrypted(ni));
1380 /*
1381 * The size needs to be aligned to a cluster boundary for allocation
1382 * purposes.
1383 */
1384 new_size = (i_size_read(vi) + vol->cluster_size - 1) &
1385 ~(vol->cluster_size - 1);
1386 if (new_size > 0) {
1387 runlist_element *rl2;
1388
1389 /*
1390 * Will need the page later and since the page lock nests
1391 * outside all ntfs locks, we need to get the page now.
1392 */
1393 page = find_or_create_page(vi->i_mapping, 0,
1394 mapping_gfp_mask(vi->i_mapping));
1395 if (unlikely(!page))
1396 return -ENOMEM;
1397 /* Start by allocating clusters to hold the attribute value. */
1398 rl = ntfs_cluster_alloc(vol, 0, new_size >>
1399 vol->cluster_size_bits, -1, DATA_ZONE);
1400 if (IS_ERR(rl)) {
1401 err = PTR_ERR(rl);
1402 ntfs_debug("Failed to allocate cluster%s, error code "
1403 "%i.", (new_size >>
1404 vol->cluster_size_bits) > 1 ? "s" : "",
1405 err);
1406 goto page_err_out;
1407 }
1408 /* Change the runlist terminator to LCN_ENOENT. */
1409 rl2 = rl;
1410 while (rl2->length)
1411 rl2++;
1412 BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
1413 rl2->lcn = LCN_ENOENT;
1414 } else {
1415 rl = NULL;
1416 page = NULL;
1417 }
1418 /* Determine the size of the mapping pairs array. */
1419 mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1);
1420 if (unlikely(mp_size < 0)) {
1421 err = mp_size;
1422 ntfs_debug("Failed to get size for mapping pairs array, error "
1423 "code %i.", err);
1424 goto rl_err_out;
1425 }
1426 down_write(&ni->runlist.lock);
1427 if (!NInoAttr(ni))
1428 base_ni = ni;
1429 else
1430 base_ni = ni->ext.base_ntfs_ino;
1431 m = map_mft_record(base_ni);
1432 if (IS_ERR(m)) {
1433 err = PTR_ERR(m);
1434 m = NULL;
1435 ctx = NULL;
1436 goto err_out;
1437 }
1438 ctx = ntfs_attr_get_search_ctx(base_ni, m);
1439 if (unlikely(!ctx)) {
1440 err = -ENOMEM;
1441 goto err_out;
1442 }
1443 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
1444 CASE_SENSITIVE, 0, NULL, 0, ctx);
1445 if (unlikely(err)) {
1446 if (err == -ENOENT)
1447 err = -EIO;
1448 goto err_out;
1449 }
1450 m = ctx->mrec;
1451 a = ctx->attr;
1452 BUG_ON(NInoNonResident(ni));
1453 BUG_ON(a->non_resident);
1454 /*
1455 * Calculate new offsets for the name and the mapping pairs array.
1456 */
1457 if (NInoSparse(ni) || NInoCompressed(ni))
1458 name_ofs = (offsetof(ATTR_REC,
1459 data.non_resident.compressed_size) +
1460 sizeof(a->data.non_resident.compressed_size) +
1461 7) & ~7;
1462 else
1463 name_ofs = (offsetof(ATTR_REC,
1464 data.non_resident.compressed_size) + 7) & ~7;
1465 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
1466 /*
1467 * Determine the size of the resident part of the now non-resident
1468 * attribute record.
1469 */
1470 arec_size = (mp_ofs + mp_size + 7) & ~7;
1471 /*
1472 * If the page is not uptodate bring it uptodate by copying from the
1473 * attribute value.
1474 */
1475 attr_size = le32_to_cpu(a->data.resident.value_length);
1476 BUG_ON(attr_size != i_size_read(vi));
1477 if (page && !PageUptodate(page)) {
1478 kaddr = kmap_atomic(page, KM_USER0);
1479 memcpy(kaddr, (u8*)a +
1480 le16_to_cpu(a->data.resident.value_offset),
1481 attr_size);
1482 memset(kaddr + attr_size, 0, PAGE_CACHE_SIZE - attr_size);
1483 kunmap_atomic(kaddr, KM_USER0);
1484 flush_dcache_page(page);
1485 SetPageUptodate(page);
1486 }
1487 /* Backup the attribute flag. */
1488 old_res_attr_flags = a->data.resident.flags;
1489 /* Resize the resident part of the attribute record. */
1490 err = ntfs_attr_record_resize(m, a, arec_size);
1491 if (unlikely(err))
1492 goto err_out;
1493 /*
1494 * Convert the resident part of the attribute record to describe a
1495 * non-resident attribute.
1496 */
1497 a->non_resident = 1;
1498 /* Move the attribute name if it exists and update the offset. */
1499 if (a->name_length)
1500 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
1501 a->name_length * sizeof(ntfschar));
1502 a->name_offset = cpu_to_le16(name_ofs);
1503 /* Setup the fields specific to non-resident attributes. */
1504 a->data.non_resident.lowest_vcn = 0;
1505 a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
1506 vol->cluster_size_bits);
1507 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
1508 memset(&a->data.non_resident.reserved, 0,
1509 sizeof(a->data.non_resident.reserved));
1510 a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
1511 a->data.non_resident.data_size =
1512 a->data.non_resident.initialized_size =
1513 cpu_to_sle64(attr_size);
1514 if (NInoSparse(ni) || NInoCompressed(ni)) {
1515 a->data.non_resident.compression_unit = 4;
1516 a->data.non_resident.compressed_size =
1517 a->data.non_resident.allocated_size;
1518 } else
1519 a->data.non_resident.compression_unit = 0;
1520 /* Generate the mapping pairs array into the attribute record. */
1521 err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
1522 arec_size - mp_ofs, rl, 0, -1, NULL);
1523 if (unlikely(err)) {
1524 ntfs_debug("Failed to build mapping pairs, error code %i.",
1525 err);
1526 goto undo_err_out;
1527 }
1528 /* Setup the in-memory attribute structure to be non-resident. */
1529 ni->runlist.rl = rl;
1530 write_lock_irqsave(&ni->size_lock, flags);
1531 ni->allocated_size = new_size;
1532 if (NInoSparse(ni) || NInoCompressed(ni)) {
1533 ni->itype.compressed.size = ni->allocated_size;
1534 ni->itype.compressed.block_size = 1U <<
1535 (a->data.non_resident.compression_unit +
1536 vol->cluster_size_bits);
1537 ni->itype.compressed.block_size_bits =
1538 ffs(ni->itype.compressed.block_size) - 1;
1539 ni->itype.compressed.block_clusters = 1U <<
1540 a->data.non_resident.compression_unit;
1541 }
1542 write_unlock_irqrestore(&ni->size_lock, flags);
1543 /*
1544 * This needs to be last since the address space operations ->readpage
1545 * and ->writepage can run concurrently with us as they are not
1546 * serialized on i_sem. Note, we are not allowed to fail once we flip
1547 * this switch, which is another reason to do this last.
1548 */
1549 NInoSetNonResident(ni);
1550 /* Mark the mft record dirty, so it gets written back. */
1551 flush_dcache_mft_record_page(ctx->ntfs_ino);
1552 mark_mft_record_dirty(ctx->ntfs_ino);
1553 ntfs_attr_put_search_ctx(ctx);
1554 unmap_mft_record(base_ni);
1555 up_write(&ni->runlist.lock);
1556 if (page) {
1557 set_page_dirty(page);
1558 unlock_page(page);
1559 mark_page_accessed(page);
1560 page_cache_release(page);
1561 }
1562 ntfs_debug("Done.");
1563 return 0;
1564undo_err_out:
1565 /* Convert the attribute back into a resident attribute. */
1566 a->non_resident = 0;
1567 /* Move the attribute name if it exists and update the offset. */
1568 name_ofs = (offsetof(ATTR_RECORD, data.resident.reserved) +
1569 sizeof(a->data.resident.reserved) + 7) & ~7;
1570 if (a->name_length)
1571 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
1572 a->name_length * sizeof(ntfschar));
1573 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
1574 a->name_offset = cpu_to_le16(name_ofs);
1575 arec_size = (mp_ofs + attr_size + 7) & ~7;
1576 /* Resize the resident part of the attribute record. */
1577 err2 = ntfs_attr_record_resize(m, a, arec_size);
1578 if (unlikely(err2)) {
1579 /*
1580 * This cannot happen (well if memory corruption is at work it
1581 * could happen in theory), but deal with it as well as we can.
1582 * If the old size is too small, truncate the attribute,
1583 * otherwise simply give it a larger allocated size.
1584 * FIXME: Should check whether chkdsk complains when the
1585 * allocated size is much bigger than the resident value size.
1586 */
1587 arec_size = le32_to_cpu(a->length);
1588 if ((mp_ofs + attr_size) > arec_size) {
1589 err2 = attr_size;
1590 attr_size = arec_size - mp_ofs;
1591 ntfs_error(vol->sb, "Failed to undo partial resident "
1592 "to non-resident attribute "
1593 "conversion. Truncating inode 0x%lx, "
1594 "attribute type 0x%x from %i bytes to "
1595 "%i bytes to maintain metadata "
1596 "consistency. THIS MEANS YOU ARE "
1597 "LOSING %i BYTES DATA FROM THIS %s.",
1598 vi->i_ino,
1599 (unsigned)le32_to_cpu(ni->type),
1600 err2, attr_size, err2 - attr_size,
1601 ((ni->type == AT_DATA) &&
1602 !ni->name_len) ? "FILE": "ATTRIBUTE");
1603 write_lock_irqsave(&ni->size_lock, flags);
1604 ni->initialized_size = attr_size;
1605 i_size_write(vi, attr_size);
1606 write_unlock_irqrestore(&ni->size_lock, flags);
1607 }
1608 }
1609 /* Setup the fields specific to resident attributes. */
1610 a->data.resident.value_length = cpu_to_le32(attr_size);
1611 a->data.resident.value_offset = cpu_to_le16(mp_ofs);
1612 a->data.resident.flags = old_res_attr_flags;
1613 memset(&a->data.resident.reserved, 0,
1614 sizeof(a->data.resident.reserved));
1615 /* Copy the data from the page back to the attribute value. */
1616 if (page) {
1617 kaddr = kmap_atomic(page, KM_USER0);
1618 memcpy((u8*)a + mp_ofs, kaddr, attr_size);
1619 kunmap_atomic(kaddr, KM_USER0);
1620 }
1621 /* Setup the allocated size in the ntfs inode in case it changed. */
1622 write_lock_irqsave(&ni->size_lock, flags);
1623 ni->allocated_size = arec_size - mp_ofs;
1624 write_unlock_irqrestore(&ni->size_lock, flags);
1625 /* Mark the mft record dirty, so it gets written back. */
1626 flush_dcache_mft_record_page(ctx->ntfs_ino);
1627 mark_mft_record_dirty(ctx->ntfs_ino);
1628err_out:
1629 if (ctx)
1630 ntfs_attr_put_search_ctx(ctx);
1631 if (m)
1632 unmap_mft_record(base_ni);
1633 ni->runlist.rl = NULL;
1634 up_write(&ni->runlist.lock);
1635rl_err_out:
1636 if (rl) {
1637 if (ntfs_cluster_free_from_rl(vol, rl) < 0) {
1638 ntfs_error(vol->sb, "Failed to release allocated "
1639 "cluster(s) in error code path. Run "
1640 "chkdsk to recover the lost "
1641 "cluster(s).");
1642 NVolSetErrors(vol);
1643 }
1644 ntfs_free(rl);
1645page_err_out:
1646 unlock_page(page);
1647 page_cache_release(page);
1648 }
1649 if (err == -EINVAL)
1650 err = -EIO;
1651 return err;
1652}
1653
1654/**
1120 * ntfs_attr_set - fill (a part of) an attribute with a byte 1655 * ntfs_attr_set - fill (a part of) an attribute with a byte
1121 * @ni: ntfs inode describing the attribute to fill 1656 * @ni: ntfs inode describing the attribute to fill
1122 * @ofs: offset inside the attribute at which to start to fill 1657 * @ofs: offset inside the attribute at which to start to fill
@@ -1127,6 +1662,10 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
1127 * byte offset @ofs inside the attribute with the constant byte @val. 1662 * byte offset @ofs inside the attribute with the constant byte @val.
1128 * 1663 *
1129 * This function is effectively like memset() applied to an ntfs attribute. 1664 * This function is effectively like memset() applied to an ntfs attribute.
1665 * Note thie function actually only operates on the page cache pages belonging
1666 * to the ntfs attribute and it marks them dirty after doing the memset().
1667 * Thus it relies on the vm dirty page write code paths to cause the modified
1668 * pages to be written to the mft record/disk.
1130 * 1669 *
1131 * Return 0 on success and -errno on error. An error code of -ESPIPE means 1670 * Return 0 on success and -errno on error. An error code of -ESPIPE means
1132 * that @ofs + @cnt were outside the end of the attribute and no write was 1671 * that @ofs + @cnt were outside the end of the attribute and no write was
@@ -1147,6 +1686,12 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
1147 BUG_ON(cnt < 0); 1686 BUG_ON(cnt < 0);
1148 if (!cnt) 1687 if (!cnt)
1149 goto done; 1688 goto done;
1689 /*
1690 * FIXME: Compressed and encrypted attributes are not supported when
1691 * writing and we should never have gotten here for them.
1692 */
1693 BUG_ON(NInoCompressed(ni));
1694 BUG_ON(NInoEncrypted(ni));
1150 mapping = VFS_I(ni)->i_mapping; 1695 mapping = VFS_I(ni)->i_mapping;
1151 /* Work out the starting index and page offset. */ 1696 /* Work out the starting index and page offset. */
1152 idx = ofs >> PAGE_CACHE_SHIFT; 1697 idx = ofs >> PAGE_CACHE_SHIFT;
@@ -1155,7 +1700,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
1155 end = ofs + cnt; 1700 end = ofs + cnt;
1156 end_ofs = end & ~PAGE_CACHE_MASK; 1701 end_ofs = end & ~PAGE_CACHE_MASK;
1157 /* If the end is outside the inode size return -ESPIPE. */ 1702 /* If the end is outside the inode size return -ESPIPE. */
1158 if (unlikely(end > VFS_I(ni)->i_size)) { 1703 if (unlikely(end > i_size_read(VFS_I(ni)))) {
1159 ntfs_error(vol->sb, "Request exceeds end of attribute."); 1704 ntfs_error(vol->sb, "Request exceeds end of attribute.");
1160 return -ESPIPE; 1705 return -ESPIPE;
1161 } 1706 }
@@ -1256,3 +1801,5 @@ done:
1256 ntfs_debug("Done."); 1801 ntfs_debug("Done.");
1257 return 0; 1802 return 0;
1258} 1803}
1804
1805#endif /* NTFS_RW */