1 btrfs: add an is_readonly() so btrfs can use common code for update_time()
3 The only reason btrfs cloned code from the VFS layer was so it could
4 add a check to see if a subvolume is read-ony. Instead of doing that,
5 let's add a new inode operation which allows a file system to return
6 an error if the inode is read-only, and use that in update_time().
7 There may be other places where the VFS layer may want to know that
8 btrfs would want to treat an inode is read-only.
10 With this commit, there are no remaining users of update_time() in the
11 inode operations structure, so we can remove it and simply things
14 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
15 Cc: linux-btrfs@vger.kernel.org
16 Reviewed-by: David Sterba <dsterba@suse.cz>
18 fs/btrfs/inode.c | 26 ++++++--------------------
19 fs/inode.c | 22 +++++++++++-----------
20 include/linux/fs.h | 2 +-
21 3 files changed, 18 insertions(+), 32 deletions(-)
23 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
24 index a5e0d0d..0bfe3a4 100644
25 --- a/fs/btrfs/inode.c
26 +++ b/fs/btrfs/inode.c
27 @@ -5554,26 +5554,12 @@ static int btrfs_dirty_inode(struct inode *inode)
32 - * This is a copy of file_update_time. We need this so we can return error on
33 - * ENOSPC for updating the inode in the case of file write and mmap writes.
35 -static int btrfs_update_time(struct inode *inode, struct timespec *now,
37 +static int btrfs_is_readonly(struct inode *inode)
39 struct btrfs_root *root = BTRFS_I(inode)->root;
41 if (btrfs_root_readonly(root))
44 - if (flags & S_VERSION)
45 - inode_inc_iversion(inode);
46 - if (flags & S_CTIME)
47 - inode->i_ctime = *now;
48 - if (flags & S_MTIME)
49 - inode->i_mtime = *now;
50 - if (flags & S_ATIME)
51 - inode->i_atime = *now;
55 @@ -9466,8 +9452,8 @@ static const struct inode_operations btrfs_dir_inode_operations = {
56 .permission = btrfs_permission,
57 .get_acl = btrfs_get_acl,
58 .set_acl = btrfs_set_acl,
59 - .update_time = btrfs_update_time,
60 .write_time = btrfs_write_time,
61 + .is_readonly = btrfs_is_readonly,
62 .tmpfile = btrfs_tmpfile,
64 static const struct inode_operations btrfs_dir_ro_inode_operations = {
65 @@ -9475,8 +9461,8 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
66 .permission = btrfs_permission,
67 .get_acl = btrfs_get_acl,
68 .set_acl = btrfs_set_acl,
69 - .update_time = btrfs_update_time,
70 .write_time = btrfs_write_time,
71 + .is_readonly = btrfs_is_readonly,
74 static const struct file_operations btrfs_dir_file_operations = {
75 @@ -9546,8 +9532,8 @@ static const struct inode_operations btrfs_file_inode_operations = {
76 .fiemap = btrfs_fiemap,
77 .get_acl = btrfs_get_acl,
78 .set_acl = btrfs_set_acl,
79 - .update_time = btrfs_update_time,
80 .write_time = btrfs_write_time,
81 + .is_readonly = btrfs_is_readonly,
83 static const struct inode_operations btrfs_special_inode_operations = {
84 .getattr = btrfs_getattr,
85 @@ -9559,8 +9545,8 @@ static const struct inode_operations btrfs_special_inode_operations = {
86 .removexattr = btrfs_removexattr,
87 .get_acl = btrfs_get_acl,
88 .set_acl = btrfs_set_acl,
89 - .update_time = btrfs_update_time,
90 .write_time = btrfs_write_time,
91 + .is_readonly = btrfs_is_readonly,
93 static const struct inode_operations btrfs_symlink_inode_operations = {
94 .readlink = generic_readlink,
95 @@ -9573,8 +9559,8 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
96 .getxattr = btrfs_getxattr,
97 .listxattr = btrfs_listxattr,
98 .removexattr = btrfs_removexattr,
99 - .update_time = btrfs_update_time,
100 .write_time = btrfs_write_time,
101 + .is_readonly = btrfs_is_readonly,
104 const struct dentry_operations btrfs_dentry_operations = {
105 diff --git a/fs/inode.c b/fs/inode.c
106 index 7b5cd40..425fe4b 100644
109 @@ -1554,20 +1554,20 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
110 unsigned short days_since_boot;
113 - if (inode->i_op->update_time) {
114 - ret = inode->i_op->update_time(inode, time, flags);
115 + if (inode->i_op->is_readonly) {
116 + ret = inode->i_op->is_readonly(inode);
120 - if (flags & S_ATIME)
121 - inode->i_atime = *time;
122 - if (flags & S_VERSION)
123 - inode_inc_iversion(inode);
124 - if (flags & S_CTIME)
125 - inode->i_ctime = *time;
126 - if (flags & S_MTIME)
127 - inode->i_mtime = *time;
129 + if (flags & S_ATIME)
130 + inode->i_atime = *time;
131 + if (flags & S_VERSION)
132 + inode_inc_iversion(inode);
133 + if (flags & S_CTIME)
134 + inode->i_ctime = *time;
135 + if (flags & S_MTIME)
136 + inode->i_mtime = *time;
139 * If i_ts_dirty_day is zero, then either we have not deferred
140 * timestamp updates, or the system has been up for less than
141 diff --git a/include/linux/fs.h b/include/linux/fs.h
142 index dbbd642..70711c8 100644
143 --- a/include/linux/fs.h
144 +++ b/include/linux/fs.h
145 @@ -1545,8 +1545,8 @@ struct inode_operations {
146 int (*removexattr) (struct dentry *, const char *);
147 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
149 - int (*update_time)(struct inode *, struct timespec *, int);
150 int (*write_time)(struct inode *);
151 + int (*is_readonly)(struct inode *);
152 int (*atomic_open)(struct inode *, struct dentry *,
153 struct file *, unsigned open_flag,
154 umode_t create_mode, int *opened);