* [bug report] fs/ntfs3: missing error code in attr_data_get_block()
@ 2021-08-27 8:57 Dan Carpenter
2021-08-27 9:43 ` Kari Argillander
0 siblings, 1 reply; 2+ messages in thread
From: Dan Carpenter @ 2021-08-27 8:57 UTC (permalink / raw)
To: almaz.alexandrovich; +Cc: ntfs3
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
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [bug report] fs/ntfs3: missing error code in attr_data_get_block()
2021-08-27 8:57 [bug report] fs/ntfs3: missing error code in attr_data_get_block() Dan Carpenter
@ 2021-08-27 9:43 ` Kari Argillander
0 siblings, 0 replies; 2+ messages in thread
From: Kari Argillander @ 2021-08-27 9:43 UTC (permalink / raw)
To: Dan Carpenter; +Cc: almaz.alexandrovich, ntfs3
On Fri, Aug 27, 2021 at 11:57:57AM +0300, Dan Carpenter wrote:
> 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.
This same code can also be founded from attr_allocate_frame(). This
"repack" really needs to be own function.
>
> --> 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
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-08-27 9:43 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-08-27 8:57 [bug report] fs/ntfs3: missing error code in attr_data_get_block() Dan Carpenter
2021-08-27 9:43 ` Kari Argillander
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox