All of lore.kernel.org
 help / color / mirror / Atom feed
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

             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.