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-only and so it could return
5 an error from btrfs_dirty_inode(). This takes care of the first
6 reason; we'll take care of the second reason in the next commit.
8 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
9 Cc: linux-btrfs@vger.kernel.org
10 Reviewed-by: David Sterba <dsterba@suse.cz>
12 fs/btrfs/inode.c | 14 ++++++++++++++
13 fs/inode.c | 7 +++++++
14 include/linux/fs.h | 1 +
15 3 files changed, 22 insertions(+)
17 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
18 index d23362f..bd46a22 100644
19 --- a/fs/btrfs/inode.c
20 +++ b/fs/btrfs/inode.c
21 @@ -5554,6 +5554,15 @@ static int btrfs_dirty_inode(struct inode *inode)
25 +static int btrfs_is_readonly(struct inode *inode)
27 + struct btrfs_root *root = BTRFS_I(inode)->root;
29 + if (btrfs_root_readonly(root))
35 * This is a copy of file_update_time. We need this so we can return error on
36 * ENOSPC for updating the inode in the case of file write and mmap writes.
37 @@ -9461,6 +9470,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
38 .permission = btrfs_permission,
39 .get_acl = btrfs_get_acl,
40 .set_acl = btrfs_set_acl,
41 + .is_readonly = btrfs_is_readonly,
42 .update_time = btrfs_update_time,
43 .tmpfile = btrfs_tmpfile,
45 @@ -9469,6 +9479,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
46 .permission = btrfs_permission,
47 .get_acl = btrfs_get_acl,
48 .set_acl = btrfs_set_acl,
49 + .is_readonly = btrfs_is_readonly,
50 .update_time = btrfs_update_time,
53 @@ -9539,6 +9550,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
54 .fiemap = btrfs_fiemap,
55 .get_acl = btrfs_get_acl,
56 .set_acl = btrfs_set_acl,
57 + .is_readonly = btrfs_is_readonly,
58 .update_time = btrfs_update_time,
60 static const struct inode_operations btrfs_special_inode_operations = {
61 @@ -9551,6 +9563,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
62 .removexattr = btrfs_removexattr,
63 .get_acl = btrfs_get_acl,
64 .set_acl = btrfs_set_acl,
65 + .is_readonly = btrfs_is_readonly,
66 .update_time = btrfs_update_time,
68 static const struct inode_operations btrfs_symlink_inode_operations = {
69 @@ -9564,6 +9577,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
70 .getxattr = btrfs_getxattr,
71 .listxattr = btrfs_listxattr,
72 .removexattr = btrfs_removexattr,
73 + .is_readonly = btrfs_is_readonly,
74 .update_time = btrfs_update_time,
77 diff --git a/fs/inode.c b/fs/inode.c
78 index 26753ba..53f0173 100644
81 @@ -1499,6 +1499,13 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
83 static int update_time(struct inode *inode, struct timespec *time, int flags)
87 + if (inode->i_op->is_readonly) {
88 + ret = inode->i_op->is_readonly(inode);
92 if (inode->i_op->update_time)
93 return inode->i_op->update_time(inode, time, flags);
95 diff --git a/include/linux/fs.h b/include/linux/fs.h
96 index 9ab779e..f4b0ecd 100644
97 --- a/include/linux/fs.h
98 +++ b/include/linux/fs.h
99 @@ -1544,6 +1544,7 @@ struct inode_operations {
100 int (*removexattr) (struct dentry *, const char *);
101 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
103 + int (*is_readonly)(struct inode *);
104 int (*update_time)(struct inode *, struct timespec *, int);
105 int (*atomic_open)(struct inode *, struct dentry *,
106 struct file *, unsigned open_flag,