From: Dan Carpenter <dan.carpenter@oracle.com>
To: almaz.alexandrovich@paragon-software.com
Cc: ntfs3@lists.linux.dev
Subject: [bug report] fs/ntfs3: missing error code in attr_data_get_block()
Date: Fri, 27 Aug 2021 11:57:57 +0300 [thread overview]
Message-ID: <20210827085757.GA9449@kili> (raw)
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
next reply other threads:[~2021-08-27 8:58 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-27 8:57 Dan Carpenter [this message]
2021-08-27 9:43 ` [bug report] fs/ntfs3: missing error code in attr_data_get_block() Kari Argillander
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210827085757.GA9449@kili \
--to=dan.carpenter@oracle.com \
--cc=almaz.alexandrovich@paragon-software.com \
--cc=ntfs3@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.