1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * 3 * 4 * Copyright (C) 2019-2021 Paragon Software Gm 4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved. 5 * 5 * 6 */ 6 */ 7 7 8 #include <linux/fs.h> 8 #include <linux/fs.h> 9 9 10 #include "debug.h" 10 #include "debug.h" 11 #include "ntfs.h" 11 #include "ntfs.h" 12 #include "ntfs_fs.h" 12 #include "ntfs_fs.h" 13 13 14 static inline int compare_attr(const struct AT 14 static inline int compare_attr(const struct ATTRIB *left, enum ATTR_TYPE type, 15 const __le16 *n 15 const __le16 *name, u8 name_len, 16 const u16 *upca 16 const u16 *upcase) 17 { 17 { 18 /* First, compare the type codes. */ 18 /* First, compare the type codes. */ 19 int diff = le32_to_cpu(left->type) - l 19 int diff = le32_to_cpu(left->type) - le32_to_cpu(type); 20 20 21 if (diff) 21 if (diff) 22 return diff; 22 return diff; 23 23 24 /* They have the same type code, so we 24 /* They have the same type code, so we have to compare the names. */ 25 return ntfs_cmp_names(attr_name(left), 25 return ntfs_cmp_names(attr_name(left), left->name_len, name, name_len, 26 upcase, true); 26 upcase, true); 27 } 27 } 28 28 29 /* 29 /* 30 * mi_new_attt_id 30 * mi_new_attt_id 31 * 31 * 32 * Return: Unused attribute id that is less th 32 * Return: Unused attribute id that is less than mrec->next_attr_id. 33 */ 33 */ 34 static __le16 mi_new_attt_id(struct mft_inode 34 static __le16 mi_new_attt_id(struct mft_inode *mi) 35 { 35 { 36 u16 free_id, max_id, t16; 36 u16 free_id, max_id, t16; 37 struct MFT_REC *rec = mi->mrec; 37 struct MFT_REC *rec = mi->mrec; 38 struct ATTRIB *attr; 38 struct ATTRIB *attr; 39 __le16 id; 39 __le16 id; 40 40 41 id = rec->next_attr_id; 41 id = rec->next_attr_id; 42 free_id = le16_to_cpu(id); 42 free_id = le16_to_cpu(id); 43 if (free_id < 0x7FFF) { 43 if (free_id < 0x7FFF) { 44 rec->next_attr_id = cpu_to_le1 44 rec->next_attr_id = cpu_to_le16(free_id + 1); 45 return id; 45 return id; 46 } 46 } 47 47 48 /* One record can store up to 1024/24 48 /* One record can store up to 1024/24 ~= 42 attributes. */ 49 free_id = 0; 49 free_id = 0; 50 max_id = 0; 50 max_id = 0; 51 51 52 attr = NULL; 52 attr = NULL; 53 53 54 for (;;) { 54 for (;;) { 55 attr = mi_enum_attr(mi, attr); 55 attr = mi_enum_attr(mi, attr); 56 if (!attr) { 56 if (!attr) { 57 rec->next_attr_id = cp 57 rec->next_attr_id = cpu_to_le16(max_id + 1); 58 mi->dirty = true; 58 mi->dirty = true; 59 return cpu_to_le16(fre 59 return cpu_to_le16(free_id); 60 } 60 } 61 61 62 t16 = le16_to_cpu(attr->id); 62 t16 = le16_to_cpu(attr->id); 63 if (t16 == free_id) { 63 if (t16 == free_id) { 64 free_id += 1; 64 free_id += 1; 65 attr = NULL; 65 attr = NULL; 66 } else if (max_id < t16) 66 } else if (max_id < t16) 67 max_id = t16; 67 max_id = t16; 68 } 68 } 69 } 69 } 70 70 71 int mi_get(struct ntfs_sb_info *sbi, CLST rno, 71 int mi_get(struct ntfs_sb_info *sbi, CLST rno, struct mft_inode **mi) 72 { 72 { 73 int err; 73 int err; 74 struct mft_inode *m = kzalloc(sizeof(s 74 struct mft_inode *m = kzalloc(sizeof(struct mft_inode), GFP_NOFS); 75 75 76 if (!m) 76 if (!m) 77 return -ENOMEM; 77 return -ENOMEM; 78 78 79 err = mi_init(m, sbi, rno); 79 err = mi_init(m, sbi, rno); 80 if (err) { 80 if (err) { 81 kfree(m); 81 kfree(m); 82 return err; 82 return err; 83 } 83 } 84 84 85 err = mi_read(m, false); 85 err = mi_read(m, false); 86 if (err) { 86 if (err) { 87 mi_put(m); 87 mi_put(m); 88 return err; 88 return err; 89 } 89 } 90 90 91 *mi = m; 91 *mi = m; 92 return 0; 92 return 0; 93 } 93 } 94 94 95 void mi_put(struct mft_inode *mi) 95 void mi_put(struct mft_inode *mi) 96 { 96 { 97 mi_clear(mi); 97 mi_clear(mi); 98 kfree(mi); 98 kfree(mi); 99 } 99 } 100 100 101 int mi_init(struct mft_inode *mi, struct ntfs_ 101 int mi_init(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno) 102 { 102 { 103 mi->sbi = sbi; 103 mi->sbi = sbi; 104 mi->rno = rno; 104 mi->rno = rno; 105 mi->mrec = kmalloc(sbi->record_size, G 105 mi->mrec = kmalloc(sbi->record_size, GFP_NOFS); 106 if (!mi->mrec) 106 if (!mi->mrec) 107 return -ENOMEM; 107 return -ENOMEM; 108 108 109 return 0; 109 return 0; 110 } 110 } 111 111 112 /* 112 /* 113 * mi_read - Read MFT data. 113 * mi_read - Read MFT data. 114 */ 114 */ 115 int mi_read(struct mft_inode *mi, bool is_mft) 115 int mi_read(struct mft_inode *mi, bool is_mft) 116 { 116 { 117 int err; 117 int err; 118 struct MFT_REC *rec = mi->mrec; 118 struct MFT_REC *rec = mi->mrec; 119 struct ntfs_sb_info *sbi = mi->sbi; 119 struct ntfs_sb_info *sbi = mi->sbi; 120 u32 bpr = sbi->record_size; 120 u32 bpr = sbi->record_size; 121 u64 vbo = (u64)mi->rno << sbi->record_ 121 u64 vbo = (u64)mi->rno << sbi->record_bits; 122 struct ntfs_inode *mft_ni = sbi->mft.n 122 struct ntfs_inode *mft_ni = sbi->mft.ni; 123 struct runs_tree *run = mft_ni ? &mft_ 123 struct runs_tree *run = mft_ni ? &mft_ni->file.run : NULL; 124 struct rw_semaphore *rw_lock = NULL; 124 struct rw_semaphore *rw_lock = NULL; 125 125 126 if (is_mounted(sbi)) { 126 if (is_mounted(sbi)) { 127 if (!is_mft && mft_ni) { 127 if (!is_mft && mft_ni) { 128 rw_lock = &mft_ni->fil 128 rw_lock = &mft_ni->file.run_lock; 129 down_read(rw_lock); 129 down_read(rw_lock); 130 } 130 } 131 } 131 } 132 132 133 err = ntfs_read_bh(sbi, run, vbo, &rec 133 err = ntfs_read_bh(sbi, run, vbo, &rec->rhdr, bpr, &mi->nb); 134 if (rw_lock) 134 if (rw_lock) 135 up_read(rw_lock); 135 up_read(rw_lock); 136 if (!err) 136 if (!err) 137 goto ok; 137 goto ok; 138 138 139 if (err == -E_NTFS_FIXUP) { 139 if (err == -E_NTFS_FIXUP) { 140 mi->dirty = true; 140 mi->dirty = true; 141 goto ok; 141 goto ok; 142 } 142 } 143 143 144 if (err != -ENOENT) 144 if (err != -ENOENT) 145 goto out; 145 goto out; 146 146 147 if (rw_lock) { 147 if (rw_lock) { 148 ni_lock(mft_ni); 148 ni_lock(mft_ni); 149 down_write(rw_lock); 149 down_write(rw_lock); 150 } 150 } 151 err = attr_load_runs_vcn(mft_ni, ATTR_ 151 err = attr_load_runs_vcn(mft_ni, ATTR_DATA, NULL, 0, run, 152 vbo >> sbi->c 152 vbo >> sbi->cluster_bits); 153 if (rw_lock) { 153 if (rw_lock) { 154 up_write(rw_lock); 154 up_write(rw_lock); 155 ni_unlock(mft_ni); 155 ni_unlock(mft_ni); 156 } 156 } 157 if (err) 157 if (err) 158 goto out; 158 goto out; 159 159 160 if (rw_lock) 160 if (rw_lock) 161 down_read(rw_lock); 161 down_read(rw_lock); 162 err = ntfs_read_bh(sbi, run, vbo, &rec 162 err = ntfs_read_bh(sbi, run, vbo, &rec->rhdr, bpr, &mi->nb); 163 if (rw_lock) 163 if (rw_lock) 164 up_read(rw_lock); 164 up_read(rw_lock); 165 165 166 if (err == -E_NTFS_FIXUP) { 166 if (err == -E_NTFS_FIXUP) { 167 mi->dirty = true; 167 mi->dirty = true; 168 goto ok; 168 goto ok; 169 } 169 } 170 if (err) 170 if (err) 171 goto out; 171 goto out; 172 172 173 ok: 173 ok: 174 /* Check field 'total' only here. */ 174 /* Check field 'total' only here. */ 175 if (le32_to_cpu(rec->total) != bpr) { 175 if (le32_to_cpu(rec->total) != bpr) { 176 err = -EINVAL; 176 err = -EINVAL; 177 goto out; 177 goto out; 178 } 178 } 179 179 180 return 0; 180 return 0; 181 181 182 out: 182 out: 183 if (err == -E_NTFS_CORRUPT) { 183 if (err == -E_NTFS_CORRUPT) { 184 ntfs_err(sbi->sb, "mft corrupt 184 ntfs_err(sbi->sb, "mft corrupted"); 185 ntfs_set_state(sbi, NTFS_DIRTY 185 ntfs_set_state(sbi, NTFS_DIRTY_ERROR); 186 err = -EINVAL; 186 err = -EINVAL; 187 } 187 } 188 188 189 return err; 189 return err; 190 } 190 } 191 191 192 /* << 193 * mi_enum_attr - start/continue attributes en << 194 * << 195 * NOTE: mi->mrec - memory of size sbi->record << 196 * here we sure that mi->mrec->total == sbi->r << 197 */ << 198 struct ATTRIB *mi_enum_attr(struct mft_inode * 192 struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr) 199 { 193 { 200 const struct MFT_REC *rec = mi->mrec; 194 const struct MFT_REC *rec = mi->mrec; 201 u32 used = le32_to_cpu(rec->used); 195 u32 used = le32_to_cpu(rec->used); 202 u32 t32, off, asize, prev_type; !! 196 u32 t32, off, asize; 203 u16 t16; 197 u16 t16; 204 u64 data_size, alloc_size, tot_size; << 205 198 206 if (!attr) { 199 if (!attr) { 207 u32 total = le32_to_cpu(rec->t 200 u32 total = le32_to_cpu(rec->total); 208 201 209 off = le16_to_cpu(rec->attr_of 202 off = le16_to_cpu(rec->attr_off); 210 203 211 if (used > total) 204 if (used > total) 212 return NULL; 205 return NULL; 213 206 214 if (off >= used || off < MFTRE 207 if (off >= used || off < MFTRECORD_FIXUP_OFFSET_1 || 215 !IS_ALIGNED(off, 4)) { 208 !IS_ALIGNED(off, 4)) { 216 return NULL; 209 return NULL; 217 } 210 } 218 211 219 /* Skip non-resident records. 212 /* Skip non-resident records. */ 220 if (!is_rec_inuse(rec)) 213 if (!is_rec_inuse(rec)) 221 return NULL; 214 return NULL; 222 215 223 prev_type = 0; << 224 attr = Add2Ptr(rec, off); 216 attr = Add2Ptr(rec, off); 225 } else { 217 } else { 226 /* !! 218 /* Check if input attr inside record. */ 227 * We don't need to check prev << 228 * a bounds checking in the pr << 229 */ << 230 off = PtrOffset(rec, attr); 219 off = PtrOffset(rec, attr); >> 220 if (off >= used) >> 221 return NULL; 231 222 232 asize = le32_to_cpu(attr->size 223 asize = le32_to_cpu(attr->size); >> 224 if (asize < SIZEOF_RESIDENT) { >> 225 /* Impossible 'cause we should not return such attribute. */ >> 226 return NULL; >> 227 } 233 228 234 prev_type = le32_to_cpu(attr-> << 235 attr = Add2Ptr(attr, asize); 229 attr = Add2Ptr(attr, asize); 236 off += asize; 230 off += asize; 237 } 231 } 238 232 >> 233 asize = le32_to_cpu(attr->size); >> 234 239 /* Can we use the first field (attr->t 235 /* Can we use the first field (attr->type). */ 240 /* NOTE: this code also checks attr->s << 241 if (off + 8 > used) { 236 if (off + 8 > used) { 242 static_assert(ALIGN(sizeof(enu 237 static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8); 243 return NULL; 238 return NULL; 244 } 239 } 245 240 246 if (attr->type == ATTR_END) { 241 if (attr->type == ATTR_END) { 247 /* End of enumeration. */ 242 /* End of enumeration. */ 248 return NULL; 243 return NULL; 249 } 244 } 250 245 251 /* 0x100 is last known attribute for n 246 /* 0x100 is last known attribute for now. */ 252 t32 = le32_to_cpu(attr->type); 247 t32 = le32_to_cpu(attr->type); 253 if (!t32 || (t32 & 0xf) || (t32 > 0x10 !! 248 if ((t32 & 0xf) || (t32 > 0x100)) 254 return NULL; << 255 << 256 /* attributes in record must be ordere << 257 if (t32 < prev_type) << 258 return NULL; 249 return NULL; 259 250 260 asize = le32_to_cpu(attr->size); << 261 << 262 /* Check overflow and boundary. */ 251 /* Check overflow and boundary. */ 263 if (off + asize < off || off + asize > 252 if (off + asize < off || off + asize > used) 264 return NULL; 253 return NULL; 265 254 266 /* Check size of attribute. */ 255 /* Check size of attribute. */ 267 if (!attr->non_res) { 256 if (!attr->non_res) { 268 /* Check resident fields. */ << 269 if (asize < SIZEOF_RESIDENT) 257 if (asize < SIZEOF_RESIDENT) 270 return NULL; 258 return NULL; 271 259 272 t16 = le16_to_cpu(attr->res.da 260 t16 = le16_to_cpu(attr->res.data_off); >> 261 273 if (t16 > asize) 262 if (t16 > asize) 274 return NULL; 263 return NULL; 275 264 276 if (le32_to_cpu(attr->res.data !! 265 t32 = le32_to_cpu(attr->res.data_size); >> 266 if (t16 + t32 > asize) 277 return NULL; 267 return NULL; 278 268 279 t32 = sizeof(short) * attr->na !! 269 if (attr->name_len && 280 if (t32 && le16_to_cpu(attr->n !! 270 le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len > t16) { 281 return NULL; 271 return NULL; >> 272 } 282 273 283 return attr; 274 return attr; 284 } 275 } 285 276 286 /* Check nonresident fields. */ !! 277 /* Check some nonresident fields. */ 287 if (attr->non_res != 1) !! 278 if (attr->name_len && 288 return NULL; !! 279 le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len > 289 !! 280 le16_to_cpu(attr->nres.run_off)) { 290 /* Can we use memory including attr->n << 291 if (asize < SIZEOF_NONRESIDENT) << 292 return NULL; << 293 << 294 t16 = le16_to_cpu(attr->nres.run_off); << 295 if (t16 > asize) << 296 return NULL; << 297 << 298 t32 = sizeof(short) * attr->name_len; << 299 if (t32 && le16_to_cpu(attr->name_off) << 300 return NULL; << 301 << 302 /* Check start/end vcn. */ << 303 if (le64_to_cpu(attr->nres.svcn) > le6 << 304 return NULL; << 305 << 306 data_size = le64_to_cpu(attr->nres.dat << 307 if (le64_to_cpu(attr->nres.valid_size) << 308 return NULL; << 309 << 310 alloc_size = le64_to_cpu(attr->nres.al << 311 if (data_size > alloc_size) << 312 return NULL; << 313 << 314 t32 = mi->sbi->cluster_mask; << 315 if (alloc_size & t32) << 316 return NULL; 281 return NULL; >> 282 } 317 283 318 if (!attr->nres.svcn && is_attr_ext(at !! 284 if (attr->nres.svcn || !is_attr_ext(attr)) { 319 /* First segment of sparse/com !! 285 if (asize + 8 < SIZEOF_NONRESIDENT) 320 /* Can we use memory including << 321 if (asize < SIZEOF_NONRESIDENT << 322 return NULL; << 323 << 324 tot_size = le64_to_cpu(attr->n << 325 if (tot_size & t32) << 326 return NULL; 286 return NULL; 327 287 328 if (tot_size > alloc_size) << 329 return NULL; << 330 } else { << 331 if (attr->nres.c_unit) 288 if (attr->nres.c_unit) 332 return NULL; 289 return NULL; 333 !! 290 } else if (asize + 8 < SIZEOF_NONRESIDENT_EX) 334 if (alloc_size > mi->sbi->volu !! 291 return NULL; 335 return NULL; << 336 } << 337 292 338 return attr; 293 return attr; 339 } 294 } 340 295 341 /* 296 /* 342 * mi_find_attr - Find the attribute by type a 297 * mi_find_attr - Find the attribute by type and name and id. 343 */ 298 */ 344 struct ATTRIB *mi_find_attr(struct mft_inode * 299 struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr, 345 enum ATTR_TYPE typ 300 enum ATTR_TYPE type, const __le16 *name, 346 u8 name_len, const !! 301 size_t name_len, const __le16 *id) 347 { 302 { 348 u32 type_in = le32_to_cpu(type); 303 u32 type_in = le32_to_cpu(type); 349 u32 atype; 304 u32 atype; 350 305 351 next_attr: 306 next_attr: 352 attr = mi_enum_attr(mi, attr); 307 attr = mi_enum_attr(mi, attr); 353 if (!attr) 308 if (!attr) 354 return NULL; 309 return NULL; 355 310 356 atype = le32_to_cpu(attr->type); 311 atype = le32_to_cpu(attr->type); 357 if (atype > type_in) 312 if (atype > type_in) 358 return NULL; 313 return NULL; 359 314 360 if (atype < type_in) 315 if (atype < type_in) 361 goto next_attr; 316 goto next_attr; 362 317 363 if (attr->name_len != name_len) 318 if (attr->name_len != name_len) 364 goto next_attr; 319 goto next_attr; 365 320 366 if (name_len && memcmp(attr_name(attr) 321 if (name_len && memcmp(attr_name(attr), name, name_len * sizeof(short))) 367 goto next_attr; 322 goto next_attr; 368 323 369 if (id && *id != attr->id) 324 if (id && *id != attr->id) 370 goto next_attr; 325 goto next_attr; 371 326 372 return attr; 327 return attr; 373 } 328 } 374 329 375 int mi_write(struct mft_inode *mi, int wait) 330 int mi_write(struct mft_inode *mi, int wait) 376 { 331 { 377 struct MFT_REC *rec; 332 struct MFT_REC *rec; 378 int err; 333 int err; 379 struct ntfs_sb_info *sbi; 334 struct ntfs_sb_info *sbi; 380 335 381 if (!mi->dirty) 336 if (!mi->dirty) 382 return 0; 337 return 0; 383 338 384 sbi = mi->sbi; 339 sbi = mi->sbi; 385 rec = mi->mrec; 340 rec = mi->mrec; 386 341 387 err = ntfs_write_bh(sbi, &rec->rhdr, & 342 err = ntfs_write_bh(sbi, &rec->rhdr, &mi->nb, wait); 388 if (err) 343 if (err) 389 return err; 344 return err; 390 345 391 if (mi->rno < sbi->mft.recs_mirr) 346 if (mi->rno < sbi->mft.recs_mirr) 392 sbi->flags |= NTFS_FLAGS_MFTMI 347 sbi->flags |= NTFS_FLAGS_MFTMIRR; 393 348 394 mi->dirty = false; 349 mi->dirty = false; 395 350 396 return 0; 351 return 0; 397 } 352 } 398 353 399 int mi_format_new(struct mft_inode *mi, struct 354 int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno, 400 __le16 flags, bool is_mft) 355 __le16 flags, bool is_mft) 401 { 356 { 402 int err; 357 int err; 403 u16 seq = 1; 358 u16 seq = 1; 404 struct MFT_REC *rec; 359 struct MFT_REC *rec; 405 u64 vbo = (u64)rno << sbi->record_bits 360 u64 vbo = (u64)rno << sbi->record_bits; 406 361 407 err = mi_init(mi, sbi, rno); 362 err = mi_init(mi, sbi, rno); 408 if (err) 363 if (err) 409 return err; 364 return err; 410 365 411 rec = mi->mrec; 366 rec = mi->mrec; 412 367 413 if (rno == MFT_REC_MFT) { 368 if (rno == MFT_REC_MFT) { 414 ; 369 ; 415 } else if (rno < MFT_REC_FREE) { 370 } else if (rno < MFT_REC_FREE) { 416 seq = rno; 371 seq = rno; 417 } else if (rno >= sbi->mft.used) { 372 } else if (rno >= sbi->mft.used) { 418 ; 373 ; 419 } else if (mi_read(mi, is_mft)) { 374 } else if (mi_read(mi, is_mft)) { 420 ; 375 ; 421 } else if (rec->rhdr.sign == NTFS_FILE 376 } else if (rec->rhdr.sign == NTFS_FILE_SIGNATURE) { 422 /* Record is reused. Update it 377 /* Record is reused. Update its sequence number. */ 423 seq = le16_to_cpu(rec->seq) + 378 seq = le16_to_cpu(rec->seq) + 1; 424 if (!seq) 379 if (!seq) 425 seq = 1; 380 seq = 1; 426 } 381 } 427 382 428 memcpy(rec, sbi->new_rec, sbi->record_ 383 memcpy(rec, sbi->new_rec, sbi->record_size); 429 384 430 rec->seq = cpu_to_le16(seq); 385 rec->seq = cpu_to_le16(seq); 431 rec->flags = RECORD_FLAG_IN_USE | flag 386 rec->flags = RECORD_FLAG_IN_USE | flags; 432 if (MFTRECORD_FIXUP_OFFSET == MFTRECOR << 433 rec->mft_record = cpu_to_le32( << 434 387 435 mi->dirty = true; 388 mi->dirty = true; 436 389 437 if (!mi->nb.nbufs) { 390 if (!mi->nb.nbufs) { 438 struct ntfs_inode *ni = sbi->m 391 struct ntfs_inode *ni = sbi->mft.ni; 439 bool lock = false; 392 bool lock = false; 440 393 441 if (is_mounted(sbi) && !is_mft 394 if (is_mounted(sbi) && !is_mft) { 442 down_read(&ni->file.ru 395 down_read(&ni->file.run_lock); 443 lock = true; 396 lock = true; 444 } 397 } 445 398 446 err = ntfs_get_bh(sbi, &ni->fi 399 err = ntfs_get_bh(sbi, &ni->file.run, vbo, sbi->record_size, 447 &mi->nb); 400 &mi->nb); 448 if (lock) 401 if (lock) 449 up_read(&ni->file.run_ 402 up_read(&ni->file.run_lock); 450 } 403 } 451 404 452 return err; 405 return err; 453 } 406 } 454 407 455 /* 408 /* >> 409 * mi_mark_free - Mark record as unused and marks it as free in bitmap. >> 410 */ >> 411 void mi_mark_free(struct mft_inode *mi) >> 412 { >> 413 CLST rno = mi->rno; >> 414 struct ntfs_sb_info *sbi = mi->sbi; >> 415 >> 416 if (rno >= MFT_REC_RESERVED && rno < MFT_REC_FREE) { >> 417 ntfs_clear_mft_tail(sbi, rno, rno + 1); >> 418 mi->dirty = false; >> 419 return; >> 420 } >> 421 >> 422 if (mi->mrec) { >> 423 clear_rec_inuse(mi->mrec); >> 424 mi->dirty = true; >> 425 mi_write(mi, 0); >> 426 } >> 427 ntfs_mark_rec_free(sbi, rno); >> 428 } >> 429 >> 430 /* 456 * mi_insert_attr - Reserve space for new attr 431 * mi_insert_attr - Reserve space for new attribute. 457 * 432 * 458 * Return: Not full constructed attribute or N 433 * Return: Not full constructed attribute or NULL if not possible to create. 459 */ 434 */ 460 struct ATTRIB *mi_insert_attr(struct mft_inode 435 struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type, 461 const __le16 *na 436 const __le16 *name, u8 name_len, u32 asize, 462 u16 name_off) 437 u16 name_off) 463 { 438 { 464 size_t tail; 439 size_t tail; 465 struct ATTRIB *attr; 440 struct ATTRIB *attr; 466 __le16 id; 441 __le16 id; 467 struct MFT_REC *rec = mi->mrec; 442 struct MFT_REC *rec = mi->mrec; 468 struct ntfs_sb_info *sbi = mi->sbi; 443 struct ntfs_sb_info *sbi = mi->sbi; 469 u32 used = le32_to_cpu(rec->used); 444 u32 used = le32_to_cpu(rec->used); 470 const u16 *upcase = sbi->upcase; 445 const u16 *upcase = sbi->upcase; >> 446 int diff; 471 447 472 /* Can we insert mi attribute? */ 448 /* Can we insert mi attribute? */ 473 if (used + asize > sbi->record_size) !! 449 if (used + asize > mi->sbi->record_size) 474 return NULL; 450 return NULL; 475 451 476 /* 452 /* 477 * Scan through the list of attributes 453 * Scan through the list of attributes to find the point 478 * at which we should insert it. 454 * at which we should insert it. 479 */ 455 */ 480 attr = NULL; 456 attr = NULL; 481 while ((attr = mi_enum_attr(mi, attr)) 457 while ((attr = mi_enum_attr(mi, attr))) { 482 int diff = compare_attr(attr, !! 458 diff = compare_attr(attr, type, name, name_len, upcase); 483 !! 459 if (diff > 0) >> 460 break; 484 if (diff < 0) 461 if (diff < 0) 485 continue; 462 continue; 486 463 487 if (!diff && !is_attr_indexed( !! 464 if (!is_attr_indexed(attr)) 488 return NULL; 465 return NULL; 489 break; 466 break; 490 } 467 } 491 468 492 if (!attr) { 469 if (!attr) { 493 /* Append. */ !! 470 tail = 8; /* Not used, just to suppress warning. */ 494 tail = 8; << 495 attr = Add2Ptr(rec, used - 8); 471 attr = Add2Ptr(rec, used - 8); 496 } else { 472 } else { 497 /* Insert before 'attr'. */ << 498 tail = used - PtrOffset(rec, a 473 tail = used - PtrOffset(rec, attr); 499 } 474 } 500 475 501 id = mi_new_attt_id(mi); 476 id = mi_new_attt_id(mi); 502 477 503 memmove(Add2Ptr(attr, asize), attr, ta 478 memmove(Add2Ptr(attr, asize), attr, tail); 504 memset(attr, 0, asize); 479 memset(attr, 0, asize); 505 480 506 attr->type = type; 481 attr->type = type; 507 attr->size = cpu_to_le32(asize); 482 attr->size = cpu_to_le32(asize); 508 attr->name_len = name_len; 483 attr->name_len = name_len; 509 attr->name_off = cpu_to_le16(name_off) 484 attr->name_off = cpu_to_le16(name_off); 510 attr->id = id; 485 attr->id = id; 511 486 512 memmove(Add2Ptr(attr, name_off), name, 487 memmove(Add2Ptr(attr, name_off), name, name_len * sizeof(short)); 513 rec->used = cpu_to_le32(used + asize); 488 rec->used = cpu_to_le32(used + asize); 514 489 515 mi->dirty = true; 490 mi->dirty = true; 516 491 517 return attr; 492 return attr; 518 } 493 } 519 494 520 /* 495 /* 521 * mi_remove_attr - Remove the attribute from 496 * mi_remove_attr - Remove the attribute from record. 522 * 497 * 523 * NOTE: The source attr will point to next at 498 * NOTE: The source attr will point to next attribute. 524 */ 499 */ 525 bool mi_remove_attr(struct ntfs_inode *ni, str 500 bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi, 526 struct ATTRIB *attr) 501 struct ATTRIB *attr) 527 { 502 { 528 struct MFT_REC *rec = mi->mrec; 503 struct MFT_REC *rec = mi->mrec; 529 u32 aoff = PtrOffset(rec, attr); 504 u32 aoff = PtrOffset(rec, attr); 530 u32 used = le32_to_cpu(rec->used); 505 u32 used = le32_to_cpu(rec->used); 531 u32 asize = le32_to_cpu(attr->size); 506 u32 asize = le32_to_cpu(attr->size); 532 507 533 if (aoff + asize > used) 508 if (aoff + asize > used) 534 return false; 509 return false; 535 510 536 if (ni && is_attr_indexed(attr) && att 511 if (ni && is_attr_indexed(attr) && attr->type == ATTR_NAME) { 537 u16 links = le16_to_cpu(ni->mi 512 u16 links = le16_to_cpu(ni->mi.mrec->hard_links); 538 if (!links) { 513 if (!links) { 539 /* minor error. Not cr 514 /* minor error. Not critical. */ 540 } else { 515 } else { 541 ni->mi.mrec->hard_link 516 ni->mi.mrec->hard_links = cpu_to_le16(links - 1); 542 ni->mi.dirty = true; 517 ni->mi.dirty = true; 543 } 518 } 544 } 519 } 545 520 546 used -= asize; 521 used -= asize; 547 memmove(attr, Add2Ptr(attr, asize), us 522 memmove(attr, Add2Ptr(attr, asize), used - aoff); 548 rec->used = cpu_to_le32(used); 523 rec->used = cpu_to_le32(used); 549 mi->dirty = true; 524 mi->dirty = true; 550 525 551 return true; 526 return true; 552 } 527 } 553 528 554 /* bytes = "new attribute size" - "old attribu 529 /* bytes = "new attribute size" - "old attribute size" */ 555 bool mi_resize_attr(struct mft_inode *mi, stru 530 bool mi_resize_attr(struct mft_inode *mi, struct ATTRIB *attr, int bytes) 556 { 531 { 557 struct MFT_REC *rec = mi->mrec; 532 struct MFT_REC *rec = mi->mrec; 558 u32 aoff = PtrOffset(rec, attr); 533 u32 aoff = PtrOffset(rec, attr); 559 u32 total, used = le32_to_cpu(rec->use 534 u32 total, used = le32_to_cpu(rec->used); 560 u32 nsize, asize = le32_to_cpu(attr->s 535 u32 nsize, asize = le32_to_cpu(attr->size); 561 u32 rsize = le32_to_cpu(attr->res.data 536 u32 rsize = le32_to_cpu(attr->res.data_size); 562 int tail = (int)(used - aoff - asize); 537 int tail = (int)(used - aoff - asize); 563 int dsize; 538 int dsize; 564 char *next; 539 char *next; 565 540 566 if (tail < 0 || aoff >= used) 541 if (tail < 0 || aoff >= used) 567 return false; 542 return false; 568 543 569 if (!bytes) 544 if (!bytes) 570 return true; 545 return true; 571 546 572 total = le32_to_cpu(rec->total); 547 total = le32_to_cpu(rec->total); 573 next = Add2Ptr(attr, asize); 548 next = Add2Ptr(attr, asize); 574 549 575 if (bytes > 0) { 550 if (bytes > 0) { 576 dsize = ALIGN(bytes, 8); 551 dsize = ALIGN(bytes, 8); 577 if (used + dsize > total) 552 if (used + dsize > total) 578 return false; 553 return false; 579 nsize = asize + dsize; 554 nsize = asize + dsize; 580 /* Move tail */ 555 /* Move tail */ 581 memmove(next + dsize, next, ta 556 memmove(next + dsize, next, tail); 582 memset(next, 0, dsize); 557 memset(next, 0, dsize); 583 used += dsize; 558 used += dsize; 584 rsize += dsize; 559 rsize += dsize; 585 } else { 560 } else { 586 dsize = ALIGN(-bytes, 8); 561 dsize = ALIGN(-bytes, 8); 587 if (dsize > asize) 562 if (dsize > asize) 588 return false; 563 return false; 589 nsize = asize - dsize; 564 nsize = asize - dsize; 590 memmove(next - dsize, next, ta 565 memmove(next - dsize, next, tail); 591 used -= dsize; 566 used -= dsize; 592 rsize -= dsize; 567 rsize -= dsize; 593 } 568 } 594 569 595 rec->used = cpu_to_le32(used); 570 rec->used = cpu_to_le32(used); 596 attr->size = cpu_to_le32(nsize); 571 attr->size = cpu_to_le32(nsize); 597 if (!attr->non_res) 572 if (!attr->non_res) 598 attr->res.data_size = cpu_to_l 573 attr->res.data_size = cpu_to_le32(rsize); 599 mi->dirty = true; 574 mi->dirty = true; 600 575 601 return true; 576 return true; 602 } 577 } 603 578 604 /* << 605 * Pack runs in MFT record. << 606 * If failed record is not changed. << 607 */ << 608 int mi_pack_runs(struct mft_inode *mi, struct 579 int mi_pack_runs(struct mft_inode *mi, struct ATTRIB *attr, 609 struct runs_tree *run, CLST l 580 struct runs_tree *run, CLST len) 610 { 581 { 611 int err = 0; 582 int err = 0; 612 struct ntfs_sb_info *sbi = mi->sbi; 583 struct ntfs_sb_info *sbi = mi->sbi; 613 u32 new_run_size; 584 u32 new_run_size; 614 CLST plen; 585 CLST plen; 615 struct MFT_REC *rec = mi->mrec; 586 struct MFT_REC *rec = mi->mrec; 616 CLST svcn = le64_to_cpu(attr->nres.svc 587 CLST svcn = le64_to_cpu(attr->nres.svcn); 617 u32 used = le32_to_cpu(rec->used); 588 u32 used = le32_to_cpu(rec->used); 618 u32 aoff = PtrOffset(rec, attr); 589 u32 aoff = PtrOffset(rec, attr); 619 u32 asize = le32_to_cpu(attr->size); 590 u32 asize = le32_to_cpu(attr->size); 620 char *next = Add2Ptr(attr, asize); 591 char *next = Add2Ptr(attr, asize); 621 u16 run_off = le16_to_cpu(attr->nres.r 592 u16 run_off = le16_to_cpu(attr->nres.run_off); 622 u32 run_size = asize - run_off; 593 u32 run_size = asize - run_off; 623 u32 tail = used - aoff - asize; 594 u32 tail = used - aoff - asize; 624 u32 dsize = sbi->record_size - used; 595 u32 dsize = sbi->record_size - used; 625 596 626 /* Make a maximum gap in current recor 597 /* Make a maximum gap in current record. */ 627 memmove(next + dsize, next, tail); 598 memmove(next + dsize, next, tail); 628 599 629 /* Pack as much as possible. */ 600 /* Pack as much as possible. */ 630 err = run_pack(run, svcn, len, Add2Ptr 601 err = run_pack(run, svcn, len, Add2Ptr(attr, run_off), run_size + dsize, 631 &plen); 602 &plen); 632 if (err < 0) { 603 if (err < 0) { 633 memmove(next, next + dsize, ta 604 memmove(next, next + dsize, tail); 634 return err; 605 return err; 635 } 606 } 636 607 637 new_run_size = ALIGN(err, 8); 608 new_run_size = ALIGN(err, 8); 638 609 639 memmove(next + new_run_size - run_size 610 memmove(next + new_run_size - run_size, next + dsize, tail); 640 611 641 attr->size = cpu_to_le32(asize + new_r 612 attr->size = cpu_to_le32(asize + new_run_size - run_size); 642 attr->nres.evcn = cpu_to_le64(svcn + p 613 attr->nres.evcn = cpu_to_le64(svcn + plen - 1); 643 rec->used = cpu_to_le32(used + new_run 614 rec->used = cpu_to_le32(used + new_run_size - run_size); 644 mi->dirty = true; 615 mi->dirty = true; 645 616 646 return 0; 617 return 0; 647 } 618 } 648 619
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.