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