Frank Sorenson <sorenson@xxxxxxxxxx> writes: > +int fat_update_time(struct inode *inode, struct timespec *now, int flags) > +{ > + int iflags = I_DIRTY_TIME; > + struct timespec ts; > + > + if (inode->i_ino == MSDOS_ROOT_INO) { > + ts = (struct timespec){0, 0}; > + if (flags & S_ATIME) > + inode->i_atime = ts; > + if (flags & S_MTIME) > + inode->i_mtime = ts; > + if (flags & S_CTIME) > + inode->i_ctime = ts; Why do we set epoch here? If rootdir is initialized by epoch, we should be able to keep epoch for rootdir. I.e. just ignore (and S_NOATIME | S_CMTIME may be better to skip some)? > + } else { > + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); > + __le16 time; > + __le16 date; > + u8 ctime_cs; > + > + if (now == NULL) { > + now = &ts; > + ts = current_time(inode); > + } > + > + if (flags & S_ATIME) { > + fat_time_unix2fat(sbi, now, &time, &date, NULL); > + fat_time_fat2unix(sbi, &inode->i_atime, 0, date, 0); > + } > + if (flags & S_MTIME) { > + fat_time_unix2fat(sbi, now, &time, &date, NULL); > + fat_time_fat2unix(sbi, &inode->i_mtime, time, date, 0); > + } > + if (flags & S_CTIME) { > + fat_time_unix2fat(sbi, now, &time, &date, > + sbi->options.isvfat ? &ctime_cs : NULL); > + fat_time_fat2unix(sbi, &inode->i_ctime, time, date, > + sbi->options.isvfat ? ctime_cs : 0); > + } Can't we use timespec_trunc() here (have to check limit of timestamp though)? Convert twice is inefficient. > + } > + if ((flags & (S_ATIME | S_CTIME | S_MTIME)) && > + !(inode->i_sb->s_flags & SB_LAZYTIME)) > + iflags |= I_DIRTY_SYNC; > + > + __mark_inode_dirty(inode, iflags); We should make this i_[acm]time update to function, and use everywhere, or such. So we can skip needless mark_inode_dirty() on metadata update. > + return 0; > +} > +EXPORT_SYMBOL_GPL(fat_update_time); Thanks. -- OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>