fs/ntfs/aops.c:899:12: warning: stack frame size of 2528 bytes in function 'ntfs_write_mst_block'

From: kernel test robot
Date: Tue Feb 02 2021 - 09:54:59 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 88bb507a74ea7d75fa49edd421eaa710a7d80598
commit: d0a3ac549f389c1511a4df0d7638536305205d20 ubsan: enable for all*config builds
date: 7 weeks ago
config: powerpc-randconfig-r035-20210202 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 275c6af7d7f1ed63a03d05b4484413e447133269)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc cross compiling tool for clang build
# apt-get install binutils-powerpc-linux-gnu
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d0a3ac549f389c1511a4df0d7638536305205d20
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout d0a3ac549f389c1511a4df0d7638536305205d20
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>

All warnings (new ones prefixed by >>):

>> fs/ntfs/aops.c:899:12: warning: stack frame size of 2528 bytes in function 'ntfs_write_mst_block' [-Wframe-larger-than=]
static int ntfs_write_mst_block(struct page *page,
^
1 warning generated.


vim +/ntfs_write_mst_block +899 fs/ntfs/aops.c

^1da177e4c3f41 Linus Torvalds 2005-04-16 874
^1da177e4c3f41 Linus Torvalds 2005-04-16 875 /**
^1da177e4c3f41 Linus Torvalds 2005-04-16 876 * ntfs_write_mst_block - write a @page to the backing store
^1da177e4c3f41 Linus Torvalds 2005-04-16 877 * @page: page cache page to write out
^1da177e4c3f41 Linus Torvalds 2005-04-16 878 * @wbc: writeback control structure
^1da177e4c3f41 Linus Torvalds 2005-04-16 879 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 880 * This function is for writing pages belonging to non-resident, mst protected
^1da177e4c3f41 Linus Torvalds 2005-04-16 881 * attributes to their backing store. The only supported attributes are index
^1da177e4c3f41 Linus Torvalds 2005-04-16 882 * allocation and $MFT/$DATA. Both directory inodes and index inodes are
^1da177e4c3f41 Linus Torvalds 2005-04-16 883 * supported for the index allocation case.
^1da177e4c3f41 Linus Torvalds 2005-04-16 884 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 885 * The page must remain locked for the duration of the write because we apply
^1da177e4c3f41 Linus Torvalds 2005-04-16 886 * the mst fixups, write, and then undo the fixups, so if we were to unlock the
^1da177e4c3f41 Linus Torvalds 2005-04-16 887 * page before undoing the fixups, any other user of the page will see the
^1da177e4c3f41 Linus Torvalds 2005-04-16 888 * page contents as corrupt.
^1da177e4c3f41 Linus Torvalds 2005-04-16 889 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 890 * We clear the page uptodate flag for the duration of the function to ensure
^1da177e4c3f41 Linus Torvalds 2005-04-16 891 * exclusion for the $MFT/$DATA case against someone mapping an mft record we
^1da177e4c3f41 Linus Torvalds 2005-04-16 892 * are about to apply the mst fixups to.
^1da177e4c3f41 Linus Torvalds 2005-04-16 893 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 894 * Return 0 on success and -errno on error.
^1da177e4c3f41 Linus Torvalds 2005-04-16 895 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 896 * Based on ntfs_write_block(), ntfs_mft_writepage(), and
^1da177e4c3f41 Linus Torvalds 2005-04-16 897 * write_mft_record_nolock().
^1da177e4c3f41 Linus Torvalds 2005-04-16 898 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 @899 static int ntfs_write_mst_block(struct page *page,
^1da177e4c3f41 Linus Torvalds 2005-04-16 900 struct writeback_control *wbc)
^1da177e4c3f41 Linus Torvalds 2005-04-16 901 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 902 sector_t block, dblock, rec_block;
^1da177e4c3f41 Linus Torvalds 2005-04-16 903 struct inode *vi = page->mapping->host;
^1da177e4c3f41 Linus Torvalds 2005-04-16 904 ntfs_inode *ni = NTFS_I(vi);
^1da177e4c3f41 Linus Torvalds 2005-04-16 905 ntfs_volume *vol = ni->vol;
^1da177e4c3f41 Linus Torvalds 2005-04-16 906 u8 *kaddr;
^1da177e4c3f41 Linus Torvalds 2005-04-16 907 unsigned int rec_size = ni->itype.index.block_size;
ac4ecf968acb9e Kees Cook 2018-08-17 908 ntfs_inode *locked_nis[PAGE_SIZE / NTFS_BLOCK_SIZE];
^1da177e4c3f41 Linus Torvalds 2005-04-16 909 struct buffer_head *bh, *head, *tbh, *rec_start_bh;
d53ee3222459f3 Anton Altaparmakov 2005-04-06 910 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
^1da177e4c3f41 Linus Torvalds 2005-04-16 911 runlist_element *rl;
d53ee3222459f3 Anton Altaparmakov 2005-04-06 912 int i, nr_locked_nis, nr_recs, nr_bhs, max_bhs, bhs_per_rec, err, err2;
d53ee3222459f3 Anton Altaparmakov 2005-04-06 913 unsigned bh_size, rec_size_bits;
c49c31115067bc Richard Knutsson 2006-09-30 914 bool sync, is_mft, page_is_dirty, rec_is_dirty;
d53ee3222459f3 Anton Altaparmakov 2005-04-06 915 unsigned char bh_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 916
ac4ecf968acb9e Kees Cook 2018-08-17 917 if (WARN_ON(rec_size < NTFS_BLOCK_SIZE))
ac4ecf968acb9e Kees Cook 2018-08-17 918 return -EINVAL;
ac4ecf968acb9e Kees Cook 2018-08-17 919
^1da177e4c3f41 Linus Torvalds 2005-04-16 920 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
^1da177e4c3f41 Linus Torvalds 2005-04-16 921 "0x%lx.", vi->i_ino, ni->type, page->index);
^1da177e4c3f41 Linus Torvalds 2005-04-16 922 BUG_ON(!NInoNonResident(ni));
^1da177e4c3f41 Linus Torvalds 2005-04-16 923 BUG_ON(!NInoMstProtected(ni));
^1da177e4c3f41 Linus Torvalds 2005-04-16 924 is_mft = (S_ISREG(vi->i_mode) && !vi->i_ino);
^1da177e4c3f41 Linus Torvalds 2005-04-16 925 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 926 * NOTE: ntfs_write_mst_block() would be called for $MFTMirr if a page
^1da177e4c3f41 Linus Torvalds 2005-04-16 927 * in its page cache were to be marked dirty. However this should
^1da177e4c3f41 Linus Torvalds 2005-04-16 928 * never happen with the current driver and considering we do not
^1da177e4c3f41 Linus Torvalds 2005-04-16 929 * handle this case here we do want to BUG(), at least for now.
^1da177e4c3f41 Linus Torvalds 2005-04-16 930 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 931 BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) ||
^1da177e4c3f41 Linus Torvalds 2005-04-16 932 (NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION)));
78af34f03d33d2 Anton Altaparmakov 2006-02-24 933 bh_size = vol->sb->s_blocksize;
78af34f03d33d2 Anton Altaparmakov 2006-02-24 934 bh_size_bits = vol->sb->s_blocksize_bits;
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01 935 max_bhs = PAGE_SIZE / bh_size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 936 BUG_ON(!max_bhs);
d53ee3222459f3 Anton Altaparmakov 2005-04-06 937 BUG_ON(max_bhs > MAX_BUF_PER_PAGE);
^1da177e4c3f41 Linus Torvalds 2005-04-16 938
^1da177e4c3f41 Linus Torvalds 2005-04-16 939 /* Were we called for sync purposes? */
^1da177e4c3f41 Linus Torvalds 2005-04-16 940 sync = (wbc->sync_mode == WB_SYNC_ALL);
^1da177e4c3f41 Linus Torvalds 2005-04-16 941
^1da177e4c3f41 Linus Torvalds 2005-04-16 942 /* Make sure we have mapped buffers. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 943 bh = head = page_buffers(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 944 BUG_ON(!bh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 945
^1da177e4c3f41 Linus Torvalds 2005-04-16 946 rec_size_bits = ni->itype.index.block_size_bits;
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01 947 BUG_ON(!(PAGE_SIZE >> rec_size_bits));
^1da177e4c3f41 Linus Torvalds 2005-04-16 948 bhs_per_rec = rec_size >> bh_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 949 BUG_ON(!bhs_per_rec);
^1da177e4c3f41 Linus Torvalds 2005-04-16 950
^1da177e4c3f41 Linus Torvalds 2005-04-16 951 /* The first block in the page. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 952 rec_block = block = (sector_t)page->index <<
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01 953 (PAGE_SHIFT - bh_size_bits);
^1da177e4c3f41 Linus Torvalds 2005-04-16 954
^1da177e4c3f41 Linus Torvalds 2005-04-16 955 /* The first out of bounds block for the data size. */
07a4e2da7dd3c9 Anton Altaparmakov 2005-01-12 956 dblock = (i_size_read(vi) + bh_size - 1) >> bh_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 957
^1da177e4c3f41 Linus Torvalds 2005-04-16 958 rl = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 959 err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0;
c49c31115067bc Richard Knutsson 2006-09-30 960 page_is_dirty = rec_is_dirty = false;
^1da177e4c3f41 Linus Torvalds 2005-04-16 961 rec_start_bh = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 962 do {
c49c31115067bc Richard Knutsson 2006-09-30 963 bool is_retry = false;
^1da177e4c3f41 Linus Torvalds 2005-04-16 964
^1da177e4c3f41 Linus Torvalds 2005-04-16 965 if (likely(block < rec_block)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 966 if (unlikely(block >= dblock)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 967 clear_buffer_dirty(bh);
946929d813a3bd Anton Altaparmakov 2005-01-13 968 set_buffer_uptodate(bh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 969 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 970 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 971 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 972 * This block is not the first one in the record. We
^1da177e4c3f41 Linus Torvalds 2005-04-16 973 * ignore the buffer's dirty state because we could
^1da177e4c3f41 Linus Torvalds 2005-04-16 974 * have raced with a parallel mark_ntfs_record_dirty().
^1da177e4c3f41 Linus Torvalds 2005-04-16 975 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 976 if (!rec_is_dirty)
^1da177e4c3f41 Linus Torvalds 2005-04-16 977 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 978 if (unlikely(err2)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 979 if (err2 != -ENOMEM)
^1da177e4c3f41 Linus Torvalds 2005-04-16 980 clear_buffer_dirty(bh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 981 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 982 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 983 } else /* if (block == rec_block) */ {
^1da177e4c3f41 Linus Torvalds 2005-04-16 984 BUG_ON(block > rec_block);
^1da177e4c3f41 Linus Torvalds 2005-04-16 985 /* This block is the first one in the record. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 986 rec_block += bhs_per_rec;
^1da177e4c3f41 Linus Torvalds 2005-04-16 987 err2 = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 988 if (unlikely(block >= dblock)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 989 clear_buffer_dirty(bh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 990 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 991 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 992 if (!buffer_dirty(bh)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 993 /* Clean records are not written out. */
c49c31115067bc Richard Knutsson 2006-09-30 994 rec_is_dirty = false;
^1da177e4c3f41 Linus Torvalds 2005-04-16 995 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 996 }
c49c31115067bc Richard Knutsson 2006-09-30 997 rec_is_dirty = true;
^1da177e4c3f41 Linus Torvalds 2005-04-16 998 rec_start_bh = bh;
^1da177e4c3f41 Linus Torvalds 2005-04-16 999 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1000 /* Need to map the buffer if it is not mapped already. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1001 if (unlikely(!buffer_mapped(bh))) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1002 VCN vcn;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1003 LCN lcn;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1004 unsigned int vcn_ofs;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1005
481d0374217f3f Anton Altaparmakov 2005-08-16 1006 bh->b_bdev = vol->sb->s_bdev;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1007 /* Obtain the vcn and offset of the current block. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1008 vcn = (VCN)block << bh_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1009 vcn_ofs = vcn & vol->cluster_size_mask;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1010 vcn >>= vol->cluster_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1011 if (!rl) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1012 lock_retry_remap:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1013 down_read(&ni->runlist.lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1014 rl = ni->runlist.rl;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1015 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1016 if (likely(rl != NULL)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1017 /* Seek to element containing target vcn. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1018 while (rl->length && rl[1].vcn <= vcn)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1019 rl++;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1020 lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1021 } else
^1da177e4c3f41 Linus Torvalds 2005-04-16 1022 lcn = LCN_RL_NOT_MAPPED;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1023 /* Successful remap. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1024 if (likely(lcn >= 0)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1025 /* Setup buffer head to correct block. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1026 bh->b_blocknr = ((lcn <<
^1da177e4c3f41 Linus Torvalds 2005-04-16 1027 vol->cluster_size_bits) +
^1da177e4c3f41 Linus Torvalds 2005-04-16 1028 vcn_ofs) >> bh_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1029 set_buffer_mapped(bh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1030 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1031 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1032 * Remap failed. Retry to map the runlist once
^1da177e4c3f41 Linus Torvalds 2005-04-16 1033 * unless we are working on $MFT which always
^1da177e4c3f41 Linus Torvalds 2005-04-16 1034 * has the whole of its runlist in memory.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1035 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1036 if (!is_mft && !is_retry &&
^1da177e4c3f41 Linus Torvalds 2005-04-16 1037 lcn == LCN_RL_NOT_MAPPED) {
c49c31115067bc Richard Knutsson 2006-09-30 1038 is_retry = true;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1039 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1040 * Attempt to map runlist, dropping
^1da177e4c3f41 Linus Torvalds 2005-04-16 1041 * lock for the duration.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1042 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1043 up_read(&ni->runlist.lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1044 err2 = ntfs_map_runlist(ni, vcn);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1045 if (likely(!err2))
^1da177e4c3f41 Linus Torvalds 2005-04-16 1046 goto lock_retry_remap;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1047 if (err2 == -ENOMEM)
c49c31115067bc Richard Knutsson 2006-09-30 1048 page_is_dirty = true;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1049 lcn = err2;
9f993fe4634b39 Anton Altaparmakov 2005-06-25 1050 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1051 err2 = -EIO;
9f993fe4634b39 Anton Altaparmakov 2005-06-25 1052 if (!rl)
9f993fe4634b39 Anton Altaparmakov 2005-06-25 1053 up_read(&ni->runlist.lock);
9f993fe4634b39 Anton Altaparmakov 2005-06-25 1054 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1055 /* Hard error. Abort writing this record. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1056 if (!err || err == -ENOMEM)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1057 err = err2;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1058 bh->b_blocknr = -1;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1059 ntfs_error(vol->sb, "Cannot write ntfs record "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1060 "0x%llx (inode 0x%lx, "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1061 "attribute type 0x%x) because "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1062 "its location on disk could "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1063 "not be determined (error "
8907547d4b099e Randy Dunlap 2005-03-03 1064 "code %lli).",
8907547d4b099e Randy Dunlap 2005-03-03 1065 (long long)block <<
^1da177e4c3f41 Linus Torvalds 2005-04-16 1066 bh_size_bits >>
^1da177e4c3f41 Linus Torvalds 2005-04-16 1067 vol->mft_record_size_bits,
^1da177e4c3f41 Linus Torvalds 2005-04-16 1068 ni->mft_no, ni->type,
^1da177e4c3f41 Linus Torvalds 2005-04-16 1069 (long long)lcn);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1070 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1071 * If this is not the first buffer, remove the
^1da177e4c3f41 Linus Torvalds 2005-04-16 1072 * buffers in this record from the list of
^1da177e4c3f41 Linus Torvalds 2005-04-16 1073 * buffers to write and clear their dirty bit
^1da177e4c3f41 Linus Torvalds 2005-04-16 1074 * if not error -ENOMEM.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1075 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1076 if (rec_start_bh != bh) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1077 while (bhs[--nr_bhs] != rec_start_bh)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1078 ;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1079 if (err2 != -ENOMEM) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1080 do {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1081 clear_buffer_dirty(
^1da177e4c3f41 Linus Torvalds 2005-04-16 1082 rec_start_bh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1083 } while ((rec_start_bh =
^1da177e4c3f41 Linus Torvalds 2005-04-16 1084 rec_start_bh->
^1da177e4c3f41 Linus Torvalds 2005-04-16 1085 b_this_page) !=
^1da177e4c3f41 Linus Torvalds 2005-04-16 1086 bh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1087 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1088 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1089 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1090 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1091 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1092 BUG_ON(!buffer_uptodate(bh));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1093 BUG_ON(nr_bhs >= max_bhs);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1094 bhs[nr_bhs++] = bh;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1095 } while (block++, (bh = bh->b_this_page) != head);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1096 if (unlikely(rl))
^1da177e4c3f41 Linus Torvalds 2005-04-16 1097 up_read(&ni->runlist.lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1098 /* If there were no dirty buffers, we are done. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1099 if (!nr_bhs)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1100 goto done;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1101 /* Map the page so we can access its contents. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1102 kaddr = kmap(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1103 /* Clear the page uptodate flag whilst the mst fixups are applied. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1104 BUG_ON(!PageUptodate(page));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1105 ClearPageUptodate(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1106 for (i = 0; i < nr_bhs; i++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1107 unsigned int ofs;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1108
^1da177e4c3f41 Linus Torvalds 2005-04-16 1109 /* Skip buffers which are not at the beginning of records. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1110 if (i % bhs_per_rec)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1111 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1112 tbh = bhs[i];
^1da177e4c3f41 Linus Torvalds 2005-04-16 1113 ofs = bh_offset(tbh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1114 if (is_mft) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1115 ntfs_inode *tni;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1116 unsigned long mft_no;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1117
^1da177e4c3f41 Linus Torvalds 2005-04-16 1118 /* Get the mft record number. */
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01 1119 mft_no = (((s64)page->index << PAGE_SHIFT) + ofs)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1120 >> rec_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1121 /* Check whether to write this mft record. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1122 tni = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1123 if (!ntfs_may_write_mft_record(vol, mft_no,
^1da177e4c3f41 Linus Torvalds 2005-04-16 1124 (MFT_RECORD*)(kaddr + ofs), &tni)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1125 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1126 * The record should not be written. This
^1da177e4c3f41 Linus Torvalds 2005-04-16 1127 * means we need to redirty the page before
^1da177e4c3f41 Linus Torvalds 2005-04-16 1128 * returning.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1129 */
c49c31115067bc Richard Knutsson 2006-09-30 1130 page_is_dirty = true;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1131 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1132 * Remove the buffers in this mft record from
^1da177e4c3f41 Linus Torvalds 2005-04-16 1133 * the list of buffers to write.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1134 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1135 do {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1136 bhs[i] = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1137 } while (++i % bhs_per_rec);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1138 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1139 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1140 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1141 * The record should be written. If a locked ntfs
^1da177e4c3f41 Linus Torvalds 2005-04-16 1142 * inode was returned, add it to the array of locked
^1da177e4c3f41 Linus Torvalds 2005-04-16 1143 * ntfs inodes.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1144 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1145 if (tni)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1146 locked_nis[nr_locked_nis++] = tni;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1147 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1148 /* Apply the mst protection fixups. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1149 err2 = pre_write_mst_fixup((NTFS_RECORD*)(kaddr + ofs),
^1da177e4c3f41 Linus Torvalds 2005-04-16 1150 rec_size);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1151 if (unlikely(err2)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1152 if (!err || err == -ENOMEM)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1153 err = -EIO;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1154 ntfs_error(vol->sb, "Failed to apply mst fixups "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1155 "(inode 0x%lx, attribute type 0x%x, "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1156 "page index 0x%lx, page offset 0x%x)!"
^1da177e4c3f41 Linus Torvalds 2005-04-16 1157 " Unmount and run chkdsk.", vi->i_ino,
^1da177e4c3f41 Linus Torvalds 2005-04-16 1158 ni->type, page->index, ofs);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1159 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1160 * Mark all the buffers in this record clean as we do
^1da177e4c3f41 Linus Torvalds 2005-04-16 1161 * not want to write corrupt data to disk.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1162 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1163 do {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1164 clear_buffer_dirty(bhs[i]);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1165 bhs[i] = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1166 } while (++i % bhs_per_rec);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1167 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1168 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1169 nr_recs++;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1170 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1171 /* If no records are to be written out, we are done. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1172 if (!nr_recs)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1173 goto unm_done;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1174 flush_dcache_page(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1175 /* Lock buffers and start synchronous write i/o on them. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1176 for (i = 0; i < nr_bhs; i++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1177 tbh = bhs[i];
^1da177e4c3f41 Linus Torvalds 2005-04-16 1178 if (!tbh)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1179 continue;
ca5de404ff036a Nick Piggin 2008-08-02 1180 if (!trylock_buffer(tbh))
^1da177e4c3f41 Linus Torvalds 2005-04-16 1181 BUG();
^1da177e4c3f41 Linus Torvalds 2005-04-16 1182 /* The buffer dirty state is now irrelevant, just clean it. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1183 clear_buffer_dirty(tbh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1184 BUG_ON(!buffer_uptodate(tbh));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1185 BUG_ON(!buffer_mapped(tbh));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1186 get_bh(tbh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1187 tbh->b_end_io = end_buffer_write_sync;
2a222ca992c35a Mike Christie 2016-06-05 1188 submit_bh(REQ_OP_WRITE, 0, tbh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1189 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1190 /* Synchronize the mft mirror now if not @sync. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1191 if (is_mft && !sync)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1192 goto do_mirror;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1193 do_wait:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1194 /* Wait on i/o completion of buffers. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1195 for (i = 0; i < nr_bhs; i++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1196 tbh = bhs[i];
^1da177e4c3f41 Linus Torvalds 2005-04-16 1197 if (!tbh)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1198 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1199 wait_on_buffer(tbh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1200 if (unlikely(!buffer_uptodate(tbh))) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1201 ntfs_error(vol->sb, "I/O error while writing ntfs "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1202 "record buffer (inode 0x%lx, "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1203 "attribute type 0x%x, page index "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1204 "0x%lx, page offset 0x%lx)! Unmount "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1205 "and run chkdsk.", vi->i_ino, ni->type,
^1da177e4c3f41 Linus Torvalds 2005-04-16 1206 page->index, bh_offset(tbh));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1207 if (!err || err == -ENOMEM)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1208 err = -EIO;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1209 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1210 * Set the buffer uptodate so the page and buffer
^1da177e4c3f41 Linus Torvalds 2005-04-16 1211 * states do not become out of sync.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1212 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1213 set_buffer_uptodate(tbh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1214 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1215 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1216 /* If @sync, now synchronize the mft mirror. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1217 if (is_mft && sync) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1218 do_mirror:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1219 for (i = 0; i < nr_bhs; i++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1220 unsigned long mft_no;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1221 unsigned int ofs;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1222
^1da177e4c3f41 Linus Torvalds 2005-04-16 1223 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1224 * Skip buffers which are not at the beginning of
^1da177e4c3f41 Linus Torvalds 2005-04-16 1225 * records.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1226 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1227 if (i % bhs_per_rec)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1228 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1229 tbh = bhs[i];
^1da177e4c3f41 Linus Torvalds 2005-04-16 1230 /* Skip removed buffers (and hence records). */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1231 if (!tbh)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1232 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1233 ofs = bh_offset(tbh);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1234 /* Get the mft record number. */
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01 1235 mft_no = (((s64)page->index << PAGE_SHIFT) + ofs)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1236 >> rec_size_bits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1237 if (mft_no < vol->mftmirr_size)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1238 ntfs_sync_mft_mirror(vol, mft_no,
^1da177e4c3f41 Linus Torvalds 2005-04-16 1239 (MFT_RECORD*)(kaddr + ofs),
^1da177e4c3f41 Linus Torvalds 2005-04-16 1240 sync);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1241 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1242 if (!sync)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1243 goto do_wait;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1244 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1245 /* Remove the mst protection fixups again. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1246 for (i = 0; i < nr_bhs; i++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1247 if (!(i % bhs_per_rec)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1248 tbh = bhs[i];
^1da177e4c3f41 Linus Torvalds 2005-04-16 1249 if (!tbh)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1250 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1251 post_write_mst_fixup((NTFS_RECORD*)(kaddr +
^1da177e4c3f41 Linus Torvalds 2005-04-16 1252 bh_offset(tbh)));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1253 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1254 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1255 flush_dcache_page(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1256 unm_done:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1257 /* Unlock any locked inodes. */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1258 while (nr_locked_nis-- > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1259 ntfs_inode *tni, *base_tni;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1260
^1da177e4c3f41 Linus Torvalds 2005-04-16 1261 tni = locked_nis[nr_locked_nis];
^1da177e4c3f41 Linus Torvalds 2005-04-16 1262 /* Get the base inode. */
4e5e529ad684f1 Ingo Molnar 2006-03-23 1263 mutex_lock(&tni->extent_lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1264 if (tni->nr_extents >= 0)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1265 base_tni = tni;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1266 else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1267 base_tni = tni->ext.base_ntfs_ino;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1268 BUG_ON(!base_tni);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1269 }
4e5e529ad684f1 Ingo Molnar 2006-03-23 1270 mutex_unlock(&tni->extent_lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1271 ntfs_debug("Unlocking %s inode 0x%lx.",
^1da177e4c3f41 Linus Torvalds 2005-04-16 1272 tni == base_tni ? "base" : "extent",
^1da177e4c3f41 Linus Torvalds 2005-04-16 1273 tni->mft_no);
4e5e529ad684f1 Ingo Molnar 2006-03-23 1274 mutex_unlock(&tni->mrec_lock);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1275 atomic_dec(&tni->count);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1276 iput(VFS_I(base_tni));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1277 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1278 SetPageUptodate(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1279 kunmap(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1280 done:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1281 if (unlikely(err && err != -ENOMEM)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1282 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1283 * Set page error if there is only one ntfs record in the page.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1284 * Otherwise we would loose per-record granularity.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1285 */
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01 1286 if (ni->itype.index.block_size == PAGE_SIZE)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1287 SetPageError(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1288 NVolSetErrors(vol);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1289 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1290 if (page_is_dirty) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1291 ntfs_debug("Page still contains one or more dirty ntfs "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1292 "records. Redirtying the page starting at "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1293 "record 0x%lx.", page->index <<
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01 1294 (PAGE_SHIFT - rec_size_bits));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1295 redirty_page_for_writepage(wbc, page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1296 unlock_page(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1297 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1298 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 1299 * Keep the VM happy. This must be done otherwise the
^1da177e4c3f41 Linus Torvalds 2005-04-16 1300 * radix-tree tag PAGECACHE_TAG_DIRTY remains set even though
^1da177e4c3f41 Linus Torvalds 2005-04-16 1301 * the page is clean.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1302 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1303 BUG_ON(PageWriteback(page));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1304 set_page_writeback(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1305 unlock_page(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1306 end_page_writeback(page);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1307 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1308 if (likely(!err))
^1da177e4c3f41 Linus Torvalds 2005-04-16 1309 ntfs_debug("Done.");
^1da177e4c3f41 Linus Torvalds 2005-04-16 1310 return err;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1311 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1312

:::::: The code at line 899 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@xxxxxxxxxxxxxxx>
:::::: CC: Linus Torvalds <torvalds@xxxxxxxxxxxxxxx>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip