.. | .. |
---|
| 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 | }; |
---|