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.c630
1 files changed, 544 insertions, 86 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 1ff7f90a18b0..cd0f9e740b14 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,217 @@
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 * Locking: - The runlist must be locked for writing.
42 * - This function takes the lock for writing and modifies the runlist. 47 * - This function modifies the runlist.
43 */ 48 */
44int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) 49int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
45{ 50{
51 VCN end_vcn;
46 ntfs_inode *base_ni; 52 ntfs_inode *base_ni;
53 MFT_RECORD *m;
54 ATTR_RECORD *a;
47 ntfs_attr_search_ctx *ctx; 55 ntfs_attr_search_ctx *ctx;
48 MFT_RECORD *mrec; 56 runlist_element *rl;
49 int err = 0; 57 int err = 0;
50 58
51 ntfs_debug("Mapping runlist part containing vcn 0x%llx.", 59 ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
52 (unsigned long long)vcn); 60 (unsigned long long)vcn);
53
54 if (!NInoAttr(ni)) 61 if (!NInoAttr(ni))
55 base_ni = ni; 62 base_ni = ni;
56 else 63 else
57 base_ni = ni->ext.base_ntfs_ino; 64 base_ni = ni->ext.base_ntfs_ino;
58 65 m = map_mft_record(base_ni);
59 mrec = map_mft_record(base_ni); 66 if (IS_ERR(m))
60 if (IS_ERR(mrec)) 67 return PTR_ERR(m);
61 return PTR_ERR(mrec); 68 ctx = ntfs_attr_get_search_ctx(base_ni, m);
62 ctx = ntfs_attr_get_search_ctx(base_ni, mrec);
63 if (unlikely(!ctx)) { 69 if (unlikely(!ctx)) {
64 err = -ENOMEM; 70 err = -ENOMEM;
65 goto err_out; 71 goto err_out;
66 } 72 }
67 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 73 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
68 CASE_SENSITIVE, vcn, NULL, 0, ctx); 74 CASE_SENSITIVE, vcn, NULL, 0, ctx);
69 if (unlikely(err)) 75 if (unlikely(err)) {
70 goto put_err_out; 76 if (err == -ENOENT)
77 err = -EIO;
78 goto err_out;
79 }
80 a = ctx->attr;
81 /*
82 * Only decompress the mapping pairs if @vcn is inside it. Otherwise
83 * we get into problems when we try to map an out of bounds vcn because
84 * we then try to map the already mapped runlist fragment and
85 * ntfs_mapping_pairs_decompress() fails.
86 */
87 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
88 if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1))
89 end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
90 if (unlikely(vcn >= end_vcn)) {
91 err = -ENOENT;
92 goto err_out;
93 }
94 rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl);
95 if (IS_ERR(rl))
96 err = PTR_ERR(rl);
97 else
98 ni->runlist.rl = rl;
99err_out:
100 if (likely(ctx))
101 ntfs_attr_put_search_ctx(ctx);
102 unmap_mft_record(base_ni);
103 return err;
104}
105
106/**
107 * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode
108 * @ni: ntfs inode for which to map (part of) a runlist
109 * @vcn: map runlist part containing this vcn
110 *
111 * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
112 *
113 * Return 0 on success and -errno on error. There is one special error code
114 * which is not an error as such. This is -ENOENT. It means that @vcn is out
115 * of bounds of the runlist.
116 *
117 * Locking: - The runlist must be unlocked on entry and is unlocked on return.
118 * - This function takes the runlist lock for writing and modifies the
119 * runlist.
120 */
121int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
122{
123 int err = 0;
71 124
72 down_write(&ni->runlist.lock); 125 down_write(&ni->runlist.lock);
73 /* Make sure someone else didn't do the work while we were sleeping. */ 126 /* 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) <= 127 if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
75 LCN_RL_NOT_MAPPED)) { 128 LCN_RL_NOT_MAPPED))
76 runlist_element *rl; 129 err = ntfs_map_runlist_nolock(ni, vcn);
130 up_write(&ni->runlist.lock);
131 return err;
132}
77 133
78 rl = ntfs_mapping_pairs_decompress(ni->vol, ctx->attr, 134/**
79 ni->runlist.rl); 135 * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode
80 if (IS_ERR(rl)) 136 * @ni: ntfs inode of the attribute whose runlist to search
81 err = PTR_ERR(rl); 137 * @vcn: vcn to convert
82 else 138 * @write_locked: true if the runlist is locked for writing
83 ni->runlist.rl = rl; 139 *
140 * Find the virtual cluster number @vcn in the runlist of the ntfs attribute
141 * described by the ntfs inode @ni and return the corresponding logical cluster
142 * number (lcn).
143 *
144 * If the @vcn is not mapped yet, the attempt is made to map the attribute
145 * extent containing the @vcn and the vcn to lcn conversion is retried.
146 *
147 * If @write_locked is true the caller has locked the runlist for writing and
148 * if false for reading.
149 *
150 * Since lcns must be >= 0, we use negative return codes with special meaning:
151 *
152 * Return code Meaning / Description
153 * ==========================================
154 * LCN_HOLE Hole / not allocated on disk.
155 * LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds.
156 * LCN_ENOMEM Not enough memory to map runlist.
157 * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc).
158 *
159 * Locking: - The runlist must be locked on entry and is left locked on return.
160 * - If @write_locked is FALSE, i.e. the runlist is locked for reading,
161 * the lock may be dropped inside the function so you cannot rely on
162 * the runlist still being the same when this function returns.
163 */
164LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
165 const BOOL write_locked)
166{
167 LCN lcn;
168 BOOL is_retry = FALSE;
169
170 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
171 ni->mft_no, (unsigned long long)vcn,
172 write_locked ? "write" : "read");
173 BUG_ON(!ni);
174 BUG_ON(!NInoNonResident(ni));
175 BUG_ON(vcn < 0);
176retry_remap:
177 /* Convert vcn to lcn. If that fails map the runlist and retry once. */
178 lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
179 if (likely(lcn >= LCN_HOLE)) {
180 ntfs_debug("Done, lcn 0x%llx.", (long long)lcn);
181 return lcn;
84 } 182 }
85 up_write(&ni->runlist.lock); 183 if (lcn != LCN_RL_NOT_MAPPED) {
184 if (lcn != LCN_ENOENT)
185 lcn = LCN_EIO;
186 } else if (!is_retry) {
187 int err;
86 188
87put_err_out: 189 if (!write_locked) {
88 ntfs_attr_put_search_ctx(ctx); 190 up_read(&ni->runlist.lock);
89err_out: 191 down_write(&ni->runlist.lock);
90 unmap_mft_record(base_ni); 192 if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
91 return err; 193 LCN_RL_NOT_MAPPED)) {
194 up_write(&ni->runlist.lock);
195 down_read(&ni->runlist.lock);
196 goto retry_remap;
197 }
198 }
199 err = ntfs_map_runlist_nolock(ni, vcn);
200 if (!write_locked) {
201 up_write(&ni->runlist.lock);
202 down_read(&ni->runlist.lock);
203 }
204 if (likely(!err)) {
205 is_retry = TRUE;
206 goto retry_remap;
207 }
208 if (err == -ENOENT)
209 lcn = LCN_ENOENT;
210 else if (err == -ENOMEM)
211 lcn = LCN_ENOMEM;
212 else
213 lcn = LCN_EIO;
214 }
215 if (lcn != LCN_ENOENT)
216 ntfs_error(ni->vol->sb, "Failed with error code %lli.",
217 (long long)lcn);
218 return lcn;
92} 219}
93 220
94/** 221/**
95 * ntfs_find_vcn - find a vcn in the runlist described by an ntfs inode 222 * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
96 * @ni: ntfs inode describing the runlist to search 223 * @ni: ntfs inode describing the runlist to search
97 * @vcn: vcn to find 224 * @vcn: vcn to find
98 * @need_write: if false, lock for reading and if true, lock for writing 225 * @write_locked: true if the runlist is locked for writing
99 * 226 *
100 * Find the virtual cluster number @vcn in the runlist described by the ntfs 227 * 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. 228 * 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 229 *
103 * is true, the runlist is locked for writing and if @need_write is false, the 230 * 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 231 * extent containing the @vcn and the vcn to lcn conversion is retried.
105 * locked. 232 *
233 * If @write_locked is true the caller has locked the runlist for writing and
234 * if false for reading.
106 * 235 *
107 * Note you need to distinguish between the lcn of the returned runlist element 236 * 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 237 * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on
@@ -118,34 +247,29 @@ err_out:
118 * -ENOMEM - Not enough memory to map runlist. 247 * -ENOMEM - Not enough memory to map runlist.
119 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). 248 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
120 * 249 *
121 * Locking: - The runlist must be unlocked on entry. 250 * Locking: - The runlist must be locked on entry and is left locked on return.
122 * - On failing return, the runlist is unlocked. 251 * - 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 252 * 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 253 * the runlist still being the same when this function returns.
125 * reading.
126 */ 254 */
127runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn, 255runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
128 const BOOL need_write) 256 const BOOL write_locked)
129{ 257{
130 runlist_element *rl; 258 runlist_element *rl;
131 int err = 0; 259 int err = 0;
132 BOOL is_retry = FALSE; 260 BOOL is_retry = FALSE;
133 261
134 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, lock for %sing.", 262 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
135 ni->mft_no, (unsigned long long)vcn, 263 ni->mft_no, (unsigned long long)vcn,
136 !need_write ? "read" : "writ"); 264 write_locked ? "write" : "read");
137 BUG_ON(!ni); 265 BUG_ON(!ni);
138 BUG_ON(!NInoNonResident(ni)); 266 BUG_ON(!NInoNonResident(ni));
139 BUG_ON(vcn < 0); 267 BUG_ON(vcn < 0);
140lock_retry_remap: 268retry_remap:
141 if (!need_write)
142 down_read(&ni->runlist.lock);
143 else
144 down_write(&ni->runlist.lock);
145 rl = ni->runlist.rl; 269 rl = ni->runlist.rl;
146 if (likely(rl && vcn >= rl[0].vcn)) { 270 if (likely(rl && vcn >= rl[0].vcn)) {
147 while (likely(rl->length)) { 271 while (likely(rl->length)) {
148 if (likely(vcn < rl[1].vcn)) { 272 if (unlikely(vcn < rl[1].vcn)) {
149 if (likely(rl->lcn >= LCN_HOLE)) { 273 if (likely(rl->lcn >= LCN_HOLE)) {
150 ntfs_debug("Done."); 274 ntfs_debug("Done.");
151 return rl; 275 return rl;
@@ -161,30 +285,41 @@ lock_retry_remap:
161 err = -EIO; 285 err = -EIO;
162 } 286 }
163 } 287 }
164 if (!need_write)
165 up_read(&ni->runlist.lock);
166 else
167 up_write(&ni->runlist.lock);
168 if (!err && !is_retry) { 288 if (!err && !is_retry) {
169 /* 289 /*
170 * The @vcn is in an unmapped region, map the runlist and 290 * The @vcn is in an unmapped region, map the runlist and
171 * retry. 291 * retry.
172 */ 292 */
173 err = ntfs_map_runlist(ni, vcn); 293 if (!write_locked) {
294 up_read(&ni->runlist.lock);
295 down_write(&ni->runlist.lock);
296 if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
297 LCN_RL_NOT_MAPPED)) {
298 up_write(&ni->runlist.lock);
299 down_read(&ni->runlist.lock);
300 goto retry_remap;
301 }
302 }
303 err = ntfs_map_runlist_nolock(ni, vcn);
304 if (!write_locked) {
305 up_write(&ni->runlist.lock);
306 down_read(&ni->runlist.lock);
307 }
174 if (likely(!err)) { 308 if (likely(!err)) {
175 is_retry = TRUE; 309 is_retry = TRUE;
176 goto lock_retry_remap; 310 goto retry_remap;
177 } 311 }
178 /* 312 /*
179 * -EINVAL and -ENOENT coming from a failed mapping attempt are 313 * -EINVAL coming from a failed mapping attempt is equivalent
180 * equivalent to i/o errors for us as they should not happen in 314 * to i/o error for us as it should not happen in our code
181 * our code paths. 315 * paths.
182 */ 316 */
183 if (err == -EINVAL || err == -ENOENT) 317 if (err == -EINVAL)
184 err = -EIO; 318 err = -EIO;
185 } else if (!err) 319 } else if (!err)
186 err = -EIO; 320 err = -EIO;
187 ntfs_error(ni->vol->sb, "Failed with error code %i.", err); 321 if (err != -ENOENT)
322 ntfs_error(ni->vol->sb, "Failed with error code %i.", err);
188 return ERR_PTR(err); 323 return ERR_PTR(err);
189} 324}
190 325
@@ -870,15 +1005,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, 1005static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
871 ntfs_inode *ni, MFT_RECORD *mrec) 1006 ntfs_inode *ni, MFT_RECORD *mrec)
872{ 1007{
873 ctx->mrec = mrec; 1008 *ctx = (ntfs_attr_search_ctx) {
874 /* Sanity checks are performed elsewhere. */ 1009 .mrec = mrec,
875 ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset)); 1010 /* Sanity checks are performed elsewhere. */
876 ctx->is_first = TRUE; 1011 .attr = (ATTR_RECORD*)((u8*)mrec +
877 ctx->ntfs_ino = ni; 1012 le16_to_cpu(mrec->attrs_offset)),
878 ctx->al_entry = NULL; 1013 .is_first = TRUE,
879 ctx->base_ntfs_ino = NULL; 1014 .ntfs_ino = ni,
880 ctx->base_mrec = NULL; 1015 };
881 ctx->base_attr = NULL;
882} 1016}
883 1017
884/** 1018/**
@@ -945,6 +1079,8 @@ void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
945 return; 1079 return;
946} 1080}
947 1081
1082#ifdef NTFS_RW
1083
948/** 1084/**
949 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file 1085 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
950 * @vol: ntfs volume to which the attribute belongs 1086 * @vol: ntfs volume to which the attribute belongs
@@ -1024,27 +1160,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 1160 * 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. 1161 * be non-resident. This information is obtained from $AttrDef system file.
1026 * 1162 *
1027 * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, or 1163 * 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. 1164 * -ENOENT if the attribute is not listed in $AttrDef.
1029 */ 1165 */
1030int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type) 1166int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1031{ 1167{
1032 ATTR_DEF *ad; 1168 ATTR_DEF *ad;
1033 1169
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. */ 1170 /* Find the attribute definition record in $AttrDef. */
1041 ad = ntfs_attr_find_in_attrdef(vol, type); 1171 ad = ntfs_attr_find_in_attrdef(vol, type);
1042 if (unlikely(!ad)) 1172 if (unlikely(!ad))
1043 return -ENOENT; 1173 return -ENOENT;
1044 /* Check the flags and return the result. */ 1174 /* Check the flags and return the result. */
1045 if (ad->flags & CAN_BE_NON_RESIDENT) 1175 if (ad->flags & ATTR_DEF_RESIDENT)
1046 return 0; 1176 return -EPERM;
1047 return -EPERM; 1177 return 0;
1048} 1178}
1049 1179
1050/** 1180/**
@@ -1067,9 +1197,9 @@ int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1067 */ 1197 */
1068int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type) 1198int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1069{ 1199{
1070 if (type != AT_INDEX_ALLOCATION && type != AT_EA) 1200 if (type == AT_INDEX_ALLOCATION || type == AT_EA)
1071 return 0; 1201 return -EPERM;
1072 return -EPERM; 1202 return 0;
1073} 1203}
1074 1204
1075/** 1205/**
@@ -1117,6 +1247,328 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
1117} 1247}
1118 1248
1119/** 1249/**
1250 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
1251 * @ni: ntfs inode describing the attribute to convert
1252 *
1253 * Convert the resident ntfs attribute described by the ntfs inode @ni to a
1254 * non-resident one.
1255 *
1256 * Return 0 on success and -errno on error. The following error return codes
1257 * are defined:
1258 * -EPERM - The attribute is not allowed to be non-resident.
1259 * -ENOMEM - Not enough memory.
1260 * -ENOSPC - Not enough disk space.
1261 * -EINVAL - Attribute not defined on the volume.
1262 * -EIO - I/o error or other error.
1263 * Note that -ENOSPC is also returned in the case that there is not enough
1264 * space in the mft record to do the conversion. This can happen when the mft
1265 * record is already very full. The caller is responsible for trying to make
1266 * space in the mft record and trying again. FIXME: Do we need a separate
1267 * error return code for this kind of -ENOSPC or is it always worth trying
1268 * again in case the attribute may then fit in a resident state so no need to
1269 * make it non-resident at all? Ho-hum... (AIA)
1270 *
1271 * NOTE to self: No changes in the attribute list are required to move from
1272 * a resident to a non-resident attribute.
1273 *
1274 * Locking: - The caller must hold i_sem on the inode.
1275 */
1276int ntfs_attr_make_non_resident(ntfs_inode *ni)
1277{
1278 s64 new_size;
1279 struct inode *vi = VFS_I(ni);
1280 ntfs_volume *vol = ni->vol;
1281 ntfs_inode *base_ni;
1282 MFT_RECORD *m;
1283 ATTR_RECORD *a;
1284 ntfs_attr_search_ctx *ctx;
1285 struct page *page;
1286 runlist_element *rl;
1287 u8 *kaddr;
1288 unsigned long flags;
1289 int mp_size, mp_ofs, name_ofs, arec_size, err, err2;
1290 u32 attr_size;
1291 u8 old_res_attr_flags;
1292
1293 /* Check that the attribute is allowed to be non-resident. */
1294 err = ntfs_attr_can_be_non_resident(vol, ni->type);
1295 if (unlikely(err)) {
1296 if (err == -EPERM)
1297 ntfs_debug("Attribute is not allowed to be "
1298 "non-resident.");
1299 else
1300 ntfs_debug("Attribute not defined on the NTFS "
1301 "volume!");
1302 return err;
1303 }
1304 /*
1305 * The size needs to be aligned to a cluster boundary for allocation
1306 * purposes.
1307 */
1308 new_size = (i_size_read(vi) + vol->cluster_size - 1) &
1309 ~(vol->cluster_size - 1);
1310 if (new_size > 0) {
1311 runlist_element *rl2;
1312
1313 /*
1314 * Will need the page later and since the page lock nests
1315 * outside all ntfs locks, we need to get the page now.
1316 */
1317 page = find_or_create_page(vi->i_mapping, 0,
1318 mapping_gfp_mask(vi->i_mapping));
1319 if (unlikely(!page))
1320 return -ENOMEM;
1321 /* Start by allocating clusters to hold the attribute value. */
1322 rl = ntfs_cluster_alloc(vol, 0, new_size >>
1323 vol->cluster_size_bits, -1, DATA_ZONE);
1324 if (IS_ERR(rl)) {
1325 err = PTR_ERR(rl);
1326 ntfs_debug("Failed to allocate cluster%s, error code "
1327 "%i.", (new_size >>
1328 vol->cluster_size_bits) > 1 ? "s" : "",
1329 err);
1330 goto page_err_out;
1331 }
1332 /* Change the runlist terminator to LCN_ENOENT. */
1333 rl2 = rl;
1334 while (rl2->length)
1335 rl2++;
1336 BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
1337 rl2->lcn = LCN_ENOENT;
1338 } else {
1339 rl = NULL;
1340 page = NULL;
1341 }
1342 /* Determine the size of the mapping pairs array. */
1343 mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1);
1344 if (unlikely(mp_size < 0)) {
1345 err = mp_size;
1346 ntfs_debug("Failed to get size for mapping pairs array, error "
1347 "code %i.", err);
1348 goto rl_err_out;
1349 }
1350 down_write(&ni->runlist.lock);
1351 if (!NInoAttr(ni))
1352 base_ni = ni;
1353 else
1354 base_ni = ni->ext.base_ntfs_ino;
1355 m = map_mft_record(base_ni);
1356 if (IS_ERR(m)) {
1357 err = PTR_ERR(m);
1358 m = NULL;
1359 ctx = NULL;
1360 goto err_out;
1361 }
1362 ctx = ntfs_attr_get_search_ctx(base_ni, m);
1363 if (unlikely(!ctx)) {
1364 err = -ENOMEM;
1365 goto err_out;
1366 }
1367 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
1368 CASE_SENSITIVE, 0, NULL, 0, ctx);
1369 if (unlikely(err)) {
1370 if (err == -ENOENT)
1371 err = -EIO;
1372 goto err_out;
1373 }
1374 m = ctx->mrec;
1375 a = ctx->attr;
1376 BUG_ON(NInoNonResident(ni));
1377 BUG_ON(a->non_resident);
1378 /*
1379 * Calculate new offsets for the name and the mapping pairs array.
1380 * We assume the attribute is not compressed or sparse.
1381 */
1382 name_ofs = (offsetof(ATTR_REC,
1383 data.non_resident.compressed_size) + 7) & ~7;
1384 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
1385 /*
1386 * Determine the size of the resident part of the now non-resident
1387 * attribute record.
1388 */
1389 arec_size = (mp_ofs + mp_size + 7) & ~7;
1390 /*
1391 * If the page is not uptodate bring it uptodate by copying from the
1392 * attribute value.
1393 */
1394 attr_size = le32_to_cpu(a->data.resident.value_length);
1395 BUG_ON(attr_size != i_size_read(vi));
1396 if (page && !PageUptodate(page)) {
1397 kaddr = kmap_atomic(page, KM_USER0);
1398 memcpy(kaddr, (u8*)a +
1399 le16_to_cpu(a->data.resident.value_offset),
1400 attr_size);
1401 memset(kaddr + attr_size, 0, PAGE_CACHE_SIZE - attr_size);
1402 kunmap_atomic(kaddr, KM_USER0);
1403 flush_dcache_page(page);
1404 SetPageUptodate(page);
1405 }
1406 /* Backup the attribute flag. */
1407 old_res_attr_flags = a->data.resident.flags;
1408 /* Resize the resident part of the attribute record. */
1409 err = ntfs_attr_record_resize(m, a, arec_size);
1410 if (unlikely(err))
1411 goto err_out;
1412 /*
1413 * Convert the resident part of the attribute record to describe a
1414 * non-resident attribute.
1415 */
1416 a->non_resident = 1;
1417 /* Move the attribute name if it exists and update the offset. */
1418 if (a->name_length)
1419 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
1420 a->name_length * sizeof(ntfschar));
1421 a->name_offset = cpu_to_le16(name_ofs);
1422 /*
1423 * FIXME: For now just clear all of these as we do not support them
1424 * when writing.
1425 */
1426 a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |
1427 ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));
1428 /* Setup the fields specific to non-resident attributes. */
1429 a->data.non_resident.lowest_vcn = 0;
1430 a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
1431 vol->cluster_size_bits);
1432 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
1433 a->data.non_resident.compression_unit = 0;
1434 memset(&a->data.non_resident.reserved, 0,
1435 sizeof(a->data.non_resident.reserved));
1436 a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
1437 a->data.non_resident.data_size =
1438 a->data.non_resident.initialized_size =
1439 cpu_to_sle64(attr_size);
1440 /* Generate the mapping pairs array into the attribute record. */
1441 err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
1442 arec_size - mp_ofs, rl, 0, -1, NULL);
1443 if (unlikely(err)) {
1444 ntfs_debug("Failed to build mapping pairs, error code %i.",
1445 err);
1446 goto undo_err_out;
1447 }
1448 /* Setup the in-memory attribute structure to be non-resident. */
1449 /*
1450 * FIXME: For now just clear all of these as we do not support them
1451 * when writing.
1452 */
1453 NInoClearSparse(ni);
1454 NInoClearEncrypted(ni);
1455 NInoClearCompressed(ni);
1456 ni->runlist.rl = rl;
1457 write_lock_irqsave(&ni->size_lock, flags);
1458 ni->allocated_size = new_size;
1459 write_unlock_irqrestore(&ni->size_lock, flags);
1460 /*
1461 * This needs to be last since the address space operations ->readpage
1462 * and ->writepage can run concurrently with us as they are not
1463 * serialized on i_sem. Note, we are not allowed to fail once we flip
1464 * this switch, which is another reason to do this last.
1465 */
1466 NInoSetNonResident(ni);
1467 /* Mark the mft record dirty, so it gets written back. */
1468 flush_dcache_mft_record_page(ctx->ntfs_ino);
1469 mark_mft_record_dirty(ctx->ntfs_ino);
1470 ntfs_attr_put_search_ctx(ctx);
1471 unmap_mft_record(base_ni);
1472 up_write(&ni->runlist.lock);
1473 if (page) {
1474 set_page_dirty(page);
1475 unlock_page(page);
1476 mark_page_accessed(page);
1477 page_cache_release(page);
1478 }
1479 ntfs_debug("Done.");
1480 return 0;
1481undo_err_out:
1482 /* Convert the attribute back into a resident attribute. */
1483 a->non_resident = 0;
1484 /* Move the attribute name if it exists and update the offset. */
1485 name_ofs = (offsetof(ATTR_RECORD, data.resident.reserved) +
1486 sizeof(a->data.resident.reserved) + 7) & ~7;
1487 if (a->name_length)
1488 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
1489 a->name_length * sizeof(ntfschar));
1490 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
1491 a->name_offset = cpu_to_le16(name_ofs);
1492 arec_size = (mp_ofs + attr_size + 7) & ~7;
1493 /* Resize the resident part of the attribute record. */
1494 err2 = ntfs_attr_record_resize(m, a, arec_size);
1495 if (unlikely(err2)) {
1496 /*
1497 * This cannot happen (well if memory corruption is at work it
1498 * could happen in theory), but deal with it as well as we can.
1499 * If the old size is too small, truncate the attribute,
1500 * otherwise simply give it a larger allocated size.
1501 * FIXME: Should check whether chkdsk complains when the
1502 * allocated size is much bigger than the resident value size.
1503 */
1504 arec_size = le32_to_cpu(a->length);
1505 if ((mp_ofs + attr_size) > arec_size) {
1506 err2 = attr_size;
1507 attr_size = arec_size - mp_ofs;
1508 ntfs_error(vol->sb, "Failed to undo partial resident "
1509 "to non-resident attribute "
1510 "conversion. Truncating inode 0x%lx, "
1511 "attribute type 0x%x from %i bytes to "
1512 "%i bytes to maintain metadata "
1513 "consistency. THIS MEANS YOU ARE "
1514 "LOSING %i BYTES DATA FROM THIS %s.",
1515 vi->i_ino,
1516 (unsigned)le32_to_cpu(ni->type),
1517 err2, attr_size, err2 - attr_size,
1518 ((ni->type == AT_DATA) &&
1519 !ni->name_len) ? "FILE": "ATTRIBUTE");
1520 write_lock_irqsave(&ni->size_lock, flags);
1521 ni->initialized_size = attr_size;
1522 i_size_write(vi, attr_size);
1523 write_unlock_irqrestore(&ni->size_lock, flags);
1524 }
1525 }
1526 /* Setup the fields specific to resident attributes. */
1527 a->data.resident.value_length = cpu_to_le32(attr_size);
1528 a->data.resident.value_offset = cpu_to_le16(mp_ofs);
1529 a->data.resident.flags = old_res_attr_flags;
1530 memset(&a->data.resident.reserved, 0,
1531 sizeof(a->data.resident.reserved));
1532 /* Copy the data from the page back to the attribute value. */
1533 if (page) {
1534 kaddr = kmap_atomic(page, KM_USER0);
1535 memcpy((u8*)a + mp_ofs, kaddr, attr_size);
1536 kunmap_atomic(kaddr, KM_USER0);
1537 }
1538 /* Setup the allocated size in the ntfs inode in case it changed. */
1539 write_lock_irqsave(&ni->size_lock, flags);
1540 ni->allocated_size = arec_size - mp_ofs;
1541 write_unlock_irqrestore(&ni->size_lock, flags);
1542 /* Mark the mft record dirty, so it gets written back. */
1543 flush_dcache_mft_record_page(ctx->ntfs_ino);
1544 mark_mft_record_dirty(ctx->ntfs_ino);
1545err_out:
1546 if (ctx)
1547 ntfs_attr_put_search_ctx(ctx);
1548 if (m)
1549 unmap_mft_record(base_ni);
1550 ni->runlist.rl = NULL;
1551 up_write(&ni->runlist.lock);
1552rl_err_out:
1553 if (rl) {
1554 if (ntfs_cluster_free_from_rl(vol, rl) < 0) {
1555 ntfs_error(vol->sb, "Failed to release allocated "
1556 "cluster(s) in error code path. Run "
1557 "chkdsk to recover the lost "
1558 "cluster(s).");
1559 NVolSetErrors(vol);
1560 }
1561 ntfs_free(rl);
1562page_err_out:
1563 unlock_page(page);
1564 page_cache_release(page);
1565 }
1566 if (err == -EINVAL)
1567 err = -EIO;
1568 return err;
1569}
1570
1571/**
1120 * ntfs_attr_set - fill (a part of) an attribute with a byte 1572 * ntfs_attr_set - fill (a part of) an attribute with a byte
1121 * @ni: ntfs inode describing the attribute to fill 1573 * @ni: ntfs inode describing the attribute to fill
1122 * @ofs: offset inside the attribute at which to start to fill 1574 * @ofs: offset inside the attribute at which to start to fill
@@ -1127,6 +1579,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. 1579 * byte offset @ofs inside the attribute with the constant byte @val.
1128 * 1580 *
1129 * This function is effectively like memset() applied to an ntfs attribute. 1581 * This function is effectively like memset() applied to an ntfs attribute.
1582 * Note thie function actually only operates on the page cache pages belonging
1583 * to the ntfs attribute and it marks them dirty after doing the memset().
1584 * Thus it relies on the vm dirty page write code paths to cause the modified
1585 * pages to be written to the mft record/disk.
1130 * 1586 *
1131 * Return 0 on success and -errno on error. An error code of -ESPIPE means 1587 * 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 1588 * that @ofs + @cnt were outside the end of the attribute and no write was
@@ -1155,7 +1611,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
1155 end = ofs + cnt; 1611 end = ofs + cnt;
1156 end_ofs = end & ~PAGE_CACHE_MASK; 1612 end_ofs = end & ~PAGE_CACHE_MASK;
1157 /* If the end is outside the inode size return -ESPIPE. */ 1613 /* If the end is outside the inode size return -ESPIPE. */
1158 if (unlikely(end > VFS_I(ni)->i_size)) { 1614 if (unlikely(end > i_size_read(VFS_I(ni)))) {
1159 ntfs_error(vol->sb, "Request exceeds end of attribute."); 1615 ntfs_error(vol->sb, "Request exceeds end of attribute.");
1160 return -ESPIPE; 1616 return -ESPIPE;
1161 } 1617 }
@@ -1256,3 +1712,5 @@ done:
1256 ntfs_debug("Done."); 1712 ntfs_debug("Done.");
1257 return 0; 1713 return 0;
1258} 1714}
1715
1716#endif /* NTFS_RW */