diff options
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/file.c | 6 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 80 | ||||
-rw-r--r-- | fs/btrfs/super.c | 13 |
4 files changed, 80 insertions, 22 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 50634abef9b4..67385033323d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2692,7 +2692,8 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); | |||
2692 | int btrfs_readpage(struct file *file, struct page *page); | 2692 | int btrfs_readpage(struct file *file, struct page *page); |
2693 | void btrfs_evict_inode(struct inode *inode); | 2693 | void btrfs_evict_inode(struct inode *inode); |
2694 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); | 2694 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
2695 | void btrfs_dirty_inode(struct inode *inode, int flags); | 2695 | int btrfs_dirty_inode(struct inode *inode); |
2696 | int btrfs_update_time(struct file *file); | ||
2696 | struct inode *btrfs_alloc_inode(struct super_block *sb); | 2697 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
2697 | void btrfs_destroy_inode(struct inode *inode); | 2698 | void btrfs_destroy_inode(struct inode *inode); |
2698 | int btrfs_drop_inode(struct inode *inode); | 2699 | int btrfs_drop_inode(struct inode *inode); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f2e928289600..cc7492c823f3 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1387,7 +1387,11 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1387 | goto out; | 1387 | goto out; |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | file_update_time(file); | 1390 | err = btrfs_update_time(file); |
1391 | if (err) { | ||
1392 | mutex_unlock(&inode->i_mutex); | ||
1393 | goto out; | ||
1394 | } | ||
1391 | BTRFS_I(inode)->sequence++; | 1395 | BTRFS_I(inode)->sequence++; |
1392 | 1396 | ||
1393 | start_pos = round_down(pos, root->sectorsize); | 1397 | start_pos = round_down(pos, root->sectorsize); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c5ccec23984c..eec33b9c953d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/falloc.h> | 38 | #include <linux/falloc.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/ratelimit.h> | 40 | #include <linux/ratelimit.h> |
41 | #include <linux/mount.h> | ||
41 | #include "compat.h" | 42 | #include "compat.h" |
42 | #include "ctree.h" | 43 | #include "ctree.h" |
43 | #include "disk-io.h" | 44 | #include "disk-io.h" |
@@ -3386,7 +3387,7 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize) | |||
3386 | return ret; | 3387 | return ret; |
3387 | } | 3388 | } |
3388 | 3389 | ||
3389 | mark_inode_dirty(inode); | 3390 | ret = btrfs_dirty_inode(inode); |
3390 | } else { | 3391 | } else { |
3391 | 3392 | ||
3392 | /* | 3393 | /* |
@@ -3426,9 +3427,9 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3426 | 3427 | ||
3427 | if (attr->ia_valid) { | 3428 | if (attr->ia_valid) { |
3428 | setattr_copy(inode, attr); | 3429 | setattr_copy(inode, attr); |
3429 | mark_inode_dirty(inode); | 3430 | err = btrfs_dirty_inode(inode); |
3430 | 3431 | ||
3431 | if (attr->ia_valid & ATTR_MODE) | 3432 | if (!err && attr->ia_valid & ATTR_MODE) |
3432 | err = btrfs_acl_chmod(inode); | 3433 | err = btrfs_acl_chmod(inode); |
3433 | } | 3434 | } |
3434 | 3435 | ||
@@ -4204,42 +4205,80 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
4204 | * FIXME, needs more benchmarking...there are no reasons other than performance | 4205 | * FIXME, needs more benchmarking...there are no reasons other than performance |
4205 | * to keep or drop this code. | 4206 | * to keep or drop this code. |
4206 | */ | 4207 | */ |
4207 | void btrfs_dirty_inode(struct inode *inode, int flags) | 4208 | int btrfs_dirty_inode(struct inode *inode) |
4208 | { | 4209 | { |
4209 | struct btrfs_root *root = BTRFS_I(inode)->root; | 4210 | struct btrfs_root *root = BTRFS_I(inode)->root; |
4210 | struct btrfs_trans_handle *trans; | 4211 | struct btrfs_trans_handle *trans; |
4211 | int ret; | 4212 | int ret; |
4212 | 4213 | ||
4213 | if (BTRFS_I(inode)->dummy_inode) | 4214 | if (BTRFS_I(inode)->dummy_inode) |
4214 | return; | 4215 | return 0; |
4215 | 4216 | ||
4216 | trans = btrfs_join_transaction(root); | 4217 | trans = btrfs_join_transaction(root); |
4217 | BUG_ON(IS_ERR(trans)); | 4218 | if (IS_ERR(trans)) |
4219 | return PTR_ERR(trans); | ||
4218 | 4220 | ||
4219 | ret = btrfs_update_inode(trans, root, inode); | 4221 | ret = btrfs_update_inode(trans, root, inode); |
4220 | if (ret && ret == -ENOSPC) { | 4222 | if (ret && ret == -ENOSPC) { |
4221 | /* whoops, lets try again with the full transaction */ | 4223 | /* whoops, lets try again with the full transaction */ |
4222 | btrfs_end_transaction(trans, root); | 4224 | btrfs_end_transaction(trans, root); |
4223 | trans = btrfs_start_transaction(root, 1); | 4225 | trans = btrfs_start_transaction(root, 1); |
4224 | if (IS_ERR(trans)) { | 4226 | if (IS_ERR(trans)) |
4225 | printk_ratelimited(KERN_ERR "btrfs: fail to " | 4227 | return PTR_ERR(trans); |
4226 | "dirty inode %llu error %ld\n", | ||
4227 | (unsigned long long)btrfs_ino(inode), | ||
4228 | PTR_ERR(trans)); | ||
4229 | return; | ||
4230 | } | ||
4231 | 4228 | ||
4232 | ret = btrfs_update_inode(trans, root, inode); | 4229 | ret = btrfs_update_inode(trans, root, inode); |
4233 | if (ret) { | ||
4234 | printk_ratelimited(KERN_ERR "btrfs: fail to " | ||
4235 | "dirty inode %llu error %d\n", | ||
4236 | (unsigned long long)btrfs_ino(inode), | ||
4237 | ret); | ||
4238 | } | ||
4239 | } | 4230 | } |
4240 | btrfs_end_transaction(trans, root); | 4231 | btrfs_end_transaction(trans, root); |
4241 | if (BTRFS_I(inode)->delayed_node) | 4232 | if (BTRFS_I(inode)->delayed_node) |
4242 | btrfs_balance_delayed_items(root); | 4233 | btrfs_balance_delayed_items(root); |
4234 | |||
4235 | return ret; | ||
4236 | } | ||
4237 | |||
4238 | /* | ||
4239 | * This is a copy of file_update_time. We need this so we can return error on | ||
4240 | * ENOSPC for updating the inode in the case of file write and mmap writes. | ||
4241 | */ | ||
4242 | int btrfs_update_time(struct file *file) | ||
4243 | { | ||
4244 | struct inode *inode = file->f_path.dentry->d_inode; | ||
4245 | struct timespec now; | ||
4246 | int ret; | ||
4247 | enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0; | ||
4248 | |||
4249 | /* First try to exhaust all avenues to not sync */ | ||
4250 | if (IS_NOCMTIME(inode)) | ||
4251 | return 0; | ||
4252 | |||
4253 | now = current_fs_time(inode->i_sb); | ||
4254 | if (!timespec_equal(&inode->i_mtime, &now)) | ||
4255 | sync_it = S_MTIME; | ||
4256 | |||
4257 | if (!timespec_equal(&inode->i_ctime, &now)) | ||
4258 | sync_it |= S_CTIME; | ||
4259 | |||
4260 | if (IS_I_VERSION(inode)) | ||
4261 | sync_it |= S_VERSION; | ||
4262 | |||
4263 | if (!sync_it) | ||
4264 | return 0; | ||
4265 | |||
4266 | /* Finally allowed to write? Takes lock. */ | ||
4267 | if (mnt_want_write_file(file)) | ||
4268 | return 0; | ||
4269 | |||
4270 | /* Only change inode inside the lock region */ | ||
4271 | if (sync_it & S_VERSION) | ||
4272 | inode_inc_iversion(inode); | ||
4273 | if (sync_it & S_CTIME) | ||
4274 | inode->i_ctime = now; | ||
4275 | if (sync_it & S_MTIME) | ||
4276 | inode->i_mtime = now; | ||
4277 | ret = btrfs_dirty_inode(inode); | ||
4278 | if (!ret) | ||
4279 | mark_inode_dirty_sync(inode); | ||
4280 | mnt_drop_write(file->f_path.mnt); | ||
4281 | return ret; | ||
4243 | } | 4282 | } |
4244 | 4283 | ||
4245 | /* | 4284 | /* |
@@ -6304,6 +6343,8 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
6304 | u64 page_end; | 6343 | u64 page_end; |
6305 | 6344 | ||
6306 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | 6345 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
6346 | if (!ret) | ||
6347 | ret = btrfs_update_time(vma->vm_file); | ||
6307 | if (ret) { | 6348 | if (ret) { |
6308 | if (ret == -ENOMEM) | 6349 | if (ret == -ENOMEM) |
6309 | ret = VM_FAULT_OOM; | 6350 | ret = VM_FAULT_OOM; |
@@ -7353,6 +7394,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
7353 | .follow_link = page_follow_link_light, | 7394 | .follow_link = page_follow_link_light, |
7354 | .put_link = page_put_link, | 7395 | .put_link = page_put_link, |
7355 | .getattr = btrfs_getattr, | 7396 | .getattr = btrfs_getattr, |
7397 | .setattr = btrfs_setattr, | ||
7356 | .permission = btrfs_permission, | 7398 | .permission = btrfs_permission, |
7357 | .setxattr = btrfs_setxattr, | 7399 | .setxattr = btrfs_setxattr, |
7358 | .getxattr = btrfs_getxattr, | 7400 | .getxattr = btrfs_getxattr, |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 1a3ce9e0b495..05b40457e26c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/cleancache.h> | 42 | #include <linux/cleancache.h> |
43 | #include <linux/mnt_namespace.h> | 43 | #include <linux/mnt_namespace.h> |
44 | #include <linux/ratelimit.h> | ||
44 | #include "compat.h" | 45 | #include "compat.h" |
45 | #include "delayed-inode.h" | 46 | #include "delayed-inode.h" |
46 | #include "ctree.h" | 47 | #include "ctree.h" |
@@ -1290,6 +1291,16 @@ static int btrfs_unfreeze(struct super_block *sb) | |||
1290 | return 0; | 1291 | return 0; |
1291 | } | 1292 | } |
1292 | 1293 | ||
1294 | static void btrfs_fs_dirty_inode(struct inode *inode, int flags) | ||
1295 | { | ||
1296 | int ret; | ||
1297 | |||
1298 | ret = btrfs_dirty_inode(inode); | ||
1299 | if (ret) | ||
1300 | printk_ratelimited(KERN_ERR "btrfs: fail to dirty inode %Lu " | ||
1301 | "error %d\n", btrfs_ino(inode), ret); | ||
1302 | } | ||
1303 | |||
1293 | static const struct super_operations btrfs_super_ops = { | 1304 | static const struct super_operations btrfs_super_ops = { |
1294 | .drop_inode = btrfs_drop_inode, | 1305 | .drop_inode = btrfs_drop_inode, |
1295 | .evict_inode = btrfs_evict_inode, | 1306 | .evict_inode = btrfs_evict_inode, |
@@ -1297,7 +1308,7 @@ static const struct super_operations btrfs_super_ops = { | |||
1297 | .sync_fs = btrfs_sync_fs, | 1308 | .sync_fs = btrfs_sync_fs, |
1298 | .show_options = btrfs_show_options, | 1309 | .show_options = btrfs_show_options, |
1299 | .write_inode = btrfs_write_inode, | 1310 | .write_inode = btrfs_write_inode, |
1300 | .dirty_inode = btrfs_dirty_inode, | 1311 | .dirty_inode = btrfs_fs_dirty_inode, |
1301 | .alloc_inode = btrfs_alloc_inode, | 1312 | .alloc_inode = btrfs_alloc_inode, |
1302 | .destroy_inode = btrfs_destroy_inode, | 1313 | .destroy_inode = btrfs_destroy_inode, |
1303 | .statfs = btrfs_statfs, | 1314 | .statfs = btrfs_statfs, |