--- linux-4.9.37/fs/fat/inode.c 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/fs/fat/inode.c 2021-06-07 13:01:34.000000000 +0300 @@ -615,8 +615,9 @@ round_up(MSDOS_I(inode)->mmu_private, MSDOS_SB(inode->i_sb)->cluster_size)) { int err; - +#ifndef CONFIG_GOKE_MC fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private); +#endif /* Fallocate results in updating the i_start/iogstart * for the zero byte file. So, make it return to * original state during evict and commit it to avoid @@ -873,15 +874,87 @@ spin_unlock(&sbi->inode_hash_lock); mark_buffer_dirty(bh); err = 0; - if (wait) + if (wait) { err = sync_dirty_buffer(bh); + } brelse(bh); return err; } +#ifdef CONFIG_GOKE_MC +static int __fat_write_inode_(struct inode *inode, int wait) +{ + struct super_block *sb = inode->i_sb; + struct msdos_sb_info *sbi = MSDOS_SB(sb); + struct buffer_head *bh; + struct msdos_dir_entry *raw_entry; + loff_t i_pos; + sector_t blocknr; + int err = 0; + int offset; + + if (inode->i_ino == MSDOS_ROOT_INO) + return 0; + +retry: + i_pos = fat_i_pos_read(sbi, inode); + if (!i_pos) + return 0; + + fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset); + bh = sb_bread(sb, blocknr); + if (!bh) { + fat_msg(sb, KERN_ERR, "unable to read inode block " + "for updating (i_pos %lld)", i_pos); + return -EIO; + } + spin_lock(&sbi->inode_hash_lock); + if (i_pos != MSDOS_I(inode)->i_pos) { + spin_unlock(&sbi->inode_hash_lock); + brelse(bh); + goto retry; + } +#if 0 + dump_stack(); + printk("%s :inode %p/%s, size %llx, logstart %x, blocknr %lx, wait %d\n", + __func__, inode, S_ISDIR(inode->i_mode)? "dir":"file", inode->i_size, + MSDOS_I(inode)->i_logstart, blocknr, wait); +#endif + raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset]; + if (S_ISDIR(inode->i_mode)) + raw_entry->size = 0; + else { + //raw_entry->size = cpu_to_le32(inode->i_size); + if ((0 != raw_entry->start) || (0 != raw_entry->starthi)) { + spin_unlock(&sbi->inode_hash_lock); + goto file_out; + } + raw_entry->size = cpu_to_le32(inode->i_size); + } + raw_entry->attr = fat_make_attrs(inode); + fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart); + fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time, + &raw_entry->date, NULL); + if (sbi->options.isvfat) { + __le16 atime; + fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime, + &raw_entry->cdate, &raw_entry->ctime_cs); + fat_time_unix2fat(sbi, &inode->i_atime, &atime, + &raw_entry->adate, NULL); + } + spin_unlock(&sbi->inode_hash_lock); + mark_buffer_dirty(bh); + if (wait) { + err = sync_dirty_buffer(bh); + } +file_out: + brelse(bh); + return err; +} +#endif static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) { - int err; + int err = 0; if (inode->i_ino == MSDOS_FSINFO_INO) { struct super_block *sb = inode->i_sb; @@ -889,8 +962,18 @@ mutex_lock(&MSDOS_SB(sb)->s_lock); err = fat_clusters_flush(sb); mutex_unlock(&MSDOS_SB(sb)->s_lock); - } else - err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); + } else { +#ifdef CONFIG_GOKE_MC + if (NULL == wbc){ + err = __fat_write_inode(inode, 1); + } + else{ + err = __fat_write_inode_(inode, wbc->sync_mode == WB_SYNC_ALL); + } +#else + err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); +#endif + } return err; }