diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 53 |
1 files changed, 14 insertions, 39 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e9991adc0960..f6ab6f5e635a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4475,46 +4475,18 @@ int btrfs_dirty_inode(struct inode *inode) | |||
4475 | * This is a copy of file_update_time. We need this so we can return error on | 4475 | * This is a copy of file_update_time. We need this so we can return error on |
4476 | * ENOSPC for updating the inode in the case of file write and mmap writes. | 4476 | * ENOSPC for updating the inode in the case of file write and mmap writes. |
4477 | */ | 4477 | */ |
4478 | int btrfs_update_time(struct file *file) | 4478 | static int btrfs_update_time(struct inode *inode, struct timespec *now, |
4479 | int flags) | ||
4479 | { | 4480 | { |
4480 | struct inode *inode = file->f_path.dentry->d_inode; | 4481 | if (flags & S_VERSION) |
4481 | struct timespec now; | ||
4482 | int ret; | ||
4483 | enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0; | ||
4484 | |||
4485 | /* First try to exhaust all avenues to not sync */ | ||
4486 | if (IS_NOCMTIME(inode)) | ||
4487 | return 0; | ||
4488 | |||
4489 | now = current_fs_time(inode->i_sb); | ||
4490 | if (!timespec_equal(&inode->i_mtime, &now)) | ||
4491 | sync_it = S_MTIME; | ||
4492 | |||
4493 | if (!timespec_equal(&inode->i_ctime, &now)) | ||
4494 | sync_it |= S_CTIME; | ||
4495 | |||
4496 | if (IS_I_VERSION(inode)) | ||
4497 | sync_it |= S_VERSION; | ||
4498 | |||
4499 | if (!sync_it) | ||
4500 | return 0; | ||
4501 | |||
4502 | /* Finally allowed to write? Takes lock. */ | ||
4503 | if (mnt_want_write_file(file)) | ||
4504 | return 0; | ||
4505 | |||
4506 | /* Only change inode inside the lock region */ | ||
4507 | if (sync_it & S_VERSION) | ||
4508 | inode_inc_iversion(inode); | 4482 | inode_inc_iversion(inode); |
4509 | if (sync_it & S_CTIME) | 4483 | if (flags & S_CTIME) |
4510 | inode->i_ctime = now; | 4484 | inode->i_ctime = *now; |
4511 | if (sync_it & S_MTIME) | 4485 | if (flags & S_MTIME) |
4512 | inode->i_mtime = now; | 4486 | inode->i_mtime = *now; |
4513 | ret = btrfs_dirty_inode(inode); | 4487 | if (flags & S_ATIME) |
4514 | if (!ret) | 4488 | inode->i_atime = *now; |
4515 | mark_inode_dirty_sync(inode); | 4489 | return btrfs_dirty_inode(inode); |
4516 | mnt_drop_write(file->f_path.mnt); | ||
4517 | return ret; | ||
4518 | } | 4490 | } |
4519 | 4491 | ||
4520 | /* | 4492 | /* |
@@ -6565,7 +6537,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
6565 | 6537 | ||
6566 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | 6538 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
6567 | if (!ret) { | 6539 | if (!ret) { |
6568 | ret = btrfs_update_time(vma->vm_file); | 6540 | ret = file_update_time(vma->vm_file); |
6569 | reserved = 1; | 6541 | reserved = 1; |
6570 | } | 6542 | } |
6571 | if (ret) { | 6543 | if (ret) { |
@@ -7635,6 +7607,7 @@ static const struct inode_operations btrfs_file_inode_operations = { | |||
7635 | .permission = btrfs_permission, | 7607 | .permission = btrfs_permission, |
7636 | .fiemap = btrfs_fiemap, | 7608 | .fiemap = btrfs_fiemap, |
7637 | .get_acl = btrfs_get_acl, | 7609 | .get_acl = btrfs_get_acl, |
7610 | .update_time = btrfs_update_time, | ||
7638 | }; | 7611 | }; |
7639 | static const struct inode_operations btrfs_special_inode_operations = { | 7612 | static const struct inode_operations btrfs_special_inode_operations = { |
7640 | .getattr = btrfs_getattr, | 7613 | .getattr = btrfs_getattr, |
@@ -7645,6 +7618,7 @@ static const struct inode_operations btrfs_special_inode_operations = { | |||
7645 | .listxattr = btrfs_listxattr, | 7618 | .listxattr = btrfs_listxattr, |
7646 | .removexattr = btrfs_removexattr, | 7619 | .removexattr = btrfs_removexattr, |
7647 | .get_acl = btrfs_get_acl, | 7620 | .get_acl = btrfs_get_acl, |
7621 | .update_time = btrfs_update_time, | ||
7648 | }; | 7622 | }; |
7649 | static const struct inode_operations btrfs_symlink_inode_operations = { | 7623 | static const struct inode_operations btrfs_symlink_inode_operations = { |
7650 | .readlink = generic_readlink, | 7624 | .readlink = generic_readlink, |
@@ -7658,6 +7632,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
7658 | .listxattr = btrfs_listxattr, | 7632 | .listxattr = btrfs_listxattr, |
7659 | .removexattr = btrfs_removexattr, | 7633 | .removexattr = btrfs_removexattr, |
7660 | .get_acl = btrfs_get_acl, | 7634 | .get_acl = btrfs_get_acl, |
7635 | .update_time = btrfs_update_time, | ||
7661 | }; | 7636 | }; |
7662 | 7637 | ||
7663 | const struct dentry_operations btrfs_dentry_operations = { | 7638 | const struct dentry_operations btrfs_dentry_operations = { |