Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'ntfs3_for_6.14' of https://github.com/Paragon-Software-Group/linux-ntfs3

Pull ntfs3 fixes from Konstantin Komarov:

- unify inode corruption marking and mark them as bad immediately upon
detection of an error in attribute enumeration

- folio cleanup

* tag 'ntfs3_for_6.14' of https://github.com/Paragon-Software-Group/linux-ntfs3:
fs/ntfs3: Unify inode corruption marking with _ntfs_bad_inode()
fs/ntfs3: Mark inode as bad as soon as error detected in mi_enum_attr()
ntfs3: Remove an access to page->index

+112 -94
+8 -7
fs/ntfs3/attrib.c
··· 787 787 if (err) 788 788 goto out; 789 789 790 - attr = mi_find_attr(mi, NULL, type, name, name_len, &le->id); 790 + attr = mi_find_attr(ni, mi, NULL, type, name, name_len, 791 + &le->id); 791 792 if (!attr) { 792 793 err = -EINVAL; 793 794 goto bad_inode; ··· 1182 1181 goto out; 1183 1182 } 1184 1183 1185 - attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0, &le->id); 1184 + attr = mi_find_attr(ni, mi, NULL, ATTR_DATA, NULL, 0, &le->id); 1186 1185 if (!attr) { 1187 1186 err = -EINVAL; 1188 1187 goto out; ··· 1407 1406 */ 1408 1407 if (!attr->non_res) { 1409 1408 if (vbo[1] + bytes_per_off > le32_to_cpu(attr->res.data_size)) { 1410 - ntfs_inode_err(&ni->vfs_inode, "is corrupted"); 1409 + _ntfs_bad_inode(&ni->vfs_inode); 1411 1410 return -EINVAL; 1412 1411 } 1413 1412 addr = resident_data(attr); ··· 1797 1796 goto out; 1798 1797 } 1799 1798 1800 - attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0, 1799 + attr = mi_find_attr(ni, mi, NULL, ATTR_DATA, NULL, 0, 1801 1800 &le->id); 1802 1801 if (!attr) { 1803 1802 err = -EINVAL; ··· 2042 2041 } 2043 2042 2044 2043 /* Look for required attribute. */ 2045 - attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL, 2046 - 0, &le->id); 2044 + attr = mi_find_attr(ni, mi, NULL, ATTR_DATA, 2045 + NULL, 0, &le->id); 2047 2046 if (!attr) { 2048 2047 err = -EINVAL; 2049 2048 goto out; ··· 2588 2587 2589 2588 attr = ni_find_attr(ni, NULL, &le, ATTR_DATA, NULL, 0, NULL, &mi); 2590 2589 if (!attr) { 2591 - ntfs_bad_inode(&ni->vfs_inode, "no data attribute"); 2590 + _ntfs_bad_inode(&ni->vfs_inode); 2592 2591 return -ENOENT; 2593 2592 } 2594 2593
+1 -1
fs/ntfs3/dir.c
··· 512 512 ctx->pos = pos; 513 513 } else if (err < 0) { 514 514 if (err == -EINVAL) 515 - ntfs_inode_err(dir, "directory corrupted"); 515 + _ntfs_bad_inode(dir); 516 516 ctx->pos = eod; 517 517 } 518 518
+40 -34
fs/ntfs3/frecord.c
··· 75 75 { 76 76 const struct ATTRIB *attr; 77 77 78 - attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL); 78 + attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_STD, NULL, 0, NULL); 79 79 return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO)) : 80 80 NULL; 81 81 } ··· 89 89 { 90 90 const struct ATTRIB *attr; 91 91 92 - attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL); 92 + attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_STD, NULL, 0, NULL); 93 93 94 94 return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO5)) : 95 95 NULL; ··· 148 148 goto out; 149 149 150 150 err = mi_get(ni->mi.sbi, rno, &r); 151 - if (err) 151 + if (err) { 152 + _ntfs_bad_inode(&ni->vfs_inode); 152 153 return err; 154 + } 153 155 154 156 ni_add_mi(ni, r); 155 157 ··· 203 201 *mi = &ni->mi; 204 202 205 203 /* Look for required attribute in primary record. */ 206 - return mi_find_attr(&ni->mi, attr, type, name, name_len, NULL); 204 + return mi_find_attr(ni, &ni->mi, attr, type, name, name_len, 205 + NULL); 207 206 } 208 207 209 208 /* First look for list entry of required type. */ ··· 220 217 return NULL; 221 218 222 219 /* Look for required attribute. */ 223 - attr = mi_find_attr(m, NULL, type, name, name_len, &le->id); 220 + attr = mi_find_attr(ni, m, NULL, type, name, name_len, &le->id); 224 221 225 222 if (!attr) 226 223 goto out; ··· 241 238 return attr; 242 239 243 240 out: 244 - ntfs_inode_err(&ni->vfs_inode, "failed to parse mft record"); 245 - ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_ERROR); 241 + _ntfs_bad_inode(&ni->vfs_inode); 246 242 return NULL; 247 243 } 248 244 ··· 261 259 if (mi) 262 260 *mi = &ni->mi; 263 261 /* Enum attributes in primary record. */ 264 - return mi_enum_attr(&ni->mi, attr); 262 + return mi_enum_attr(ni, &ni->mi, attr); 265 263 } 266 264 267 265 /* Get next list entry. */ ··· 277 275 *mi = mi2; 278 276 279 277 /* Find attribute in loaded record. */ 280 - return rec_find_attr_le(mi2, le2); 278 + return rec_find_attr_le(ni, mi2, le2); 281 279 } 282 280 283 281 /* ··· 295 293 if (!ni->attr_list.size) { 296 294 if (pmi) 297 295 *pmi = &ni->mi; 298 - return mi_find_attr(&ni->mi, NULL, type, name, name_len, NULL); 296 + return mi_find_attr(ni, &ni->mi, NULL, type, name, name_len, 297 + NULL); 299 298 } 300 299 301 300 le = al_find_ex(ni, NULL, type, name, name_len, NULL); ··· 322 319 if (pmi) 323 320 *pmi = mi; 324 321 325 - attr = mi_find_attr(mi, NULL, type, name, name_len, &le->id); 322 + attr = mi_find_attr(ni, mi, NULL, type, name, name_len, &le->id); 326 323 if (!attr) 327 324 return NULL; 328 325 ··· 333 330 vcn <= le64_to_cpu(attr->nres.evcn)) 334 331 return attr; 335 332 333 + _ntfs_bad_inode(&ni->vfs_inode); 336 334 return NULL; 337 335 } 338 336 ··· 402 398 int diff; 403 399 404 400 if (base_only || type == ATTR_LIST || !ni->attr_list.size) { 405 - attr = mi_find_attr(&ni->mi, NULL, type, name, name_len, id); 401 + attr = mi_find_attr(ni, &ni->mi, NULL, type, name, name_len, 402 + id); 406 403 if (!attr) 407 404 return -ENOENT; 408 405 ··· 442 437 443 438 al_remove_le(ni, le); 444 439 445 - attr = mi_find_attr(mi, NULL, type, name, name_len, id); 440 + attr = mi_find_attr(ni, mi, NULL, type, name, name_len, id); 446 441 if (!attr) 447 442 return -ENOENT; 448 443 ··· 490 485 name = le->name; 491 486 } 492 487 493 - attr = mi_insert_attr(mi, type, name, name_len, asize, name_off); 488 + attr = mi_insert_attr(ni, mi, type, name, name_len, asize, name_off); 494 489 if (!attr) { 495 490 if (le_added) 496 491 al_remove_le(ni, le); ··· 678 673 if (err) 679 674 return err; 680 675 681 - attr_list = mi_find_attr(&ni->mi, NULL, ATTR_LIST, NULL, 0, NULL); 676 + attr_list = mi_find_attr(ni, &ni->mi, NULL, ATTR_LIST, NULL, 0, NULL); 682 677 if (!attr_list) 683 678 return 0; 684 679 ··· 700 695 if (!mi) 701 696 return 0; 702 697 703 - attr = mi_find_attr(mi, NULL, le->type, le_name(le), 698 + attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le), 704 699 le->name_len, &le->id); 705 700 if (!attr) 706 701 return 0; ··· 736 731 goto out; 737 732 } 738 733 739 - attr = mi_find_attr(mi, NULL, le->type, le_name(le), 734 + attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le), 740 735 le->name_len, &le->id); 741 736 if (!attr) { 742 737 /* Should never happened, 'cause already checked. */ ··· 745 740 asize = le32_to_cpu(attr->size); 746 741 747 742 /* Insert into primary record. */ 748 - attr_ins = mi_insert_attr(&ni->mi, le->type, le_name(le), 743 + attr_ins = mi_insert_attr(ni, &ni->mi, le->type, le_name(le), 749 744 le->name_len, asize, 750 745 le16_to_cpu(attr->name_off)); 751 746 if (!attr_ins) { ··· 773 768 if (!mi) 774 769 continue; 775 770 776 - attr = mi_find_attr(mi, NULL, le->type, le_name(le), 771 + attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le), 777 772 le->name_len, &le->id); 778 773 if (!attr) 779 774 continue; ··· 836 831 free_b = 0; 837 832 attr = NULL; 838 833 839 - for (; (attr = mi_enum_attr(&ni->mi, attr)); le = Add2Ptr(le, sz)) { 834 + for (; (attr = mi_enum_attr(ni, &ni->mi, attr)); le = Add2Ptr(le, sz)) { 840 835 sz = le_size(attr->name_len); 841 836 le->type = attr->type; 842 837 le->size = cpu_to_le16(sz); ··· 891 886 u32 asize = le32_to_cpu(b->size); 892 887 u16 name_off = le16_to_cpu(b->name_off); 893 888 894 - attr = mi_insert_attr(mi, b->type, Add2Ptr(b, name_off), 889 + attr = mi_insert_attr(ni, mi, b->type, Add2Ptr(b, name_off), 895 890 b->name_len, asize, name_off); 896 891 if (!attr) 897 892 goto out; ··· 914 909 goto out; 915 910 } 916 911 917 - attr = mi_insert_attr(&ni->mi, ATTR_LIST, NULL, 0, 912 + attr = mi_insert_attr(ni, &ni->mi, ATTR_LIST, NULL, 0, 918 913 lsize + SIZEOF_RESIDENT, SIZEOF_RESIDENT); 919 914 if (!attr) 920 915 goto out; ··· 998 993 mi = rb_entry(node, struct mft_inode, node); 999 994 1000 995 if (is_mft_data && 1001 - (mi_enum_attr(mi, NULL) || 996 + (mi_enum_attr(ni, mi, NULL) || 1002 997 vbo <= ((u64)mi->rno << sbi->record_bits))) { 1003 998 /* We can't accept this record 'cause MFT's bootstrapping. */ 1004 999 continue; 1005 1000 } 1006 1001 if (is_mft && 1007 - mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0, NULL)) { 1002 + mi_find_attr(ni, mi, NULL, ATTR_DATA, NULL, 0, NULL)) { 1008 1003 /* 1009 1004 * This child record already has a ATTR_DATA. 1010 1005 * So it can't accept any other records. ··· 1013 1008 } 1014 1009 1015 1010 if ((type != ATTR_NAME || name_len) && 1016 - mi_find_attr(mi, NULL, type, name, name_len, NULL)) { 1011 + mi_find_attr(ni, mi, NULL, type, name, name_len, NULL)) { 1017 1012 /* Only indexed attributes can share same record. */ 1018 1013 continue; 1019 1014 } ··· 1162 1157 /* Estimate the result of moving all possible attributes away. */ 1163 1158 attr = NULL; 1164 1159 1165 - while ((attr = mi_enum_attr(&ni->mi, attr))) { 1160 + while ((attr = mi_enum_attr(ni, &ni->mi, attr))) { 1166 1161 if (attr->type == ATTR_STD) 1167 1162 continue; 1168 1163 if (attr->type == ATTR_LIST) ··· 1180 1175 attr = NULL; 1181 1176 1182 1177 for (;;) { 1183 - attr = mi_enum_attr(&ni->mi, attr); 1178 + attr = mi_enum_attr(ni, &ni->mi, attr); 1184 1179 if (!attr) { 1185 1180 /* We should never be here 'cause we have already check this case. */ 1186 1181 err = -EINVAL; ··· 1264 1259 for (node = rb_first(&ni->mi_tree); node; node = rb_next(node)) { 1265 1260 mi = rb_entry(node, struct mft_inode, node); 1266 1261 1267 - attr = mi_enum_attr(mi, NULL); 1262 + attr = mi_enum_attr(ni, mi, NULL); 1268 1263 1269 1264 if (!attr) { 1270 1265 mft_min = mi->rno; ··· 1285 1280 ni_remove_mi(ni, mi_new); 1286 1281 } 1287 1282 1288 - attr = mi_find_attr(&ni->mi, NULL, ATTR_DATA, NULL, 0, NULL); 1283 + attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_DATA, NULL, 0, NULL); 1289 1284 if (!attr) { 1290 1285 err = -EINVAL; 1291 1286 goto out; ··· 1402 1397 continue; 1403 1398 1404 1399 /* Find attribute in primary record. */ 1405 - attr = rec_find_attr_le(&ni->mi, le); 1400 + attr = rec_find_attr_le(ni, &ni->mi, le); 1406 1401 if (!attr) { 1407 1402 err = -EINVAL; 1408 1403 goto out; ··· 1609 1604 roff = le16_to_cpu(attr->nres.run_off); 1610 1605 1611 1606 if (roff > asize) { 1612 - _ntfs_bad_inode(&ni->vfs_inode); 1613 - return -EINVAL; 1607 + /* ni_enum_attr_ex checks this case. */ 1608 + continue; 1614 1609 } 1615 1610 1616 1611 /* run==1 means unpack and deallocate. */ ··· 2731 2726 { 2732 2727 int err; 2733 2728 struct ntfs_sb_info *sbi = ni->mi.sbi; 2729 + struct folio *folio = page_folio(pages[0]); 2734 2730 u8 frame_bits = NTFS_LZNT_CUNIT + sbi->cluster_bits; 2735 2731 u32 frame_size = sbi->cluster_size << NTFS_LZNT_CUNIT; 2736 - u64 frame_vbo = (u64)pages[0]->index << PAGE_SHIFT; 2732 + u64 frame_vbo = folio_pos(folio); 2737 2733 CLST frame = frame_vbo >> frame_bits; 2738 2734 char *frame_ondisk = NULL; 2739 2735 struct page **pages_disk = NULL; ··· 3349 3343 if (!mi->dirty) 3350 3344 continue; 3351 3345 3352 - is_empty = !mi_enum_attr(mi, NULL); 3346 + is_empty = !mi_enum_attr(ni, mi, NULL); 3353 3347 3354 3348 if (is_empty) 3355 3349 clear_rec_inuse(mi->mrec);
+5 -1
fs/ntfs3/fsntfs.c
··· 908 908 909 909 ntfs_inode_err(inode, "%s", hint); 910 910 make_bad_inode(inode); 911 - ntfs_set_state(sbi, NTFS_DIRTY_ERROR); 911 + /* Avoid recursion if bad inode is $Volume. */ 912 + if (inode->i_ino != MFT_REC_VOL && 913 + !(sbi->flags & NTFS_FLAGS_LOG_REPLAYING)) { 914 + ntfs_set_state(sbi, NTFS_DIRTY_ERROR); 915 + } 912 916 } 913 917 914 918 /*
+2 -4
fs/ntfs3/index.c
··· 1094 1094 1095 1095 ok: 1096 1096 if (!index_buf_check(ib, bytes, &vbn)) { 1097 - ntfs_inode_err(&ni->vfs_inode, "directory corrupted"); 1098 - ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_ERROR); 1097 + _ntfs_bad_inode(&ni->vfs_inode); 1099 1098 err = -EINVAL; 1100 1099 goto out; 1101 1100 } ··· 1116 1117 1117 1118 out: 1118 1119 if (err == -E_NTFS_CORRUPT) { 1119 - ntfs_inode_err(&ni->vfs_inode, "directory corrupted"); 1120 - ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_ERROR); 1120 + _ntfs_bad_inode(&ni->vfs_inode); 1121 1121 err = -EINVAL; 1122 1122 } 1123 1123
+3
fs/ntfs3/inode.c
··· 410 410 if (!std5) 411 411 goto out; 412 412 413 + if (is_bad_inode(inode)) 414 + goto out; 415 + 413 416 if (!is_match && name) { 414 417 err = -ENOENT; 415 418 goto out;
+11 -10
fs/ntfs3/ntfs_fs.h
··· 745 745 void mi_put(struct mft_inode *mi); 746 746 int mi_init(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno); 747 747 int mi_read(struct mft_inode *mi, bool is_mft); 748 - struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr); 749 - // TODO: id? 750 - struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr, 751 - enum ATTR_TYPE type, const __le16 *name, 752 - u8 name_len, const __le16 *id); 753 - static inline struct ATTRIB *rec_find_attr_le(struct mft_inode *rec, 748 + struct ATTRIB *mi_enum_attr(struct ntfs_inode *ni, struct mft_inode *mi, 749 + struct ATTRIB *attr); 750 + struct ATTRIB *mi_find_attr(struct ntfs_inode *ni, struct mft_inode *mi, 751 + struct ATTRIB *attr, enum ATTR_TYPE type, 752 + const __le16 *name, u8 name_len, const __le16 *id); 753 + static inline struct ATTRIB *rec_find_attr_le(struct ntfs_inode *ni, 754 + struct mft_inode *rec, 754 755 struct ATTR_LIST_ENTRY *le) 755 756 { 756 - return mi_find_attr(rec, NULL, le->type, le_name(le), le->name_len, 757 + return mi_find_attr(ni, rec, NULL, le->type, le_name(le), le->name_len, 757 758 &le->id); 758 759 } 759 760 int mi_write(struct mft_inode *mi, int wait); 760 761 int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno, 761 762 __le16 flags, bool is_mft); 762 - struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type, 763 - const __le16 *name, u8 name_len, u32 asize, 764 - u16 name_off); 763 + struct ATTRIB *mi_insert_attr(struct ntfs_inode *ni, struct mft_inode *mi, 764 + enum ATTR_TYPE type, const __le16 *name, 765 + u8 name_len, u32 asize, u16 name_off); 765 766 766 767 bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi, 767 768 struct ATTRIB *attr);
+42 -37
fs/ntfs3/record.c
··· 31 31 * 32 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 *mi) 34 + static __le16 mi_new_attt_id(struct ntfs_inode *ni, struct mft_inode *mi) 35 35 { 36 36 u16 free_id, max_id, t16; 37 37 struct MFT_REC *rec = mi->mrec; ··· 52 52 attr = NULL; 53 53 54 54 for (;;) { 55 - attr = mi_enum_attr(mi, attr); 55 + attr = mi_enum_attr(ni, mi, attr); 56 56 if (!attr) { 57 57 rec->next_attr_id = cpu_to_le16(max_id + 1); 58 58 mi->dirty = true; ··· 195 195 * NOTE: mi->mrec - memory of size sbi->record_size 196 196 * here we sure that mi->mrec->total == sbi->record_size (see mi_read) 197 197 */ 198 - struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr) 198 + struct ATTRIB *mi_enum_attr(struct ntfs_inode *ni, struct mft_inode *mi, 199 + struct ATTRIB *attr) 199 200 { 200 201 const struct MFT_REC *rec = mi->mrec; 201 202 u32 used = le32_to_cpu(rec->used); ··· 210 209 off = le16_to_cpu(rec->attr_off); 211 210 212 211 if (used > total) 213 - return NULL; 212 + goto out; 214 213 215 214 if (off >= used || off < MFTRECORD_FIXUP_OFFSET_1 || 216 215 !IS_ALIGNED(off, 8)) { 217 - return NULL; 216 + goto out; 218 217 } 219 218 220 219 /* Skip non-resident records. */ ··· 244 243 */ 245 244 if (off + 8 > used) { 246 245 static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8); 247 - return NULL; 246 + goto out; 248 247 } 249 248 250 249 if (attr->type == ATTR_END) { ··· 255 254 /* 0x100 is last known attribute for now. */ 256 255 t32 = le32_to_cpu(attr->type); 257 256 if (!t32 || (t32 & 0xf) || (t32 > 0x100)) 258 - return NULL; 257 + goto out; 259 258 260 259 /* attributes in record must be ordered by type */ 261 260 if (t32 < prev_type) 262 - return NULL; 261 + goto out; 263 262 264 263 asize = le32_to_cpu(attr->size); 265 264 266 265 if (!IS_ALIGNED(asize, 8)) 267 - return NULL; 266 + goto out; 268 267 269 268 /* Check overflow and boundary. */ 270 269 if (off + asize < off || off + asize > used) 271 - return NULL; 270 + goto out; 272 271 273 272 /* Can we use the field attr->non_res. */ 274 273 if (off + 9 > used) 275 - return NULL; 274 + goto out; 276 275 277 276 /* Check size of attribute. */ 278 277 if (!attr->non_res) { 279 278 /* Check resident fields. */ 280 279 if (asize < SIZEOF_RESIDENT) 281 - return NULL; 280 + goto out; 282 281 283 282 t16 = le16_to_cpu(attr->res.data_off); 284 283 if (t16 > asize) 285 - return NULL; 284 + goto out; 286 285 287 286 if (le32_to_cpu(attr->res.data_size) > asize - t16) 288 - return NULL; 287 + goto out; 289 288 290 289 t32 = sizeof(short) * attr->name_len; 291 290 if (t32 && le16_to_cpu(attr->name_off) + t32 > t16) 292 - return NULL; 291 + goto out; 293 292 294 293 return attr; 295 294 } 296 295 297 296 /* Check nonresident fields. */ 298 297 if (attr->non_res != 1) 299 - return NULL; 298 + goto out; 300 299 301 300 /* Can we use memory including attr->nres.valid_size? */ 302 301 if (asize < SIZEOF_NONRESIDENT) 303 - return NULL; 302 + goto out; 304 303 305 304 t16 = le16_to_cpu(attr->nres.run_off); 306 305 if (t16 > asize) 307 - return NULL; 306 + goto out; 308 307 309 308 t32 = sizeof(short) * attr->name_len; 310 309 if (t32 && le16_to_cpu(attr->name_off) + t32 > t16) 311 - return NULL; 310 + goto out; 312 311 313 312 /* Check start/end vcn. */ 314 313 if (le64_to_cpu(attr->nres.svcn) > le64_to_cpu(attr->nres.evcn) + 1) 315 - return NULL; 314 + goto out; 316 315 317 316 data_size = le64_to_cpu(attr->nres.data_size); 318 317 if (le64_to_cpu(attr->nres.valid_size) > data_size) 319 - return NULL; 318 + goto out; 320 319 321 320 alloc_size = le64_to_cpu(attr->nres.alloc_size); 322 321 if (data_size > alloc_size) 323 - return NULL; 322 + goto out; 324 323 325 324 t32 = mi->sbi->cluster_mask; 326 325 if (alloc_size & t32) 327 - return NULL; 326 + goto out; 328 327 329 328 if (!attr->nres.svcn && is_attr_ext(attr)) { 330 329 /* First segment of sparse/compressed attribute */ 331 330 /* Can we use memory including attr->nres.total_size? */ 332 331 if (asize < SIZEOF_NONRESIDENT_EX) 333 - return NULL; 332 + goto out; 334 333 335 334 tot_size = le64_to_cpu(attr->nres.total_size); 336 335 if (tot_size & t32) 337 - return NULL; 336 + goto out; 338 337 339 338 if (tot_size > alloc_size) 340 - return NULL; 339 + goto out; 341 340 } else { 342 341 if (attr->nres.c_unit) 343 - return NULL; 342 + goto out; 344 343 345 344 if (alloc_size > mi->sbi->volume.size) 346 - return NULL; 345 + goto out; 347 346 } 348 347 349 348 return attr; 349 + 350 + out: 351 + _ntfs_bad_inode(&ni->vfs_inode); 352 + return NULL; 350 353 } 351 354 352 355 /* 353 356 * mi_find_attr - Find the attribute by type and name and id. 354 357 */ 355 - struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr, 356 - enum ATTR_TYPE type, const __le16 *name, 357 - u8 name_len, const __le16 *id) 358 + struct ATTRIB *mi_find_attr(struct ntfs_inode *ni, struct mft_inode *mi, 359 + struct ATTRIB *attr, enum ATTR_TYPE type, 360 + const __le16 *name, u8 name_len, const __le16 *id) 358 361 { 359 362 u32 type_in = le32_to_cpu(type); 360 363 u32 atype; 361 364 362 365 next_attr: 363 - attr = mi_enum_attr(mi, attr); 366 + attr = mi_enum_attr(ni, mi, attr); 364 367 if (!attr) 365 368 return NULL; 366 369 ··· 472 467 * 473 468 * Return: Not full constructed attribute or NULL if not possible to create. 474 469 */ 475 - struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type, 476 - const __le16 *name, u8 name_len, u32 asize, 477 - u16 name_off) 470 + struct ATTRIB *mi_insert_attr(struct ntfs_inode *ni, struct mft_inode *mi, 471 + enum ATTR_TYPE type, const __le16 *name, 472 + u8 name_len, u32 asize, u16 name_off) 478 473 { 479 474 size_t tail; 480 475 struct ATTRIB *attr; ··· 493 488 * at which we should insert it. 494 489 */ 495 490 attr = NULL; 496 - while ((attr = mi_enum_attr(mi, attr))) { 491 + while ((attr = mi_enum_attr(ni, mi, attr))) { 497 492 int diff = compare_attr(attr, type, name, name_len, upcase); 498 493 499 494 if (diff < 0) ··· 513 508 tail = used - PtrOffset(rec, attr); 514 509 } 515 510 516 - id = mi_new_attt_id(mi); 511 + id = mi_new_attt_id(ni, mi); 517 512 518 513 memmove(Add2Ptr(attr, asize), attr, tail); 519 514 memset(attr, 0, asize);