| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/fs/fat/file.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 24 | 25 | { |
|---|
| 25 | 26 | u32 attr; |
|---|
| 26 | 27 | |
|---|
| 27 | | - inode_lock(inode); |
|---|
| 28 | + inode_lock_shared(inode); |
|---|
| 28 | 29 | attr = fat_make_attrs(inode); |
|---|
| 29 | | - inode_unlock(inode); |
|---|
| 30 | + inode_unlock_shared(inode); |
|---|
| 30 | 31 | |
|---|
| 31 | 32 | return put_user(attr, user_attr); |
|---|
| 32 | 33 | } |
|---|
| .. | .. |
|---|
| 171 | 172 | } |
|---|
| 172 | 173 | } |
|---|
| 173 | 174 | |
|---|
| 174 | | -#ifdef CONFIG_COMPAT |
|---|
| 175 | | -static long fat_generic_compat_ioctl(struct file *filp, unsigned int cmd, |
|---|
| 176 | | - unsigned long arg) |
|---|
| 177 | | - |
|---|
| 178 | | -{ |
|---|
| 179 | | - return fat_generic_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); |
|---|
| 180 | | -} |
|---|
| 181 | | -#endif |
|---|
| 182 | | - |
|---|
| 183 | 175 | static int fat_file_release(struct inode *inode, struct file *filp) |
|---|
| 184 | 176 | { |
|---|
| 185 | 177 | if ((filp->f_mode & FMODE_WRITE) && |
|---|
| .. | .. |
|---|
| 203 | 195 | if (err) |
|---|
| 204 | 196 | return err; |
|---|
| 205 | 197 | |
|---|
| 206 | | - return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); |
|---|
| 198 | + return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL); |
|---|
| 207 | 199 | } |
|---|
| 208 | 200 | |
|---|
| 209 | 201 | |
|---|
| .. | .. |
|---|
| 214 | 206 | .mmap = generic_file_mmap, |
|---|
| 215 | 207 | .release = fat_file_release, |
|---|
| 216 | 208 | .unlocked_ioctl = fat_generic_ioctl, |
|---|
| 217 | | -#ifdef CONFIG_COMPAT |
|---|
| 218 | | - .compat_ioctl = fat_generic_compat_ioctl, |
|---|
| 219 | | -#endif |
|---|
| 209 | + .compat_ioctl = compat_ptr_ioctl, |
|---|
| 220 | 210 | .fsync = fat_file_fsync, |
|---|
| 221 | 211 | .splice_read = generic_file_splice_read, |
|---|
| 212 | + .splice_write = iter_file_splice_write, |
|---|
| 222 | 213 | .fallocate = fat_fallocate, |
|---|
| 223 | 214 | }; |
|---|
| 224 | 215 | |
|---|
| .. | .. |
|---|
| 232 | 223 | if (err) |
|---|
| 233 | 224 | goto out; |
|---|
| 234 | 225 | |
|---|
| 235 | | - inode->i_ctime = inode->i_mtime = current_time(inode); |
|---|
| 226 | + fat_truncate_time(inode, NULL, S_CTIME|S_MTIME); |
|---|
| 236 | 227 | mark_inode_dirty(inode); |
|---|
| 237 | 228 | if (IS_SYNC(inode)) { |
|---|
| 238 | 229 | int err2; |
|---|
| .. | .. |
|---|
| 335 | 326 | MSDOS_I(inode)->i_logstart = 0; |
|---|
| 336 | 327 | } |
|---|
| 337 | 328 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; |
|---|
| 338 | | - inode->i_ctime = inode->i_mtime = current_time(inode); |
|---|
| 329 | + fat_truncate_time(inode, NULL, S_CTIME|S_MTIME); |
|---|
| 339 | 330 | if (wait) { |
|---|
| 340 | 331 | err = fat_sync_inode(inode); |
|---|
| 341 | 332 | if (err) { |
|---|
| .. | .. |
|---|
| 547 | 538 | up_write(&MSDOS_I(inode)->truncate_lock); |
|---|
| 548 | 539 | } |
|---|
| 549 | 540 | |
|---|
| 541 | + /* |
|---|
| 542 | + * setattr_copy can't truncate these appropriately, so we'll |
|---|
| 543 | + * copy them ourselves |
|---|
| 544 | + */ |
|---|
| 545 | + if (attr->ia_valid & ATTR_ATIME) |
|---|
| 546 | + fat_truncate_time(inode, &attr->ia_atime, S_ATIME); |
|---|
| 547 | + if (attr->ia_valid & ATTR_CTIME) |
|---|
| 548 | + fat_truncate_time(inode, &attr->ia_ctime, S_CTIME); |
|---|
| 549 | + if (attr->ia_valid & ATTR_MTIME) |
|---|
| 550 | + fat_truncate_time(inode, &attr->ia_mtime, S_MTIME); |
|---|
| 551 | + attr->ia_valid &= ~(ATTR_ATIME|ATTR_CTIME|ATTR_MTIME); |
|---|
| 552 | + |
|---|
| 550 | 553 | setattr_copy(inode, attr); |
|---|
| 551 | 554 | mark_inode_dirty(inode); |
|---|
| 552 | 555 | out: |
|---|
| .. | .. |
|---|
| 557 | 560 | const struct inode_operations fat_file_inode_operations = { |
|---|
| 558 | 561 | .setattr = fat_setattr, |
|---|
| 559 | 562 | .getattr = fat_getattr, |
|---|
| 563 | + .update_time = fat_update_time, |
|---|
| 560 | 564 | }; |
|---|