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

Pull ntfs3 updates from Konstantin Komarov:

- Fix integer overflows on 32-bit systems and in hdr_first_de()

- Fix 'proc_info_root' leak on NTFS initialization failure

- Remove unused functions ni_load_attr, ntfs_sb_read, ntfs_flush_inodes

- update inode->i_mapping->a_ops on compression state

- ensure atomicity of write operations

- refactor ntfs_{create/remove}_{procdir,proc_root}()

* tag 'ntfs3_for_6.15' of https://github.com/Paragon-Software-Group/linux-ntfs3:
fs/ntfs3: Remove unused ntfs_flush_inodes
fs/ntfs3: Remove unused ntfs_sb_read
fs/ntfs3: Remove unused ni_load_attr
fs/ntfs3: Prevent integer overflow in hdr_first_de()
fs/ntfs3: Fix a couple integer overflows on 32bit systems
fs/ntfs3: Update inode->i_mapping->a_ops on compression state
fs/ntfs3: Fix WARNING in ntfs_extend_initialized_size
fs/ntfs3: Fix 'proc_info_root' leak when init ntfs failed
fs/ntfs3: Factor out ntfs_{create/remove}_proc_root()
fs/ntfs3: Factor out ntfs_{create/remove}_procdir()
fs/ntfs3: Keep write operations atomic

+96 -181
+2 -1
fs/ntfs3/attrib.c
··· 2664 2664 attr->nres.run_off = cpu_to_le16(run_off); 2665 2665 } 2666 2666 2667 - /* Update data attribute flags. */ 2667 + /* Update attribute flags. */ 2668 2668 if (compr) { 2669 + attr->flags &= ~ATTR_FLAG_SPARSED; 2669 2670 attr->flags |= ATTR_FLAG_COMPRESSED; 2670 2671 attr->nres.c_unit = NTFS_LZNT_CUNIT; 2671 2672 } else {
+31 -11
fs/ntfs3/file.c
··· 101 101 /* Allowed to change compression for empty files and for directories only. */ 102 102 if (!is_dedup(ni) && !is_encrypted(ni) && 103 103 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { 104 - /* Change compress state. */ 105 - int err = ni_set_compress(inode, flags & FS_COMPR_FL); 104 + int err = 0; 105 + struct address_space *mapping = inode->i_mapping; 106 + 107 + /* write out all data and wait. */ 108 + filemap_invalidate_lock(mapping); 109 + err = filemap_write_and_wait(mapping); 110 + 111 + if (err >= 0) { 112 + /* Change compress state. */ 113 + bool compr = flags & FS_COMPR_FL; 114 + err = ni_set_compress(inode, compr); 115 + 116 + /* For files change a_ops too. */ 117 + if (!err) 118 + mapping->a_ops = compr ? &ntfs_aops_cmpr : 119 + &ntfs_aops; 120 + } 121 + 122 + filemap_invalidate_unlock(mapping); 123 + 106 124 if (err) 107 125 return err; 108 126 } ··· 430 412 } 431 413 432 414 if (extend_init && !is_compressed(ni)) { 415 + WARN_ON(ni->i_valid >= pos); 433 416 err = ntfs_extend_initialized_size(file, ni, ni->i_valid, pos); 434 417 if (err) 435 418 goto out; ··· 1247 1228 ssize_t ret; 1248 1229 int err; 1249 1230 1250 - err = check_write_restriction(inode); 1251 - if (err) 1252 - return err; 1253 - 1254 - if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) { 1255 - ntfs_inode_warn(inode, "direct i/o + compressed not supported"); 1256 - return -EOPNOTSUPP; 1257 - } 1258 - 1259 1231 if (!inode_trylock(inode)) { 1260 1232 if (iocb->ki_flags & IOCB_NOWAIT) 1261 1233 return -EAGAIN; 1262 1234 inode_lock(inode); 1235 + } 1236 + 1237 + ret = check_write_restriction(inode); 1238 + if (ret) 1239 + goto out; 1240 + 1241 + if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) { 1242 + ntfs_inode_warn(inode, "direct i/o + compressed not supported"); 1243 + ret = -EOPNOTSUPP; 1244 + goto out; 1263 1245 } 1264 1246 1265 1247 ret = generic_write_checks(iocb, from);
+4 -59
fs/ntfs3/frecord.c
··· 281 281 } 282 282 283 283 /* 284 - * ni_load_attr - Load attribute that contains given VCN. 285 - */ 286 - struct ATTRIB *ni_load_attr(struct ntfs_inode *ni, enum ATTR_TYPE type, 287 - const __le16 *name, u8 name_len, CLST vcn, 288 - struct mft_inode **pmi) 289 - { 290 - struct ATTR_LIST_ENTRY *le; 291 - struct ATTRIB *attr; 292 - struct mft_inode *mi; 293 - struct ATTR_LIST_ENTRY *next; 294 - 295 - if (!ni->attr_list.size) { 296 - if (pmi) 297 - *pmi = &ni->mi; 298 - return mi_find_attr(ni, &ni->mi, NULL, type, name, name_len, 299 - NULL); 300 - } 301 - 302 - le = al_find_ex(ni, NULL, type, name, name_len, NULL); 303 - if (!le) 304 - return NULL; 305 - 306 - /* 307 - * Unfortunately ATTR_LIST_ENTRY contains only start VCN. 308 - * So to find the ATTRIB segment that contains 'vcn' we should 309 - * enumerate some entries. 310 - */ 311 - if (vcn) { 312 - for (;; le = next) { 313 - next = al_find_ex(ni, le, type, name, name_len, NULL); 314 - if (!next || le64_to_cpu(next->vcn) > vcn) 315 - break; 316 - } 317 - } 318 - 319 - if (ni_load_mi(ni, le, &mi)) 320 - return NULL; 321 - 322 - if (pmi) 323 - *pmi = mi; 324 - 325 - attr = mi_find_attr(ni, mi, NULL, type, name, name_len, &le->id); 326 - if (!attr) 327 - return NULL; 328 - 329 - if (!attr->non_res) 330 - return attr; 331 - 332 - if (le64_to_cpu(attr->nres.svcn) <= vcn && 333 - vcn <= le64_to_cpu(attr->nres.evcn)) 334 - return attr; 335 - 336 - _ntfs_bad_inode(&ni->vfs_inode); 337 - return NULL; 338 - } 339 - 340 - /* 341 284 * ni_load_all_mi - Load all subrecords. 342 285 */ 343 286 int ni_load_all_mi(struct ntfs_inode *ni) ··· 3377 3434 } 3378 3435 3379 3436 ni->std_fa = std->fa; 3380 - if (compr) 3437 + if (compr) { 3438 + std->fa &= ~FILE_ATTRIBUTE_SPARSE_FILE; 3381 3439 std->fa |= FILE_ATTRIBUTE_COMPRESSED; 3382 - else 3440 + } else { 3383 3441 std->fa &= ~FILE_ATTRIBUTE_COMPRESSED; 3442 + } 3384 3443 3385 3444 if (ni->std_fa != std->fa) { 3386 3445 ni->std_fa = std->fa;
-28
fs/ntfs3/fsntfs.c
··· 1035 1035 return NULL; 1036 1036 } 1037 1037 1038 - int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer) 1039 - { 1040 - struct block_device *bdev = sb->s_bdev; 1041 - u32 blocksize = sb->s_blocksize; 1042 - u64 block = lbo >> sb->s_blocksize_bits; 1043 - u32 off = lbo & (blocksize - 1); 1044 - u32 op = blocksize - off; 1045 - 1046 - for (; bytes; block += 1, off = 0, op = blocksize) { 1047 - struct buffer_head *bh = __bread(bdev, block, blocksize); 1048 - 1049 - if (!bh) 1050 - return -EIO; 1051 - 1052 - if (op > bytes) 1053 - op = bytes; 1054 - 1055 - memcpy(buffer, bh->b_data + off, op); 1056 - 1057 - put_bh(bh); 1058 - 1059 - bytes -= op; 1060 - buffer = Add2Ptr(buffer, op); 1061 - } 1062 - 1063 - return 0; 1064 - } 1065 - 1066 1038 int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes, 1067 1039 const void *buf, int wait) 1068 1040 {
+2 -2
fs/ntfs3/index.c
··· 618 618 u32 off = le32_to_cpu(hdr->de_off); 619 619 620 620 if (!IS_ALIGNED(off, 8) || tot > bytes || end > tot || 621 - off + sizeof(struct NTFS_DE) > end) { 621 + size_add(off, sizeof(struct NTFS_DE)) > end) { 622 622 /* incorrect index buffer. */ 623 623 return false; 624 624 } ··· 736 736 if (end > total) 737 737 return NULL; 738 738 739 - if (off + sizeof(struct NTFS_DE) > end) 739 + if (size_add(off, sizeof(struct NTFS_DE)) > end) 740 740 return NULL; 741 741 742 742 e = Add2Ptr(hdr, off);
-40
fs/ntfs3/inode.c
··· 1025 1025 } 1026 1026 1027 1027 /* 1028 - * writeback_inode - Helper function for ntfs_flush_inodes(). 1029 - * 1030 - * This writes both the inode and the file data blocks, waiting 1031 - * for in flight data blocks before the start of the call. It 1032 - * does not wait for any io started during the call. 1033 - */ 1034 - static int writeback_inode(struct inode *inode) 1035 - { 1036 - int ret = sync_inode_metadata(inode, 0); 1037 - 1038 - if (!ret) 1039 - ret = filemap_fdatawrite(inode->i_mapping); 1040 - return ret; 1041 - } 1042 - 1043 - /* 1044 - * ntfs_flush_inodes 1045 - * 1046 - * Write data and metadata corresponding to i1 and i2. The io is 1047 - * started but we do not wait for any of it to finish. 1048 - * 1049 - * filemap_flush() is used for the block device, so if there is a dirty 1050 - * page for a block already in flight, we will not wait and start the 1051 - * io over again. 1052 - */ 1053 - int ntfs_flush_inodes(struct super_block *sb, struct inode *i1, 1054 - struct inode *i2) 1055 - { 1056 - int ret = 0; 1057 - 1058 - if (i1) 1059 - ret = writeback_inode(i1); 1060 - if (!ret && i2) 1061 - ret = writeback_inode(i2); 1062 - if (!ret) 1063 - ret = filemap_flush(sb->s_bdev_file->f_mapping); 1064 - return ret; 1065 - } 1066 - 1067 - /* 1068 1028 * Helper function to read file. 1069 1029 */ 1070 1030 int inode_read_data(struct inode *inode, void *data, size_t bytes)
+1 -1
fs/ntfs3/ntfs.h
··· 717 717 struct NTFS_DE *e; 718 718 u16 esize; 719 719 720 - if (de_off >= used || de_off + sizeof(struct NTFS_DE) > used ) 720 + if (de_off >= used || size_add(de_off, sizeof(struct NTFS_DE)) > used) 721 721 return NULL; 722 722 723 723 e = Add2Ptr(hdr, de_off);
-6
fs/ntfs3/ntfs_fs.h
··· 530 530 struct ATTRIB *ni_enum_attr_ex(struct ntfs_inode *ni, struct ATTRIB *attr, 531 531 struct ATTR_LIST_ENTRY **le, 532 532 struct mft_inode **mi); 533 - struct ATTRIB *ni_load_attr(struct ntfs_inode *ni, enum ATTR_TYPE type, 534 - const __le16 *name, u8 name_len, CLST vcn, 535 - struct mft_inode **pmi); 536 533 int ni_load_all_mi(struct ntfs_inode *ni); 537 534 bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi); 538 535 int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type, ··· 616 619 NTFS_DIRTY_ERROR = 2, 617 620 }; 618 621 int ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty); 619 - int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer); 620 622 int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes, 621 623 const void *buffer, int wait); 622 624 int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run, ··· 713 717 u32 len, u32 copied, struct folio *folio, void *fsdata); 714 718 int ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc); 715 719 int ntfs_sync_inode(struct inode *inode); 716 - int ntfs_flush_inodes(struct super_block *sb, struct inode *i1, 717 - struct inode *i2); 718 720 int inode_read_data(struct inode *inode, void *data, size_t bytes); 719 721 int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, 720 722 struct dentry *dentry, const struct cpu_str *uni,
+56 -33
fs/ntfs3/super.c
··· 555 555 .proc_write = ntfs3_label_write, 556 556 }; 557 557 558 + static void ntfs_create_procdir(struct super_block *sb) 559 + { 560 + struct proc_dir_entry *e; 561 + 562 + if (!proc_info_root) 563 + return; 564 + 565 + e = proc_mkdir(sb->s_id, proc_info_root); 566 + if (e) { 567 + struct ntfs_sb_info *sbi = sb->s_fs_info; 568 + 569 + proc_create_data("volinfo", 0444, e, 570 + &ntfs3_volinfo_fops, sb); 571 + proc_create_data("label", 0644, e, 572 + &ntfs3_label_fops, sb); 573 + sbi->procdir = e; 574 + } 575 + } 576 + 577 + static void ntfs_remove_procdir(struct super_block *sb) 578 + { 579 + struct ntfs_sb_info *sbi = sb->s_fs_info; 580 + 581 + if (!sbi->procdir) 582 + return; 583 + 584 + remove_proc_entry("label", sbi->procdir); 585 + remove_proc_entry("volinfo", sbi->procdir); 586 + remove_proc_entry(sb->s_id, proc_info_root); 587 + sbi->procdir = NULL; 588 + } 589 + 590 + static void ntfs_create_proc_root(void) 591 + { 592 + proc_info_root = proc_mkdir("fs/ntfs3", NULL); 593 + } 594 + 595 + static void ntfs_remove_proc_root(void) 596 + { 597 + if (proc_info_root) { 598 + remove_proc_entry("fs/ntfs3", NULL); 599 + proc_info_root = NULL; 600 + } 601 + } 602 + #else 603 + static void ntfs_create_procdir(struct super_block *sb) {} 604 + static void ntfs_remove_procdir(struct super_block *sb) {} 605 + static void ntfs_create_proc_root(void) {} 606 + static void ntfs_remove_proc_root(void) {} 558 607 #endif 559 608 560 609 static struct kmem_cache *ntfs_inode_cachep; ··· 693 644 { 694 645 struct ntfs_sb_info *sbi = sb->s_fs_info; 695 646 696 - #ifdef CONFIG_PROC_FS 697 - // Remove /proc/fs/ntfs3/.. 698 - if (sbi->procdir) { 699 - remove_proc_entry("label", sbi->procdir); 700 - remove_proc_entry("volinfo", sbi->procdir); 701 - remove_proc_entry(sb->s_id, proc_info_root); 702 - sbi->procdir = NULL; 703 - } 704 - #endif 647 + ntfs_remove_procdir(sb); 705 648 706 649 /* Mark rw ntfs as clear, if possible. */ 707 650 ntfs_set_state(sbi, NTFS_DIRTY_CLEAR); ··· 1631 1590 kfree(boot2); 1632 1591 } 1633 1592 1634 - #ifdef CONFIG_PROC_FS 1635 - /* Create /proc/fs/ntfs3/.. */ 1636 - if (proc_info_root) { 1637 - struct proc_dir_entry *e = proc_mkdir(sb->s_id, proc_info_root); 1638 - static_assert((S_IRUGO | S_IWUSR) == 0644); 1639 - if (e) { 1640 - proc_create_data("volinfo", S_IRUGO, e, 1641 - &ntfs3_volinfo_fops, sb); 1642 - proc_create_data("label", S_IRUGO | S_IWUSR, e, 1643 - &ntfs3_label_fops, sb); 1644 - sbi->procdir = e; 1645 - } 1646 - } 1647 - #endif 1593 + ntfs_create_procdir(sb); 1648 1594 1649 1595 if (is_legacy_ntfs(sb)) 1650 1596 sb->s_flags |= SB_RDONLY; ··· 1881 1853 if (IS_ENABLED(CONFIG_NTFS3_LZX_XPRESS)) 1882 1854 pr_info("ntfs3: Read-only LZX/Xpress compression included\n"); 1883 1855 1884 - #ifdef CONFIG_PROC_FS 1885 - /* Create "/proc/fs/ntfs3" */ 1886 - proc_info_root = proc_mkdir("fs/ntfs3", NULL); 1887 - #endif 1856 + ntfs_create_proc_root(); 1888 1857 1889 1858 err = ntfs3_init_bitmap(); 1890 1859 if (err) 1891 - return err; 1860 + goto out2; 1892 1861 1893 1862 ntfs_inode_cachep = kmem_cache_create( 1894 1863 "ntfs_inode_cache", sizeof(struct ntfs_inode), 0, ··· 1905 1880 kmem_cache_destroy(ntfs_inode_cachep); 1906 1881 out1: 1907 1882 ntfs3_exit_bitmap(); 1883 + out2: 1884 + ntfs_remove_proc_root(); 1908 1885 return err; 1909 1886 } 1910 1887 ··· 1917 1890 unregister_filesystem(&ntfs_fs_type); 1918 1891 unregister_as_ntfs_legacy(); 1919 1892 ntfs3_exit_bitmap(); 1920 - 1921 - #ifdef CONFIG_PROC_FS 1922 - if (proc_info_root) 1923 - remove_proc_entry("fs/ntfs3", NULL); 1924 - #endif 1893 + ntfs_remove_proc_root(); 1925 1894 } 1926 1895 1927 1896 MODULE_LICENSE("GPL");