diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a7d1921ac76b8ee5d85d563c1ceed80f4a65a2dd..fcc65802f367dd16d066a45d2149761af0aae042 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4518,6 +4518,11 @@ int btrfs_dirty_inode(struct inode *inode) static int btrfs_update_time(struct inode *inode, struct timespec *now, int flags) { + struct btrfs_root *root = BTRFS_I(inode)->root; + + if (btrfs_root_readonly(root)) + return -EROFS; + if (flags & S_VERSION) inode_inc_iversion(inode); if (flags & S_CTIME) diff --git a/fs/inode.c b/fs/inode.c index c99163b1b31036ef68974c0c5dbc192f8f73f4da..033529ecd242b94ca91f1b1818fe51df7b8c4ba8 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1551,6 +1551,8 @@ void touch_atime(struct path *path) * Btrfs), but since we touch atime while walking down the path we * really don't care if we failed to update the atime of the file, * so just ignore the return value. + * We may also fail on filesystems that have the ability to make parts + * of the fs read only, e.g. subvolumes in Btrfs. */ update_time(inode, &now, S_ATIME); mnt_drop_write(mnt);