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