Hello Konstantin Komarov, The patch be71b5cba2e6: "fs/ntfs3: Add attrib operations" from Aug 13, 2021, leads to the following Smatch static checker warning: fs/ntfs3/attrib.c:1031 attr_data_get_block() warn: missing error code here? 'ni_load_mi()' failed. 'err' = '0' fs/ntfs3/attrib.c 823 int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, 824 CLST *len, bool *new) 825 { 826 int err = 0; 827 struct runs_tree *run = &ni->file.run; 828 struct ntfs_sb_info *sbi; 829 u8 cluster_bits; 830 struct ATTRIB *attr = NULL, *attr_b; 831 struct ATTR_LIST_ENTRY *le, *le_b; 832 struct mft_inode *mi, *mi_b; 833 CLST hint, svcn, to_alloc, evcn1, next_svcn, asize, end; 834 u64 total_size; 835 u32 clst_per_frame; 836 bool ok; 837 838 if (new) 839 *new = false; 840 841 down_read(&ni->file.run_lock); 842 ok = run_lookup_entry(run, vcn, lcn, len, NULL); 843 up_read(&ni->file.run_lock); 844 845 if (ok && (*lcn != SPARSE_LCN || !new)) { 846 /* normal way */ 847 return 0; 848 } 849 850 if (!clen) 851 clen = 1; 852 853 if (ok && clen > *len) 854 clen = *len; 855 856 sbi = ni->mi.sbi; 857 cluster_bits = sbi->cluster_bits; 858 859 ni_lock(ni); 860 down_write(&ni->file.run_lock); 861 862 le_b = NULL; 863 attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL, &mi_b); 864 if (!attr_b) { 865 err = -ENOENT; 866 goto out; 867 } 868 869 if (!attr_b->non_res) { 870 *lcn = RESIDENT_LCN; 871 *len = 1; 872 goto out; 873 } 874 875 asize = le64_to_cpu(attr_b->nres.alloc_size) >> sbi->cluster_bits; 876 if (vcn >= asize) { 877 err = -EINVAL; 878 goto out; 879 } 880 881 clst_per_frame = 1u << attr_b->nres.c_unit; 882 to_alloc = (clen + clst_per_frame - 1) & ~(clst_per_frame - 1); 883 884 if (vcn + to_alloc > asize) 885 to_alloc = asize - vcn; 886 887 svcn = le64_to_cpu(attr_b->nres.svcn); 888 evcn1 = le64_to_cpu(attr_b->nres.evcn) + 1; 889 890 attr = attr_b; 891 le = le_b; 892 mi = mi_b; 893 894 if (le_b && (vcn < svcn || evcn1 <= vcn)) { 895 attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0, &vcn, 896 &mi); 897 if (!attr) { 898 err = -EINVAL; 899 goto out; 900 } 901 svcn = le64_to_cpu(attr->nres.svcn); 902 evcn1 = le64_to_cpu(attr->nres.evcn) + 1; 903 } 904 905 err = attr_load_runs(attr, ni, run, NULL); 906 if (err) 907 goto out; 908 909 if (!ok) { 910 ok = run_lookup_entry(run, vcn, lcn, len, NULL); 911 if (ok && (*lcn != SPARSE_LCN || !new)) { 912 /* normal way */ 913 err = 0; 914 goto ok; 915 } 916 917 if (!ok && !new) { 918 *len = 0; 919 err = 0; 920 goto ok; 921 } 922 923 if (ok && clen > *len) { 924 clen = *len; 925 to_alloc = (clen + clst_per_frame - 1) & 926 ~(clst_per_frame - 1); 927 } 928 } 929 930 if (!is_attr_ext(attr_b)) { 931 err = -EINVAL; 932 goto out; 933 } 934 935 /* Get the last lcn to allocate from */ 936 hint = 0; 937 938 if (vcn > evcn1) { 939 if (!run_add_entry(run, evcn1, SPARSE_LCN, vcn - evcn1, 940 false)) { 941 err = -ENOMEM; 942 goto out; 943 } 944 } else if (vcn && !run_lookup_entry(run, vcn - 1, &hint, NULL, NULL)) { 945 hint = -1; 946 } 947 948 err = attr_allocate_clusters( 949 sbi, run, vcn, hint + 1, to_alloc, NULL, 0, len, 950 (sbi->record_size - le32_to_cpu(mi->mrec->used) + 8) / 3 + 1, 951 lcn); 952 if (err) 953 goto out; 954 *new = true; 955 956 end = vcn + *len; 957 958 total_size = le64_to_cpu(attr_b->nres.total_size) + 959 ((u64)*len << cluster_bits); 960 961 repack: 962 err = mi_pack_runs(mi, attr, run, max(end, evcn1) - svcn); 963 if (err) 964 goto out; 965 966 attr_b->nres.total_size = cpu_to_le64(total_size); 967 inode_set_bytes(&ni->vfs_inode, total_size); 968 ni->ni_flags |= NI_FLAG_UPDATE_PARENT; 969 970 mi_b->dirty = true; 971 mark_inode_dirty(&ni->vfs_inode); 972 973 /* stored [vcn : next_svcn) from [vcn : end) */ 974 next_svcn = le64_to_cpu(attr->nres.evcn) + 1; 975 976 if (end <= evcn1) { 977 if (next_svcn == evcn1) { 978 /* Normal way. update attribute and exit */ 979 goto ok; 980 } 981 /* add new segment [next_svcn : evcn1 - next_svcn )*/ 982 if (!ni->attr_list.size) { 983 err = ni_create_attr_list(ni); 984 if (err) 985 goto out; 986 /* layout of records is changed */ 987 le_b = NULL; 988 attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 989 0, NULL, &mi_b); 990 if (!attr_b) { 991 err = -ENOENT; 992 goto out; 993 } 994 995 attr = attr_b; 996 le = le_b; 997 mi = mi_b; 998 goto repack; 999 } 1000 } 1001 1002 svcn = evcn1; 1003 1004 /* Estimate next attribute */ 1005 attr = ni_find_attr(ni, attr, &le, ATTR_DATA, NULL, 0, &svcn, &mi); 1006 1007 if (attr) { 1008 CLST alloc = bytes_to_cluster( 1009 sbi, le64_to_cpu(attr_b->nres.alloc_size)); 1010 CLST evcn = le64_to_cpu(attr->nres.evcn); 1011 1012 if (end < next_svcn) 1013 end = next_svcn; 1014 while (end > evcn) { 1015 /* remove segment [svcn : evcn)*/ 1016 mi_remove_attr(mi, attr); 1017 1018 if (!al_remove_le(ni, le)) { 1019 err = -EINVAL; 1020 goto out; 1021 } 1022 1023 if (evcn + 1 >= alloc) { 1024 /* last attribute segment */ 1025 evcn1 = evcn + 1; 1026 goto ins_ext; 1027 } 1028 1029 if (ni_load_mi(ni, le, &mi)) { 1030 attr = NULL; No error code on this path. Also no need to set "attr" to NULL. --> 1031 goto out; 1032 } 1033 1034 attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0, 1035 &le->id); 1036 if (!attr) { 1037 err = -EINVAL; 1038 goto out; 1039 } 1040 svcn = le64_to_cpu(attr->nres.svcn); 1041 evcn = le64_to_cpu(attr->nres.evcn); 1042 } 1043 1044 if (end < svcn) 1045 end = svcn; 1046 1047 err = attr_load_runs(attr, ni, run, &end); 1048 if (err) 1049 goto out; 1050 1051 evcn1 = evcn + 1; 1052 attr->nres.svcn = cpu_to_le64(next_svcn); 1053 err = mi_pack_runs(mi, attr, run, evcn1 - next_svcn); 1054 if (err) 1055 goto out; 1056 1057 le->vcn = cpu_to_le64(next_svcn); 1058 ni->attr_list.dirty = true; 1059 mi->dirty = true; 1060 1061 next_svcn = le64_to_cpu(attr->nres.evcn) + 1; 1062 } 1063 ins_ext: 1064 if (evcn1 > next_svcn) { 1065 err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run, 1066 next_svcn, evcn1 - next_svcn, 1067 attr_b->flags, &attr, &mi); 1068 if (err) 1069 goto out; 1070 } 1071 ok: 1072 run_truncate_around(run, vcn); 1073 out: 1074 up_write(&ni->file.run_lock); 1075 ni_unlock(ni); 1076 1077 return err; 1078 } regards, dan carpenter