diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/fid.c | 15 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 1 | ||||
-rw-r--r-- | fs/9p/vfs_dentry.c | 4 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 2 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 80 | ||||
-rw-r--r-- | fs/binfmt_elf.c | 6 | ||||
-rw-r--r-- | fs/btrfs/acl.c | 9 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 9 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 2 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 125 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 82 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/file.c | 21 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 119 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 165 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/super.c | 42 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 48 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 4 | ||||
-rw-r--r-- | fs/btrfs/xattr.c | 33 | ||||
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/fhandle.c | 1 | ||||
-rw-r--r-- | fs/filesystems.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 1 | ||||
-rw-r--r-- | fs/partitions/ldm.c | 16 | ||||
-rw-r--r-- | fs/proc/base.c | 9 | ||||
-rw-r--r-- | fs/ramfs/file-nommu.c | 1 | ||||
-rw-r--r-- | fs/ubifs/debug.h | 152 | ||||
-rw-r--r-- | fs/ubifs/file.c | 3 |
29 files changed, 618 insertions, 341 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 0ee594569dcc..85b67ffa2a43 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -286,11 +286,9 @@ static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid) | |||
286 | 286 | ||
287 | struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) | 287 | struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) |
288 | { | 288 | { |
289 | int err, flags; | 289 | int err; |
290 | struct p9_fid *fid; | 290 | struct p9_fid *fid; |
291 | struct v9fs_session_info *v9ses; | ||
292 | 291 | ||
293 | v9ses = v9fs_dentry2v9ses(dentry); | ||
294 | fid = v9fs_fid_clone_with_uid(dentry, 0); | 292 | fid = v9fs_fid_clone_with_uid(dentry, 0); |
295 | if (IS_ERR(fid)) | 293 | if (IS_ERR(fid)) |
296 | goto error_out; | 294 | goto error_out; |
@@ -299,17 +297,8 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) | |||
299 | * dirty pages. We always request for the open fid in read-write | 297 | * dirty pages. We always request for the open fid in read-write |
300 | * mode so that a partial page write which result in page | 298 | * mode so that a partial page write which result in page |
301 | * read can work. | 299 | * read can work. |
302 | * | ||
303 | * we don't have a tsyncfs operation for older version | ||
304 | * of protocol. So make sure the write back fid is | ||
305 | * opened in O_SYNC mode. | ||
306 | */ | 300 | */ |
307 | if (!v9fs_proto_dotl(v9ses)) | 301 | err = p9_client_open(fid, O_RDWR); |
308 | flags = O_RDWR | O_SYNC; | ||
309 | else | ||
310 | flags = O_RDWR; | ||
311 | |||
312 | err = p9_client_open(fid, flags); | ||
313 | if (err < 0) { | 302 | if (err < 0) { |
314 | p9_client_clunk(fid); | 303 | p9_client_clunk(fid); |
315 | fid = ERR_PTR(err); | 304 | fid = ERR_PTR(err); |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 9665c2b840e6..e5ebedfc5ed8 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -116,7 +116,6 @@ struct v9fs_session_info { | |||
116 | struct list_head slist; /* list of sessions registered with v9fs */ | 116 | struct list_head slist; /* list of sessions registered with v9fs */ |
117 | struct backing_dev_info bdi; | 117 | struct backing_dev_info bdi; |
118 | struct rw_semaphore rename_sem; | 118 | struct rw_semaphore rename_sem; |
119 | struct p9_fid *root_fid; /* Used for file system sync */ | ||
120 | }; | 119 | }; |
121 | 120 | ||
122 | /* cache_validity flags */ | 121 | /* cache_validity flags */ |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index b6a3b9f7fe4d..e022890c6f40 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -126,7 +126,9 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
126 | retval = v9fs_refresh_inode_dotl(fid, inode); | 126 | retval = v9fs_refresh_inode_dotl(fid, inode); |
127 | else | 127 | else |
128 | retval = v9fs_refresh_inode(fid, inode); | 128 | retval = v9fs_refresh_inode(fid, inode); |
129 | if (retval <= 0) | 129 | if (retval == -ENOENT) |
130 | return 0; | ||
131 | if (retval < 0) | ||
130 | return retval; | 132 | return retval; |
131 | } | 133 | } |
132 | out_valid: | 134 | out_valid: |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index ffbb113d5f33..82a7c38ddad0 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -811,7 +811,7 @@ v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd) | |||
811 | fid = v9fs_fid_lookup(dentry); | 811 | fid = v9fs_fid_lookup(dentry); |
812 | if (IS_ERR(fid)) { | 812 | if (IS_ERR(fid)) { |
813 | __putname(link); | 813 | __putname(link); |
814 | link = ERR_PTR(PTR_ERR(fid)); | 814 | link = ERR_CAST(fid); |
815 | goto ndset; | 815 | goto ndset; |
816 | } | 816 | } |
817 | retval = p9_client_readlink(fid, &target); | 817 | retval = p9_client_readlink(fid, &target); |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index f3eed3383e4f..feef6cdc1fd2 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -154,6 +154,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, | |||
154 | retval = PTR_ERR(inode); | 154 | retval = PTR_ERR(inode); |
155 | goto release_sb; | 155 | goto release_sb; |
156 | } | 156 | } |
157 | |||
157 | root = d_alloc_root(inode); | 158 | root = d_alloc_root(inode); |
158 | if (!root) { | 159 | if (!root) { |
159 | iput(inode); | 160 | iput(inode); |
@@ -185,21 +186,10 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, | |||
185 | p9stat_free(st); | 186 | p9stat_free(st); |
186 | kfree(st); | 187 | kfree(st); |
187 | } | 188 | } |
188 | v9fs_fid_add(root, fid); | ||
189 | retval = v9fs_get_acl(inode, fid); | 189 | retval = v9fs_get_acl(inode, fid); |
190 | if (retval) | 190 | if (retval) |
191 | goto release_sb; | 191 | goto release_sb; |
192 | /* | 192 | v9fs_fid_add(root, fid); |
193 | * Add the root fid to session info. This is used | ||
194 | * for file system sync. We want a cloned fid here | ||
195 | * so that we can do a sync_filesystem after a | ||
196 | * shrink_dcache_for_umount | ||
197 | */ | ||
198 | v9ses->root_fid = v9fs_fid_clone(root); | ||
199 | if (IS_ERR(v9ses->root_fid)) { | ||
200 | retval = PTR_ERR(v9ses->root_fid); | ||
201 | goto release_sb; | ||
202 | } | ||
203 | 193 | ||
204 | P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); | 194 | P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); |
205 | return dget(sb->s_root); | 195 | return dget(sb->s_root); |
@@ -210,11 +200,15 @@ close_session: | |||
210 | v9fs_session_close(v9ses); | 200 | v9fs_session_close(v9ses); |
211 | kfree(v9ses); | 201 | kfree(v9ses); |
212 | return ERR_PTR(retval); | 202 | return ERR_PTR(retval); |
203 | |||
213 | release_sb: | 204 | release_sb: |
214 | /* | 205 | /* |
215 | * we will do the session_close and root dentry | 206 | * we will do the session_close and root dentry release |
216 | * release in the below call. | 207 | * in the below call. But we need to clunk fid, because we haven't |
208 | * attached the fid to dentry so it won't get clunked | ||
209 | * automatically. | ||
217 | */ | 210 | */ |
211 | p9_client_clunk(fid); | ||
218 | deactivate_locked_super(sb); | 212 | deactivate_locked_super(sb); |
219 | return ERR_PTR(retval); | 213 | return ERR_PTR(retval); |
220 | } | 214 | } |
@@ -232,7 +226,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
232 | P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); | 226 | P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); |
233 | 227 | ||
234 | kill_anon_super(s); | 228 | kill_anon_super(s); |
235 | p9_client_clunk(v9ses->root_fid); | 229 | |
236 | v9fs_session_cancel(v9ses); | 230 | v9fs_session_cancel(v9ses); |
237 | v9fs_session_close(v9ses); | 231 | v9fs_session_close(v9ses); |
238 | kfree(v9ses); | 232 | kfree(v9ses); |
@@ -285,14 +279,6 @@ done: | |||
285 | return res; | 279 | return res; |
286 | } | 280 | } |
287 | 281 | ||
288 | static int v9fs_sync_fs(struct super_block *sb, int wait) | ||
289 | { | ||
290 | struct v9fs_session_info *v9ses = sb->s_fs_info; | ||
291 | |||
292 | P9_DPRINTK(P9_DEBUG_VFS, "v9fs_sync_fs: super_block %p\n", sb); | ||
293 | return p9_client_sync_fs(v9ses->root_fid); | ||
294 | } | ||
295 | |||
296 | static int v9fs_drop_inode(struct inode *inode) | 282 | static int v9fs_drop_inode(struct inode *inode) |
297 | { | 283 | { |
298 | struct v9fs_session_info *v9ses; | 284 | struct v9fs_session_info *v9ses; |
@@ -307,6 +293,51 @@ static int v9fs_drop_inode(struct inode *inode) | |||
307 | return 1; | 293 | return 1; |
308 | } | 294 | } |
309 | 295 | ||
296 | static int v9fs_write_inode(struct inode *inode, | ||
297 | struct writeback_control *wbc) | ||
298 | { | ||
299 | int ret; | ||
300 | struct p9_wstat wstat; | ||
301 | struct v9fs_inode *v9inode; | ||
302 | /* | ||
303 | * send an fsync request to server irrespective of | ||
304 | * wbc->sync_mode. | ||
305 | */ | ||
306 | P9_DPRINTK(P9_DEBUG_VFS, "%s: inode %p\n", __func__, inode); | ||
307 | v9inode = V9FS_I(inode); | ||
308 | if (!v9inode->writeback_fid) | ||
309 | return 0; | ||
310 | v9fs_blank_wstat(&wstat); | ||
311 | |||
312 | ret = p9_client_wstat(v9inode->writeback_fid, &wstat); | ||
313 | if (ret < 0) { | ||
314 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | ||
315 | return ret; | ||
316 | } | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int v9fs_write_inode_dotl(struct inode *inode, | ||
321 | struct writeback_control *wbc) | ||
322 | { | ||
323 | int ret; | ||
324 | struct v9fs_inode *v9inode; | ||
325 | /* | ||
326 | * send an fsync request to server irrespective of | ||
327 | * wbc->sync_mode. | ||
328 | */ | ||
329 | P9_DPRINTK(P9_DEBUG_VFS, "%s: inode %p\n", __func__, inode); | ||
330 | v9inode = V9FS_I(inode); | ||
331 | if (!v9inode->writeback_fid) | ||
332 | return 0; | ||
333 | ret = p9_client_fsync(v9inode->writeback_fid, 0); | ||
334 | if (ret < 0) { | ||
335 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | ||
336 | return ret; | ||
337 | } | ||
338 | return 0; | ||
339 | } | ||
340 | |||
310 | static const struct super_operations v9fs_super_ops = { | 341 | static const struct super_operations v9fs_super_ops = { |
311 | .alloc_inode = v9fs_alloc_inode, | 342 | .alloc_inode = v9fs_alloc_inode, |
312 | .destroy_inode = v9fs_destroy_inode, | 343 | .destroy_inode = v9fs_destroy_inode, |
@@ -314,17 +345,18 @@ static const struct super_operations v9fs_super_ops = { | |||
314 | .evict_inode = v9fs_evict_inode, | 345 | .evict_inode = v9fs_evict_inode, |
315 | .show_options = generic_show_options, | 346 | .show_options = generic_show_options, |
316 | .umount_begin = v9fs_umount_begin, | 347 | .umount_begin = v9fs_umount_begin, |
348 | .write_inode = v9fs_write_inode, | ||
317 | }; | 349 | }; |
318 | 350 | ||
319 | static const struct super_operations v9fs_super_ops_dotl = { | 351 | static const struct super_operations v9fs_super_ops_dotl = { |
320 | .alloc_inode = v9fs_alloc_inode, | 352 | .alloc_inode = v9fs_alloc_inode, |
321 | .destroy_inode = v9fs_destroy_inode, | 353 | .destroy_inode = v9fs_destroy_inode, |
322 | .sync_fs = v9fs_sync_fs, | ||
323 | .statfs = v9fs_statfs, | 354 | .statfs = v9fs_statfs, |
324 | .drop_inode = v9fs_drop_inode, | 355 | .drop_inode = v9fs_drop_inode, |
325 | .evict_inode = v9fs_evict_inode, | 356 | .evict_inode = v9fs_evict_inode, |
326 | .show_options = generic_show_options, | 357 | .show_options = generic_show_options, |
327 | .umount_begin = v9fs_umount_begin, | 358 | .umount_begin = v9fs_umount_begin, |
359 | .write_inode = v9fs_write_inode_dotl, | ||
328 | }; | 360 | }; |
329 | 361 | ||
330 | struct file_system_type v9fs_fs_type = { | 362 | struct file_system_type v9fs_fs_type = { |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index f34078d702d3..303983fabfd6 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -941,9 +941,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
941 | current->mm->start_stack = bprm->p; | 941 | current->mm->start_stack = bprm->p; |
942 | 942 | ||
943 | #ifdef arch_randomize_brk | 943 | #ifdef arch_randomize_brk |
944 | if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) | 944 | if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { |
945 | current->mm->brk = current->mm->start_brk = | 945 | current->mm->brk = current->mm->start_brk = |
946 | arch_randomize_brk(current->mm); | 946 | arch_randomize_brk(current->mm); |
947 | #ifdef CONFIG_COMPAT_BRK | ||
948 | current->brk_randomized = 1; | ||
949 | #endif | ||
950 | } | ||
947 | #endif | 951 | #endif |
948 | 952 | ||
949 | if (current->personality & MMAP_PAGE_ZERO) { | 953 | if (current->personality & MMAP_PAGE_ZERO) { |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index de34bfad9ec3..5d505aaa72fb 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -178,16 +178,17 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, | |||
178 | 178 | ||
179 | if (value) { | 179 | if (value) { |
180 | acl = posix_acl_from_xattr(value, size); | 180 | acl = posix_acl_from_xattr(value, size); |
181 | if (acl == NULL) { | 181 | if (acl) { |
182 | value = NULL; | 182 | ret = posix_acl_valid(acl); |
183 | size = 0; | 183 | if (ret) |
184 | goto out; | ||
184 | } else if (IS_ERR(acl)) { | 185 | } else if (IS_ERR(acl)) { |
185 | return PTR_ERR(acl); | 186 | return PTR_ERR(acl); |
186 | } | 187 | } |
187 | } | 188 | } |
188 | 189 | ||
189 | ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); | 190 | ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); |
190 | 191 | out: | |
191 | posix_acl_release(acl); | 192 | posix_acl_release(acl); |
192 | 193 | ||
193 | return ret; | 194 | return ret; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3458b5725540..2e61fe1b6b8c 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -740,8 +740,10 @@ struct btrfs_space_info { | |||
740 | */ | 740 | */ |
741 | unsigned long reservation_progress; | 741 | unsigned long reservation_progress; |
742 | 742 | ||
743 | int full; /* indicates that we cannot allocate any more | 743 | int full:1; /* indicates that we cannot allocate any more |
744 | chunks for this space */ | 744 | chunks for this space */ |
745 | int chunk_alloc:1; /* set if we are allocating a chunk */ | ||
746 | |||
745 | int force_alloc; /* set if we need to force a chunk alloc for | 747 | int force_alloc; /* set if we need to force a chunk alloc for |
746 | this space */ | 748 | this space */ |
747 | 749 | ||
@@ -2576,6 +2578,11 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, | |||
2576 | int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, | 2578 | int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, |
2577 | struct inode *inode, u64 start, u64 end); | 2579 | struct inode *inode, u64 start, u64 end); |
2578 | int btrfs_release_file(struct inode *inode, struct file *file); | 2580 | int btrfs_release_file(struct inode *inode, struct file *file); |
2581 | void btrfs_drop_pages(struct page **pages, size_t num_pages); | ||
2582 | int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, | ||
2583 | struct page **pages, size_t num_pages, | ||
2584 | loff_t pos, size_t write_bytes, | ||
2585 | struct extent_state **cached); | ||
2579 | 2586 | ||
2580 | /* tree-defrag.c */ | 2587 | /* tree-defrag.c */ |
2581 | int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | 2588 | int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8f1d44ba332f..68c84c8c24bd 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -3057,7 +3057,7 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
3057 | btrfs_destroy_pinned_extent(root, | 3057 | btrfs_destroy_pinned_extent(root, |
3058 | root->fs_info->pinned_extents); | 3058 | root->fs_info->pinned_extents); |
3059 | 3059 | ||
3060 | t->use_count = 0; | 3060 | atomic_set(&t->use_count, 0); |
3061 | list_del_init(&t->list); | 3061 | list_del_init(&t->list); |
3062 | memset(t, 0, sizeof(*t)); | 3062 | memset(t, 0, sizeof(*t)); |
3063 | kmem_cache_free(btrfs_transaction_cachep, t); | 3063 | kmem_cache_free(btrfs_transaction_cachep, t); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f619c3cb13b7..31f33ba56fe8 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -33,6 +33,25 @@ | |||
33 | #include "locking.h" | 33 | #include "locking.h" |
34 | #include "free-space-cache.h" | 34 | #include "free-space-cache.h" |
35 | 35 | ||
36 | /* control flags for do_chunk_alloc's force field | ||
37 | * CHUNK_ALLOC_NO_FORCE means to only allocate a chunk | ||
38 | * if we really need one. | ||
39 | * | ||
40 | * CHUNK_ALLOC_FORCE means it must try to allocate one | ||
41 | * | ||
42 | * CHUNK_ALLOC_LIMITED means to only try and allocate one | ||
43 | * if we have very few chunks already allocated. This is | ||
44 | * used as part of the clustering code to help make sure | ||
45 | * we have a good pool of storage to cluster in, without | ||
46 | * filling the FS with empty chunks | ||
47 | * | ||
48 | */ | ||
49 | enum { | ||
50 | CHUNK_ALLOC_NO_FORCE = 0, | ||
51 | CHUNK_ALLOC_FORCE = 1, | ||
52 | CHUNK_ALLOC_LIMITED = 2, | ||
53 | }; | ||
54 | |||
36 | static int update_block_group(struct btrfs_trans_handle *trans, | 55 | static int update_block_group(struct btrfs_trans_handle *trans, |
37 | struct btrfs_root *root, | 56 | struct btrfs_root *root, |
38 | u64 bytenr, u64 num_bytes, int alloc); | 57 | u64 bytenr, u64 num_bytes, int alloc); |
@@ -3019,7 +3038,8 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
3019 | found->bytes_readonly = 0; | 3038 | found->bytes_readonly = 0; |
3020 | found->bytes_may_use = 0; | 3039 | found->bytes_may_use = 0; |
3021 | found->full = 0; | 3040 | found->full = 0; |
3022 | found->force_alloc = 0; | 3041 | found->force_alloc = CHUNK_ALLOC_NO_FORCE; |
3042 | found->chunk_alloc = 0; | ||
3023 | *space_info = found; | 3043 | *space_info = found; |
3024 | list_add_rcu(&found->list, &info->space_info); | 3044 | list_add_rcu(&found->list, &info->space_info); |
3025 | atomic_set(&found->caching_threads, 0); | 3045 | atomic_set(&found->caching_threads, 0); |
@@ -3150,7 +3170,7 @@ again: | |||
3150 | if (!data_sinfo->full && alloc_chunk) { | 3170 | if (!data_sinfo->full && alloc_chunk) { |
3151 | u64 alloc_target; | 3171 | u64 alloc_target; |
3152 | 3172 | ||
3153 | data_sinfo->force_alloc = 1; | 3173 | data_sinfo->force_alloc = CHUNK_ALLOC_FORCE; |
3154 | spin_unlock(&data_sinfo->lock); | 3174 | spin_unlock(&data_sinfo->lock); |
3155 | alloc: | 3175 | alloc: |
3156 | alloc_target = btrfs_get_alloc_profile(root, 1); | 3176 | alloc_target = btrfs_get_alloc_profile(root, 1); |
@@ -3160,7 +3180,8 @@ alloc: | |||
3160 | 3180 | ||
3161 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 3181 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
3162 | bytes + 2 * 1024 * 1024, | 3182 | bytes + 2 * 1024 * 1024, |
3163 | alloc_target, 0); | 3183 | alloc_target, |
3184 | CHUNK_ALLOC_NO_FORCE); | ||
3164 | btrfs_end_transaction(trans, root); | 3185 | btrfs_end_transaction(trans, root); |
3165 | if (ret < 0) { | 3186 | if (ret < 0) { |
3166 | if (ret != -ENOSPC) | 3187 | if (ret != -ENOSPC) |
@@ -3239,31 +3260,56 @@ static void force_metadata_allocation(struct btrfs_fs_info *info) | |||
3239 | rcu_read_lock(); | 3260 | rcu_read_lock(); |
3240 | list_for_each_entry_rcu(found, head, list) { | 3261 | list_for_each_entry_rcu(found, head, list) { |
3241 | if (found->flags & BTRFS_BLOCK_GROUP_METADATA) | 3262 | if (found->flags & BTRFS_BLOCK_GROUP_METADATA) |
3242 | found->force_alloc = 1; | 3263 | found->force_alloc = CHUNK_ALLOC_FORCE; |
3243 | } | 3264 | } |
3244 | rcu_read_unlock(); | 3265 | rcu_read_unlock(); |
3245 | } | 3266 | } |
3246 | 3267 | ||
3247 | static int should_alloc_chunk(struct btrfs_root *root, | 3268 | static int should_alloc_chunk(struct btrfs_root *root, |
3248 | struct btrfs_space_info *sinfo, u64 alloc_bytes) | 3269 | struct btrfs_space_info *sinfo, u64 alloc_bytes, |
3270 | int force) | ||
3249 | { | 3271 | { |
3250 | u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; | 3272 | u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; |
3273 | u64 num_allocated = sinfo->bytes_used + sinfo->bytes_reserved; | ||
3251 | u64 thresh; | 3274 | u64 thresh; |
3252 | 3275 | ||
3253 | if (sinfo->bytes_used + sinfo->bytes_reserved + | 3276 | if (force == CHUNK_ALLOC_FORCE) |
3254 | alloc_bytes + 256 * 1024 * 1024 < num_bytes) | 3277 | return 1; |
3278 | |||
3279 | /* | ||
3280 | * in limited mode, we want to have some free space up to | ||
3281 | * about 1% of the FS size. | ||
3282 | */ | ||
3283 | if (force == CHUNK_ALLOC_LIMITED) { | ||
3284 | thresh = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
3285 | thresh = max_t(u64, 64 * 1024 * 1024, | ||
3286 | div_factor_fine(thresh, 1)); | ||
3287 | |||
3288 | if (num_bytes - num_allocated < thresh) | ||
3289 | return 1; | ||
3290 | } | ||
3291 | |||
3292 | /* | ||
3293 | * we have two similar checks here, one based on percentage | ||
3294 | * and once based on a hard number of 256MB. The idea | ||
3295 | * is that if we have a good amount of free | ||
3296 | * room, don't allocate a chunk. A good mount is | ||
3297 | * less than 80% utilized of the chunks we have allocated, | ||
3298 | * or more than 256MB free | ||
3299 | */ | ||
3300 | if (num_allocated + alloc_bytes + 256 * 1024 * 1024 < num_bytes) | ||
3255 | return 0; | 3301 | return 0; |
3256 | 3302 | ||
3257 | if (sinfo->bytes_used + sinfo->bytes_reserved + | 3303 | if (num_allocated + alloc_bytes < div_factor(num_bytes, 8)) |
3258 | alloc_bytes < div_factor(num_bytes, 8)) | ||
3259 | return 0; | 3304 | return 0; |
3260 | 3305 | ||
3261 | thresh = btrfs_super_total_bytes(&root->fs_info->super_copy); | 3306 | thresh = btrfs_super_total_bytes(&root->fs_info->super_copy); |
3307 | |||
3308 | /* 256MB or 5% of the FS */ | ||
3262 | thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5)); | 3309 | thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5)); |
3263 | 3310 | ||
3264 | if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 3)) | 3311 | if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 3)) |
3265 | return 0; | 3312 | return 0; |
3266 | |||
3267 | return 1; | 3313 | return 1; |
3268 | } | 3314 | } |
3269 | 3315 | ||
@@ -3273,10 +3319,9 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
3273 | { | 3319 | { |
3274 | struct btrfs_space_info *space_info; | 3320 | struct btrfs_space_info *space_info; |
3275 | struct btrfs_fs_info *fs_info = extent_root->fs_info; | 3321 | struct btrfs_fs_info *fs_info = extent_root->fs_info; |
3322 | int wait_for_alloc = 0; | ||
3276 | int ret = 0; | 3323 | int ret = 0; |
3277 | 3324 | ||
3278 | mutex_lock(&fs_info->chunk_mutex); | ||
3279 | |||
3280 | flags = btrfs_reduce_alloc_profile(extent_root, flags); | 3325 | flags = btrfs_reduce_alloc_profile(extent_root, flags); |
3281 | 3326 | ||
3282 | space_info = __find_space_info(extent_root->fs_info, flags); | 3327 | space_info = __find_space_info(extent_root->fs_info, flags); |
@@ -3287,21 +3332,40 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
3287 | } | 3332 | } |
3288 | BUG_ON(!space_info); | 3333 | BUG_ON(!space_info); |
3289 | 3334 | ||
3335 | again: | ||
3290 | spin_lock(&space_info->lock); | 3336 | spin_lock(&space_info->lock); |
3291 | if (space_info->force_alloc) | 3337 | if (space_info->force_alloc) |
3292 | force = 1; | 3338 | force = space_info->force_alloc; |
3293 | if (space_info->full) { | 3339 | if (space_info->full) { |
3294 | spin_unlock(&space_info->lock); | 3340 | spin_unlock(&space_info->lock); |
3295 | goto out; | 3341 | return 0; |
3296 | } | 3342 | } |
3297 | 3343 | ||
3298 | if (!force && !should_alloc_chunk(extent_root, space_info, | 3344 | if (!should_alloc_chunk(extent_root, space_info, alloc_bytes, force)) { |
3299 | alloc_bytes)) { | ||
3300 | spin_unlock(&space_info->lock); | 3345 | spin_unlock(&space_info->lock); |
3301 | goto out; | 3346 | return 0; |
3347 | } else if (space_info->chunk_alloc) { | ||
3348 | wait_for_alloc = 1; | ||
3349 | } else { | ||
3350 | space_info->chunk_alloc = 1; | ||
3302 | } | 3351 | } |
3352 | |||
3303 | spin_unlock(&space_info->lock); | 3353 | spin_unlock(&space_info->lock); |
3304 | 3354 | ||
3355 | mutex_lock(&fs_info->chunk_mutex); | ||
3356 | |||
3357 | /* | ||
3358 | * The chunk_mutex is held throughout the entirety of a chunk | ||
3359 | * allocation, so once we've acquired the chunk_mutex we know that the | ||
3360 | * other guy is done and we need to recheck and see if we should | ||
3361 | * allocate. | ||
3362 | */ | ||
3363 | if (wait_for_alloc) { | ||
3364 | mutex_unlock(&fs_info->chunk_mutex); | ||
3365 | wait_for_alloc = 0; | ||
3366 | goto again; | ||
3367 | } | ||
3368 | |||
3305 | /* | 3369 | /* |
3306 | * If we have mixed data/metadata chunks we want to make sure we keep | 3370 | * If we have mixed data/metadata chunks we want to make sure we keep |
3307 | * allocating mixed chunks instead of individual chunks. | 3371 | * allocating mixed chunks instead of individual chunks. |
@@ -3327,9 +3391,10 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
3327 | space_info->full = 1; | 3391 | space_info->full = 1; |
3328 | else | 3392 | else |
3329 | ret = 1; | 3393 | ret = 1; |
3330 | space_info->force_alloc = 0; | 3394 | |
3395 | space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; | ||
3396 | space_info->chunk_alloc = 0; | ||
3331 | spin_unlock(&space_info->lock); | 3397 | spin_unlock(&space_info->lock); |
3332 | out: | ||
3333 | mutex_unlock(&extent_root->fs_info->chunk_mutex); | 3398 | mutex_unlock(&extent_root->fs_info->chunk_mutex); |
3334 | return ret; | 3399 | return ret; |
3335 | } | 3400 | } |
@@ -5303,11 +5368,13 @@ loop: | |||
5303 | 5368 | ||
5304 | if (allowed_chunk_alloc) { | 5369 | if (allowed_chunk_alloc) { |
5305 | ret = do_chunk_alloc(trans, root, num_bytes + | 5370 | ret = do_chunk_alloc(trans, root, num_bytes + |
5306 | 2 * 1024 * 1024, data, 1); | 5371 | 2 * 1024 * 1024, data, |
5372 | CHUNK_ALLOC_LIMITED); | ||
5307 | allowed_chunk_alloc = 0; | 5373 | allowed_chunk_alloc = 0; |
5308 | done_chunk_alloc = 1; | 5374 | done_chunk_alloc = 1; |
5309 | } else if (!done_chunk_alloc) { | 5375 | } else if (!done_chunk_alloc && |
5310 | space_info->force_alloc = 1; | 5376 | space_info->force_alloc == CHUNK_ALLOC_NO_FORCE) { |
5377 | space_info->force_alloc = CHUNK_ALLOC_LIMITED; | ||
5311 | } | 5378 | } |
5312 | 5379 | ||
5313 | if (loop < LOOP_NO_EMPTY_SIZE) { | 5380 | if (loop < LOOP_NO_EMPTY_SIZE) { |
@@ -5393,7 +5460,8 @@ again: | |||
5393 | */ | 5460 | */ |
5394 | if (empty_size || root->ref_cows) | 5461 | if (empty_size || root->ref_cows) |
5395 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 5462 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
5396 | num_bytes + 2 * 1024 * 1024, data, 0); | 5463 | num_bytes + 2 * 1024 * 1024, data, |
5464 | CHUNK_ALLOC_NO_FORCE); | ||
5397 | 5465 | ||
5398 | WARN_ON(num_bytes < root->sectorsize); | 5466 | WARN_ON(num_bytes < root->sectorsize); |
5399 | ret = find_free_extent(trans, root, num_bytes, empty_size, | 5467 | ret = find_free_extent(trans, root, num_bytes, empty_size, |
@@ -5405,7 +5473,7 @@ again: | |||
5405 | num_bytes = num_bytes & ~(root->sectorsize - 1); | 5473 | num_bytes = num_bytes & ~(root->sectorsize - 1); |
5406 | num_bytes = max(num_bytes, min_alloc_size); | 5474 | num_bytes = max(num_bytes, min_alloc_size); |
5407 | do_chunk_alloc(trans, root->fs_info->extent_root, | 5475 | do_chunk_alloc(trans, root->fs_info->extent_root, |
5408 | num_bytes, data, 1); | 5476 | num_bytes, data, CHUNK_ALLOC_FORCE); |
5409 | goto again; | 5477 | goto again; |
5410 | } | 5478 | } |
5411 | if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { | 5479 | if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { |
@@ -8109,13 +8177,15 @@ int btrfs_set_block_group_ro(struct btrfs_root *root, | |||
8109 | 8177 | ||
8110 | alloc_flags = update_block_group_flags(root, cache->flags); | 8178 | alloc_flags = update_block_group_flags(root, cache->flags); |
8111 | if (alloc_flags != cache->flags) | 8179 | if (alloc_flags != cache->flags) |
8112 | do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, 1); | 8180 | do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, |
8181 | CHUNK_ALLOC_FORCE); | ||
8113 | 8182 | ||
8114 | ret = set_block_group_ro(cache); | 8183 | ret = set_block_group_ro(cache); |
8115 | if (!ret) | 8184 | if (!ret) |
8116 | goto out; | 8185 | goto out; |
8117 | alloc_flags = get_alloc_profile(root, cache->space_info->flags); | 8186 | alloc_flags = get_alloc_profile(root, cache->space_info->flags); |
8118 | ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, 1); | 8187 | ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, |
8188 | CHUNK_ALLOC_FORCE); | ||
8119 | if (ret < 0) | 8189 | if (ret < 0) |
8120 | goto out; | 8190 | goto out; |
8121 | ret = set_block_group_ro(cache); | 8191 | ret = set_block_group_ro(cache); |
@@ -8128,7 +8198,8 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, | |||
8128 | struct btrfs_root *root, u64 type) | 8198 | struct btrfs_root *root, u64 type) |
8129 | { | 8199 | { |
8130 | u64 alloc_flags = get_alloc_profile(root, type); | 8200 | u64 alloc_flags = get_alloc_profile(root, type); |
8131 | return do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, 1); | 8201 | return do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, |
8202 | CHUNK_ALLOC_FORCE); | ||
8132 | } | 8203 | } |
8133 | 8204 | ||
8134 | /* | 8205 | /* |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 20ddb28602a8..315138605088 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -690,6 +690,15 @@ static void cache_state(struct extent_state *state, | |||
690 | } | 690 | } |
691 | } | 691 | } |
692 | 692 | ||
693 | static void uncache_state(struct extent_state **cached_ptr) | ||
694 | { | ||
695 | if (cached_ptr && (*cached_ptr)) { | ||
696 | struct extent_state *state = *cached_ptr; | ||
697 | *cached_ptr = NULL; | ||
698 | free_extent_state(state); | ||
699 | } | ||
700 | } | ||
701 | |||
693 | /* | 702 | /* |
694 | * set some bits on a range in the tree. This may require allocations or | 703 | * set some bits on a range in the tree. This may require allocations or |
695 | * sleeping, so the gfp mask is used to indicate what is allowed. | 704 | * sleeping, so the gfp mask is used to indicate what is allowed. |
@@ -940,10 +949,10 @@ static int clear_extent_new(struct extent_io_tree *tree, u64 start, u64 end, | |||
940 | } | 949 | } |
941 | 950 | ||
942 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, | 951 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, |
943 | gfp_t mask) | 952 | struct extent_state **cached_state, gfp_t mask) |
944 | { | 953 | { |
945 | return set_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, NULL, | 954 | return set_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, |
946 | NULL, mask); | 955 | NULL, cached_state, mask); |
947 | } | 956 | } |
948 | 957 | ||
949 | static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, | 958 | static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, |
@@ -1012,8 +1021,7 @@ int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, | |||
1012 | mask); | 1021 | mask); |
1013 | } | 1022 | } |
1014 | 1023 | ||
1015 | int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, | 1024 | int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) |
1016 | gfp_t mask) | ||
1017 | { | 1025 | { |
1018 | return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL, | 1026 | return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL, |
1019 | mask); | 1027 | mask); |
@@ -1735,6 +1743,9 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
1735 | 1743 | ||
1736 | do { | 1744 | do { |
1737 | struct page *page = bvec->bv_page; | 1745 | struct page *page = bvec->bv_page; |
1746 | struct extent_state *cached = NULL; | ||
1747 | struct extent_state *state; | ||
1748 | |||
1738 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 1749 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
1739 | 1750 | ||
1740 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + | 1751 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + |
@@ -1749,9 +1760,20 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
1749 | if (++bvec <= bvec_end) | 1760 | if (++bvec <= bvec_end) |
1750 | prefetchw(&bvec->bv_page->flags); | 1761 | prefetchw(&bvec->bv_page->flags); |
1751 | 1762 | ||
1763 | spin_lock(&tree->lock); | ||
1764 | state = find_first_extent_bit_state(tree, start, EXTENT_LOCKED); | ||
1765 | if (state && state->start == start) { | ||
1766 | /* | ||
1767 | * take a reference on the state, unlock will drop | ||
1768 | * the ref | ||
1769 | */ | ||
1770 | cache_state(state, &cached); | ||
1771 | } | ||
1772 | spin_unlock(&tree->lock); | ||
1773 | |||
1752 | if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { | 1774 | if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { |
1753 | ret = tree->ops->readpage_end_io_hook(page, start, end, | 1775 | ret = tree->ops->readpage_end_io_hook(page, start, end, |
1754 | NULL); | 1776 | state); |
1755 | if (ret) | 1777 | if (ret) |
1756 | uptodate = 0; | 1778 | uptodate = 0; |
1757 | } | 1779 | } |
@@ -1764,15 +1786,16 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
1764 | test_bit(BIO_UPTODATE, &bio->bi_flags); | 1786 | test_bit(BIO_UPTODATE, &bio->bi_flags); |
1765 | if (err) | 1787 | if (err) |
1766 | uptodate = 0; | 1788 | uptodate = 0; |
1789 | uncache_state(&cached); | ||
1767 | continue; | 1790 | continue; |
1768 | } | 1791 | } |
1769 | } | 1792 | } |
1770 | 1793 | ||
1771 | if (uptodate) { | 1794 | if (uptodate) { |
1772 | set_extent_uptodate(tree, start, end, | 1795 | set_extent_uptodate(tree, start, end, &cached, |
1773 | GFP_ATOMIC); | 1796 | GFP_ATOMIC); |
1774 | } | 1797 | } |
1775 | unlock_extent(tree, start, end, GFP_ATOMIC); | 1798 | unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC); |
1776 | 1799 | ||
1777 | if (whole_page) { | 1800 | if (whole_page) { |
1778 | if (uptodate) { | 1801 | if (uptodate) { |
@@ -1811,6 +1834,7 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err) | |||
1811 | 1834 | ||
1812 | do { | 1835 | do { |
1813 | struct page *page = bvec->bv_page; | 1836 | struct page *page = bvec->bv_page; |
1837 | struct extent_state *cached = NULL; | ||
1814 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 1838 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
1815 | 1839 | ||
1816 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + | 1840 | start = ((u64)page->index << PAGE_CACHE_SHIFT) + |
@@ -1821,13 +1845,14 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err) | |||
1821 | prefetchw(&bvec->bv_page->flags); | 1845 | prefetchw(&bvec->bv_page->flags); |
1822 | 1846 | ||
1823 | if (uptodate) { | 1847 | if (uptodate) { |
1824 | set_extent_uptodate(tree, start, end, GFP_ATOMIC); | 1848 | set_extent_uptodate(tree, start, end, &cached, |
1849 | GFP_ATOMIC); | ||
1825 | } else { | 1850 | } else { |
1826 | ClearPageUptodate(page); | 1851 | ClearPageUptodate(page); |
1827 | SetPageError(page); | 1852 | SetPageError(page); |
1828 | } | 1853 | } |
1829 | 1854 | ||
1830 | unlock_extent(tree, start, end, GFP_ATOMIC); | 1855 | unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC); |
1831 | 1856 | ||
1832 | } while (bvec >= bio->bi_io_vec); | 1857 | } while (bvec >= bio->bi_io_vec); |
1833 | 1858 | ||
@@ -2016,14 +2041,17 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
2016 | while (cur <= end) { | 2041 | while (cur <= end) { |
2017 | if (cur >= last_byte) { | 2042 | if (cur >= last_byte) { |
2018 | char *userpage; | 2043 | char *userpage; |
2044 | struct extent_state *cached = NULL; | ||
2045 | |||
2019 | iosize = PAGE_CACHE_SIZE - page_offset; | 2046 | iosize = PAGE_CACHE_SIZE - page_offset; |
2020 | userpage = kmap_atomic(page, KM_USER0); | 2047 | userpage = kmap_atomic(page, KM_USER0); |
2021 | memset(userpage + page_offset, 0, iosize); | 2048 | memset(userpage + page_offset, 0, iosize); |
2022 | flush_dcache_page(page); | 2049 | flush_dcache_page(page); |
2023 | kunmap_atomic(userpage, KM_USER0); | 2050 | kunmap_atomic(userpage, KM_USER0); |
2024 | set_extent_uptodate(tree, cur, cur + iosize - 1, | 2051 | set_extent_uptodate(tree, cur, cur + iosize - 1, |
2025 | GFP_NOFS); | 2052 | &cached, GFP_NOFS); |
2026 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); | 2053 | unlock_extent_cached(tree, cur, cur + iosize - 1, |
2054 | &cached, GFP_NOFS); | ||
2027 | break; | 2055 | break; |
2028 | } | 2056 | } |
2029 | em = get_extent(inode, page, page_offset, cur, | 2057 | em = get_extent(inode, page, page_offset, cur, |
@@ -2063,14 +2091,17 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
2063 | /* we've found a hole, just zero and go on */ | 2091 | /* we've found a hole, just zero and go on */ |
2064 | if (block_start == EXTENT_MAP_HOLE) { | 2092 | if (block_start == EXTENT_MAP_HOLE) { |
2065 | char *userpage; | 2093 | char *userpage; |
2094 | struct extent_state *cached = NULL; | ||
2095 | |||
2066 | userpage = kmap_atomic(page, KM_USER0); | 2096 | userpage = kmap_atomic(page, KM_USER0); |
2067 | memset(userpage + page_offset, 0, iosize); | 2097 | memset(userpage + page_offset, 0, iosize); |
2068 | flush_dcache_page(page); | 2098 | flush_dcache_page(page); |
2069 | kunmap_atomic(userpage, KM_USER0); | 2099 | kunmap_atomic(userpage, KM_USER0); |
2070 | 2100 | ||
2071 | set_extent_uptodate(tree, cur, cur + iosize - 1, | 2101 | set_extent_uptodate(tree, cur, cur + iosize - 1, |
2072 | GFP_NOFS); | 2102 | &cached, GFP_NOFS); |
2073 | unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); | 2103 | unlock_extent_cached(tree, cur, cur + iosize - 1, |
2104 | &cached, GFP_NOFS); | ||
2074 | cur = cur + iosize; | 2105 | cur = cur + iosize; |
2075 | page_offset += iosize; | 2106 | page_offset += iosize; |
2076 | continue; | 2107 | continue; |
@@ -2789,9 +2820,12 @@ int extent_prepare_write(struct extent_io_tree *tree, | |||
2789 | iocount++; | 2820 | iocount++; |
2790 | block_start = block_start + iosize; | 2821 | block_start = block_start + iosize; |
2791 | } else { | 2822 | } else { |
2792 | set_extent_uptodate(tree, block_start, cur_end, | 2823 | struct extent_state *cached = NULL; |
2824 | |||
2825 | set_extent_uptodate(tree, block_start, cur_end, &cached, | ||
2793 | GFP_NOFS); | 2826 | GFP_NOFS); |
2794 | unlock_extent(tree, block_start, cur_end, GFP_NOFS); | 2827 | unlock_extent_cached(tree, block_start, cur_end, |
2828 | &cached, GFP_NOFS); | ||
2795 | block_start = cur_end + 1; | 2829 | block_start = cur_end + 1; |
2796 | } | 2830 | } |
2797 | page_offset = block_start & (PAGE_CACHE_SIZE - 1); | 2831 | page_offset = block_start & (PAGE_CACHE_SIZE - 1); |
@@ -3457,7 +3491,7 @@ int set_extent_buffer_uptodate(struct extent_io_tree *tree, | |||
3457 | num_pages = num_extent_pages(eb->start, eb->len); | 3491 | num_pages = num_extent_pages(eb->start, eb->len); |
3458 | 3492 | ||
3459 | set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, | 3493 | set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, |
3460 | GFP_NOFS); | 3494 | NULL, GFP_NOFS); |
3461 | for (i = 0; i < num_pages; i++) { | 3495 | for (i = 0; i < num_pages; i++) { |
3462 | page = extent_buffer_page(eb, i); | 3496 | page = extent_buffer_page(eb, i); |
3463 | if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || | 3497 | if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || |
@@ -3885,6 +3919,12 @@ static void move_pages(struct page *dst_page, struct page *src_page, | |||
3885 | kunmap_atomic(dst_kaddr, KM_USER0); | 3919 | kunmap_atomic(dst_kaddr, KM_USER0); |
3886 | } | 3920 | } |
3887 | 3921 | ||
3922 | static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len) | ||
3923 | { | ||
3924 | unsigned long distance = (src > dst) ? src - dst : dst - src; | ||
3925 | return distance < len; | ||
3926 | } | ||
3927 | |||
3888 | static void copy_pages(struct page *dst_page, struct page *src_page, | 3928 | static void copy_pages(struct page *dst_page, struct page *src_page, |
3889 | unsigned long dst_off, unsigned long src_off, | 3929 | unsigned long dst_off, unsigned long src_off, |
3890 | unsigned long len) | 3930 | unsigned long len) |
@@ -3892,10 +3932,12 @@ static void copy_pages(struct page *dst_page, struct page *src_page, | |||
3892 | char *dst_kaddr = kmap_atomic(dst_page, KM_USER0); | 3932 | char *dst_kaddr = kmap_atomic(dst_page, KM_USER0); |
3893 | char *src_kaddr; | 3933 | char *src_kaddr; |
3894 | 3934 | ||
3895 | if (dst_page != src_page) | 3935 | if (dst_page != src_page) { |
3896 | src_kaddr = kmap_atomic(src_page, KM_USER1); | 3936 | src_kaddr = kmap_atomic(src_page, KM_USER1); |
3897 | else | 3937 | } else { |
3898 | src_kaddr = dst_kaddr; | 3938 | src_kaddr = dst_kaddr; |
3939 | BUG_ON(areas_overlap(src_off, dst_off, len)); | ||
3940 | } | ||
3899 | 3941 | ||
3900 | memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len); | 3942 | memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len); |
3901 | kunmap_atomic(dst_kaddr, KM_USER0); | 3943 | kunmap_atomic(dst_kaddr, KM_USER0); |
@@ -3970,7 +4012,7 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, | |||
3970 | "len %lu len %lu\n", dst_offset, len, dst->len); | 4012 | "len %lu len %lu\n", dst_offset, len, dst->len); |
3971 | BUG_ON(1); | 4013 | BUG_ON(1); |
3972 | } | 4014 | } |
3973 | if (dst_offset < src_offset) { | 4015 | if (!areas_overlap(src_offset, dst_offset, len)) { |
3974 | memcpy_extent_buffer(dst, dst_offset, src_offset, len); | 4016 | memcpy_extent_buffer(dst, dst_offset, src_offset, len); |
3975 | return; | 4017 | return; |
3976 | } | 4018 | } |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index f62c5442835d..af2d7179c372 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -208,7 +208,7 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
208 | int bits, int exclusive_bits, u64 *failed_start, | 208 | int bits, int exclusive_bits, u64 *failed_start, |
209 | struct extent_state **cached_state, gfp_t mask); | 209 | struct extent_state **cached_state, gfp_t mask); |
210 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, | 210 | int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, |
211 | gfp_t mask); | 211 | struct extent_state **cached_state, gfp_t mask); |
212 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, | 212 | int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, |
213 | gfp_t mask); | 213 | gfp_t mask); |
214 | int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, | 214 | int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e621ea54a3fd..75899a01dded 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -104,7 +104,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, | |||
104 | /* | 104 | /* |
105 | * unlocks pages after btrfs_file_write is done with them | 105 | * unlocks pages after btrfs_file_write is done with them |
106 | */ | 106 | */ |
107 | static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages) | 107 | void btrfs_drop_pages(struct page **pages, size_t num_pages) |
108 | { | 108 | { |
109 | size_t i; | 109 | size_t i; |
110 | for (i = 0; i < num_pages; i++) { | 110 | for (i = 0; i < num_pages; i++) { |
@@ -127,16 +127,13 @@ static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages) | |||
127 | * this also makes the decision about creating an inline extent vs | 127 | * this also makes the decision about creating an inline extent vs |
128 | * doing real data extents, marking pages dirty and delalloc as required. | 128 | * doing real data extents, marking pages dirty and delalloc as required. |
129 | */ | 129 | */ |
130 | static noinline int dirty_and_release_pages(struct btrfs_root *root, | 130 | int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, |
131 | struct file *file, | 131 | struct page **pages, size_t num_pages, |
132 | struct page **pages, | 132 | loff_t pos, size_t write_bytes, |
133 | size_t num_pages, | 133 | struct extent_state **cached) |
134 | loff_t pos, | ||
135 | size_t write_bytes) | ||
136 | { | 134 | { |
137 | int err = 0; | 135 | int err = 0; |
138 | int i; | 136 | int i; |
139 | struct inode *inode = fdentry(file)->d_inode; | ||
140 | u64 num_bytes; | 137 | u64 num_bytes; |
141 | u64 start_pos; | 138 | u64 start_pos; |
142 | u64 end_of_last_block; | 139 | u64 end_of_last_block; |
@@ -149,7 +146,7 @@ static noinline int dirty_and_release_pages(struct btrfs_root *root, | |||
149 | 146 | ||
150 | end_of_last_block = start_pos + num_bytes - 1; | 147 | end_of_last_block = start_pos + num_bytes - 1; |
151 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, | 148 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, |
152 | NULL); | 149 | cached); |
153 | if (err) | 150 | if (err) |
154 | return err; | 151 | return err; |
155 | 152 | ||
@@ -992,9 +989,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
992 | } | 989 | } |
993 | 990 | ||
994 | if (copied > 0) { | 991 | if (copied > 0) { |
995 | ret = dirty_and_release_pages(root, file, pages, | 992 | ret = btrfs_dirty_pages(root, inode, pages, |
996 | dirty_pages, pos, | 993 | dirty_pages, pos, copied, |
997 | copied); | 994 | NULL); |
998 | if (ret) { | 995 | if (ret) { |
999 | btrfs_delalloc_release_space(inode, | 996 | btrfs_delalloc_release_space(inode, |
1000 | dirty_pages << PAGE_CACHE_SHIFT); | 997 | dirty_pages << PAGE_CACHE_SHIFT); |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index f561c953205b..11d2e9cea09e 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -508,6 +508,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
508 | struct inode *inode; | 508 | struct inode *inode; |
509 | struct rb_node *node; | 509 | struct rb_node *node; |
510 | struct list_head *pos, *n; | 510 | struct list_head *pos, *n; |
511 | struct page **pages; | ||
511 | struct page *page; | 512 | struct page *page; |
512 | struct extent_state *cached_state = NULL; | 513 | struct extent_state *cached_state = NULL; |
513 | struct btrfs_free_cluster *cluster = NULL; | 514 | struct btrfs_free_cluster *cluster = NULL; |
@@ -517,13 +518,13 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
517 | u64 start, end, len; | 518 | u64 start, end, len; |
518 | u64 bytes = 0; | 519 | u64 bytes = 0; |
519 | u32 *crc, *checksums; | 520 | u32 *crc, *checksums; |
520 | pgoff_t index = 0, last_index = 0; | ||
521 | unsigned long first_page_offset; | 521 | unsigned long first_page_offset; |
522 | int num_checksums; | 522 | int index = 0, num_pages = 0; |
523 | int entries = 0; | 523 | int entries = 0; |
524 | int bitmaps = 0; | 524 | int bitmaps = 0; |
525 | int ret = 0; | 525 | int ret = 0; |
526 | bool next_page = false; | 526 | bool next_page = false; |
527 | bool out_of_space = false; | ||
527 | 528 | ||
528 | root = root->fs_info->tree_root; | 529 | root = root->fs_info->tree_root; |
529 | 530 | ||
@@ -551,24 +552,31 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
551 | return 0; | 552 | return 0; |
552 | } | 553 | } |
553 | 554 | ||
554 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; | 555 | num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> |
556 | PAGE_CACHE_SHIFT; | ||
555 | filemap_write_and_wait(inode->i_mapping); | 557 | filemap_write_and_wait(inode->i_mapping); |
556 | btrfs_wait_ordered_range(inode, inode->i_size & | 558 | btrfs_wait_ordered_range(inode, inode->i_size & |
557 | ~(root->sectorsize - 1), (u64)-1); | 559 | ~(root->sectorsize - 1), (u64)-1); |
558 | 560 | ||
559 | /* We need a checksum per page. */ | 561 | /* We need a checksum per page. */ |
560 | num_checksums = i_size_read(inode) / PAGE_CACHE_SIZE; | 562 | crc = checksums = kzalloc(sizeof(u32) * num_pages, GFP_NOFS); |
561 | crc = checksums = kzalloc(sizeof(u32) * num_checksums, GFP_NOFS); | ||
562 | if (!crc) { | 563 | if (!crc) { |
563 | iput(inode); | 564 | iput(inode); |
564 | return 0; | 565 | return 0; |
565 | } | 566 | } |
566 | 567 | ||
568 | pages = kzalloc(sizeof(struct page *) * num_pages, GFP_NOFS); | ||
569 | if (!pages) { | ||
570 | kfree(crc); | ||
571 | iput(inode); | ||
572 | return 0; | ||
573 | } | ||
574 | |||
567 | /* Since the first page has all of our checksums and our generation we | 575 | /* Since the first page has all of our checksums and our generation we |
568 | * need to calculate the offset into the page that we can start writing | 576 | * need to calculate the offset into the page that we can start writing |
569 | * our entries. | 577 | * our entries. |
570 | */ | 578 | */ |
571 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); | 579 | first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64); |
572 | 580 | ||
573 | /* Get the cluster for this block_group if it exists */ | 581 | /* Get the cluster for this block_group if it exists */ |
574 | if (!list_empty(&block_group->cluster_list)) | 582 | if (!list_empty(&block_group->cluster_list)) |
@@ -590,20 +598,18 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
590 | * after find_get_page at this point. Just putting this here so people | 598 | * after find_get_page at this point. Just putting this here so people |
591 | * know and don't freak out. | 599 | * know and don't freak out. |
592 | */ | 600 | */ |
593 | while (index <= last_index) { | 601 | while (index < num_pages) { |
594 | page = grab_cache_page(inode->i_mapping, index); | 602 | page = grab_cache_page(inode->i_mapping, index); |
595 | if (!page) { | 603 | if (!page) { |
596 | pgoff_t i = 0; | 604 | int i; |
597 | 605 | ||
598 | while (i < index) { | 606 | for (i = 0; i < num_pages; i++) { |
599 | page = find_get_page(inode->i_mapping, i); | 607 | unlock_page(pages[i]); |
600 | unlock_page(page); | 608 | page_cache_release(pages[i]); |
601 | page_cache_release(page); | ||
602 | page_cache_release(page); | ||
603 | i++; | ||
604 | } | 609 | } |
605 | goto out_free; | 610 | goto out_free; |
606 | } | 611 | } |
612 | pages[index] = page; | ||
607 | index++; | 613 | index++; |
608 | } | 614 | } |
609 | 615 | ||
@@ -631,7 +637,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
631 | offset = start_offset; | 637 | offset = start_offset; |
632 | } | 638 | } |
633 | 639 | ||
634 | page = find_get_page(inode->i_mapping, index); | 640 | if (index >= num_pages) { |
641 | out_of_space = true; | ||
642 | break; | ||
643 | } | ||
644 | |||
645 | page = pages[index]; | ||
635 | 646 | ||
636 | addr = kmap(page); | 647 | addr = kmap(page); |
637 | entry = addr + start_offset; | 648 | entry = addr + start_offset; |
@@ -708,23 +719,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
708 | 719 | ||
709 | bytes += PAGE_CACHE_SIZE; | 720 | bytes += PAGE_CACHE_SIZE; |
710 | 721 | ||
711 | ClearPageChecked(page); | ||
712 | set_page_extent_mapped(page); | ||
713 | SetPageUptodate(page); | ||
714 | set_page_dirty(page); | ||
715 | |||
716 | /* | ||
717 | * We need to release our reference we got for grab_cache_page, | ||
718 | * except for the first page which will hold our checksums, we | ||
719 | * do that below. | ||
720 | */ | ||
721 | if (index != 0) { | ||
722 | unlock_page(page); | ||
723 | page_cache_release(page); | ||
724 | } | ||
725 | |||
726 | page_cache_release(page); | ||
727 | |||
728 | index++; | 722 | index++; |
729 | } while (node || next_page); | 723 | } while (node || next_page); |
730 | 724 | ||
@@ -734,7 +728,11 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
734 | struct btrfs_free_space *entry = | 728 | struct btrfs_free_space *entry = |
735 | list_entry(pos, struct btrfs_free_space, list); | 729 | list_entry(pos, struct btrfs_free_space, list); |
736 | 730 | ||
737 | page = find_get_page(inode->i_mapping, index); | 731 | if (index >= num_pages) { |
732 | out_of_space = true; | ||
733 | break; | ||
734 | } | ||
735 | page = pages[index]; | ||
738 | 736 | ||
739 | addr = kmap(page); | 737 | addr = kmap(page); |
740 | memcpy(addr, entry->bitmap, PAGE_CACHE_SIZE); | 738 | memcpy(addr, entry->bitmap, PAGE_CACHE_SIZE); |
@@ -745,64 +743,58 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
745 | crc++; | 743 | crc++; |
746 | bytes += PAGE_CACHE_SIZE; | 744 | bytes += PAGE_CACHE_SIZE; |
747 | 745 | ||
748 | ClearPageChecked(page); | ||
749 | set_page_extent_mapped(page); | ||
750 | SetPageUptodate(page); | ||
751 | set_page_dirty(page); | ||
752 | unlock_page(page); | ||
753 | page_cache_release(page); | ||
754 | page_cache_release(page); | ||
755 | list_del_init(&entry->list); | 746 | list_del_init(&entry->list); |
756 | index++; | 747 | index++; |
757 | } | 748 | } |
758 | 749 | ||
750 | if (out_of_space) { | ||
751 | btrfs_drop_pages(pages, num_pages); | ||
752 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, | ||
753 | i_size_read(inode) - 1, &cached_state, | ||
754 | GFP_NOFS); | ||
755 | ret = 0; | ||
756 | goto out_free; | ||
757 | } | ||
758 | |||
759 | /* Zero out the rest of the pages just to make sure */ | 759 | /* Zero out the rest of the pages just to make sure */ |
760 | while (index <= last_index) { | 760 | while (index < num_pages) { |
761 | void *addr; | 761 | void *addr; |
762 | 762 | ||
763 | page = find_get_page(inode->i_mapping, index); | 763 | page = pages[index]; |
764 | |||
765 | addr = kmap(page); | 764 | addr = kmap(page); |
766 | memset(addr, 0, PAGE_CACHE_SIZE); | 765 | memset(addr, 0, PAGE_CACHE_SIZE); |
767 | kunmap(page); | 766 | kunmap(page); |
768 | ClearPageChecked(page); | ||
769 | set_page_extent_mapped(page); | ||
770 | SetPageUptodate(page); | ||
771 | set_page_dirty(page); | ||
772 | unlock_page(page); | ||
773 | page_cache_release(page); | ||
774 | page_cache_release(page); | ||
775 | bytes += PAGE_CACHE_SIZE; | 767 | bytes += PAGE_CACHE_SIZE; |
776 | index++; | 768 | index++; |
777 | } | 769 | } |
778 | 770 | ||
779 | btrfs_set_extent_delalloc(inode, 0, bytes - 1, &cached_state); | ||
780 | |||
781 | /* Write the checksums and trans id to the first page */ | 771 | /* Write the checksums and trans id to the first page */ |
782 | { | 772 | { |
783 | void *addr; | 773 | void *addr; |
784 | u64 *gen; | 774 | u64 *gen; |
785 | 775 | ||
786 | page = find_get_page(inode->i_mapping, 0); | 776 | page = pages[0]; |
787 | 777 | ||
788 | addr = kmap(page); | 778 | addr = kmap(page); |
789 | memcpy(addr, checksums, sizeof(u32) * num_checksums); | 779 | memcpy(addr, checksums, sizeof(u32) * num_pages); |
790 | gen = addr + (sizeof(u32) * num_checksums); | 780 | gen = addr + (sizeof(u32) * num_pages); |
791 | *gen = trans->transid; | 781 | *gen = trans->transid; |
792 | kunmap(page); | 782 | kunmap(page); |
793 | ClearPageChecked(page); | ||
794 | set_page_extent_mapped(page); | ||
795 | SetPageUptodate(page); | ||
796 | set_page_dirty(page); | ||
797 | unlock_page(page); | ||
798 | page_cache_release(page); | ||
799 | page_cache_release(page); | ||
800 | } | 783 | } |
801 | BTRFS_I(inode)->generation = trans->transid; | ||
802 | 784 | ||
785 | ret = btrfs_dirty_pages(root, inode, pages, num_pages, 0, | ||
786 | bytes, &cached_state); | ||
787 | btrfs_drop_pages(pages, num_pages); | ||
803 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, | 788 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, |
804 | i_size_read(inode) - 1, &cached_state, GFP_NOFS); | 789 | i_size_read(inode) - 1, &cached_state, GFP_NOFS); |
805 | 790 | ||
791 | if (ret) { | ||
792 | ret = 0; | ||
793 | goto out_free; | ||
794 | } | ||
795 | |||
796 | BTRFS_I(inode)->generation = trans->transid; | ||
797 | |||
806 | filemap_write_and_wait(inode->i_mapping); | 798 | filemap_write_and_wait(inode->i_mapping); |
807 | 799 | ||
808 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; | 800 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; |
@@ -853,6 +845,7 @@ out_free: | |||
853 | BTRFS_I(inode)->generation = 0; | 845 | BTRFS_I(inode)->generation = 0; |
854 | } | 846 | } |
855 | kfree(checksums); | 847 | kfree(checksums); |
848 | kfree(pages); | ||
856 | btrfs_update_inode(trans, root, inode); | 849 | btrfs_update_inode(trans, root, inode); |
857 | iput(inode); | 850 | iput(inode); |
858 | return ret; | 851 | return ret; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5cc64ab9c485..fcd66b6a8086 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1770,9 +1770,12 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1770 | add_pending_csums(trans, inode, ordered_extent->file_offset, | 1770 | add_pending_csums(trans, inode, ordered_extent->file_offset, |
1771 | &ordered_extent->list); | 1771 | &ordered_extent->list); |
1772 | 1772 | ||
1773 | btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1773 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1774 | ret = btrfs_update_inode(trans, root, inode); | 1774 | if (!ret) { |
1775 | BUG_ON(ret); | 1775 | ret = btrfs_update_inode(trans, root, inode); |
1776 | BUG_ON(ret); | ||
1777 | } | ||
1778 | ret = 0; | ||
1776 | out: | 1779 | out: |
1777 | if (nolock) { | 1780 | if (nolock) { |
1778 | if (trans) | 1781 | if (trans) |
@@ -2590,6 +2593,13 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
2590 | struct btrfs_inode_item *item, | 2593 | struct btrfs_inode_item *item, |
2591 | struct inode *inode) | 2594 | struct inode *inode) |
2592 | { | 2595 | { |
2596 | if (!leaf->map_token) | ||
2597 | map_private_extent_buffer(leaf, (unsigned long)item, | ||
2598 | sizeof(struct btrfs_inode_item), | ||
2599 | &leaf->map_token, &leaf->kaddr, | ||
2600 | &leaf->map_start, &leaf->map_len, | ||
2601 | KM_USER1); | ||
2602 | |||
2593 | btrfs_set_inode_uid(leaf, item, inode->i_uid); | 2603 | btrfs_set_inode_uid(leaf, item, inode->i_uid); |
2594 | btrfs_set_inode_gid(leaf, item, inode->i_gid); | 2604 | btrfs_set_inode_gid(leaf, item, inode->i_gid); |
2595 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); | 2605 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); |
@@ -2618,6 +2628,11 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
2618 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); | 2628 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); |
2619 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); | 2629 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); |
2620 | btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group); | 2630 | btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group); |
2631 | |||
2632 | if (leaf->map_token) { | ||
2633 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | ||
2634 | leaf->map_token = NULL; | ||
2635 | } | ||
2621 | } | 2636 | } |
2622 | 2637 | ||
2623 | /* | 2638 | /* |
@@ -4207,10 +4222,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4207 | struct btrfs_key found_key; | 4222 | struct btrfs_key found_key; |
4208 | struct btrfs_path *path; | 4223 | struct btrfs_path *path; |
4209 | int ret; | 4224 | int ret; |
4210 | u32 nritems; | ||
4211 | struct extent_buffer *leaf; | 4225 | struct extent_buffer *leaf; |
4212 | int slot; | 4226 | int slot; |
4213 | int advance; | ||
4214 | unsigned char d_type; | 4227 | unsigned char d_type; |
4215 | int over = 0; | 4228 | int over = 0; |
4216 | u32 di_cur; | 4229 | u32 di_cur; |
@@ -4253,27 +4266,19 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4253 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 4266 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
4254 | if (ret < 0) | 4267 | if (ret < 0) |
4255 | goto err; | 4268 | goto err; |
4256 | advance = 0; | ||
4257 | 4269 | ||
4258 | while (1) { | 4270 | while (1) { |
4259 | leaf = path->nodes[0]; | 4271 | leaf = path->nodes[0]; |
4260 | nritems = btrfs_header_nritems(leaf); | ||
4261 | slot = path->slots[0]; | 4272 | slot = path->slots[0]; |
4262 | if (advance || slot >= nritems) { | 4273 | if (slot >= btrfs_header_nritems(leaf)) { |
4263 | if (slot >= nritems - 1) { | 4274 | ret = btrfs_next_leaf(root, path); |
4264 | ret = btrfs_next_leaf(root, path); | 4275 | if (ret < 0) |
4265 | if (ret) | 4276 | goto err; |
4266 | break; | 4277 | else if (ret > 0) |
4267 | leaf = path->nodes[0]; | 4278 | break; |
4268 | nritems = btrfs_header_nritems(leaf); | 4279 | continue; |
4269 | slot = path->slots[0]; | ||
4270 | } else { | ||
4271 | slot++; | ||
4272 | path->slots[0]++; | ||
4273 | } | ||
4274 | } | 4280 | } |
4275 | 4281 | ||
4276 | advance = 1; | ||
4277 | item = btrfs_item_nr(leaf, slot); | 4282 | item = btrfs_item_nr(leaf, slot); |
4278 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 4283 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
4279 | 4284 | ||
@@ -4282,7 +4287,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4282 | if (btrfs_key_type(&found_key) != key_type) | 4287 | if (btrfs_key_type(&found_key) != key_type) |
4283 | break; | 4288 | break; |
4284 | if (found_key.offset < filp->f_pos) | 4289 | if (found_key.offset < filp->f_pos) |
4285 | continue; | 4290 | goto next; |
4286 | 4291 | ||
4287 | filp->f_pos = found_key.offset; | 4292 | filp->f_pos = found_key.offset; |
4288 | 4293 | ||
@@ -4335,6 +4340,8 @@ skip: | |||
4335 | di_cur += di_len; | 4340 | di_cur += di_len; |
4336 | di = (struct btrfs_dir_item *)((char *)di + di_len); | 4341 | di = (struct btrfs_dir_item *)((char *)di + di_len); |
4337 | } | 4342 | } |
4343 | next: | ||
4344 | path->slots[0]++; | ||
4338 | } | 4345 | } |
4339 | 4346 | ||
4340 | /* Reached end of directory/root. Bump pos past the last item. */ | 4347 | /* Reached end of directory/root. Bump pos past the last item. */ |
@@ -4527,14 +4534,17 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
4527 | BUG_ON(!path); | 4534 | BUG_ON(!path); |
4528 | 4535 | ||
4529 | inode = new_inode(root->fs_info->sb); | 4536 | inode = new_inode(root->fs_info->sb); |
4530 | if (!inode) | 4537 | if (!inode) { |
4538 | btrfs_free_path(path); | ||
4531 | return ERR_PTR(-ENOMEM); | 4539 | return ERR_PTR(-ENOMEM); |
4540 | } | ||
4532 | 4541 | ||
4533 | if (dir) { | 4542 | if (dir) { |
4534 | trace_btrfs_inode_request(dir); | 4543 | trace_btrfs_inode_request(dir); |
4535 | 4544 | ||
4536 | ret = btrfs_set_inode_index(dir, index); | 4545 | ret = btrfs_set_inode_index(dir, index); |
4537 | if (ret) { | 4546 | if (ret) { |
4547 | btrfs_free_path(path); | ||
4538 | iput(inode); | 4548 | iput(inode); |
4539 | return ERR_PTR(ret); | 4549 | return ERR_PTR(ret); |
4540 | } | 4550 | } |
@@ -4834,9 +4844,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4834 | if (inode->i_nlink == ~0U) | 4844 | if (inode->i_nlink == ~0U) |
4835 | return -EMLINK; | 4845 | return -EMLINK; |
4836 | 4846 | ||
4837 | btrfs_inc_nlink(inode); | ||
4838 | inode->i_ctime = CURRENT_TIME; | ||
4839 | |||
4840 | err = btrfs_set_inode_index(dir, &index); | 4847 | err = btrfs_set_inode_index(dir, &index); |
4841 | if (err) | 4848 | if (err) |
4842 | goto fail; | 4849 | goto fail; |
@@ -4852,6 +4859,9 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4852 | goto fail; | 4859 | goto fail; |
4853 | } | 4860 | } |
4854 | 4861 | ||
4862 | btrfs_inc_nlink(inode); | ||
4863 | inode->i_ctime = CURRENT_TIME; | ||
4864 | |||
4855 | btrfs_set_trans_block_group(trans, dir); | 4865 | btrfs_set_trans_block_group(trans, dir); |
4856 | ihold(inode); | 4866 | ihold(inode); |
4857 | 4867 | ||
@@ -5221,7 +5231,7 @@ again: | |||
5221 | btrfs_mark_buffer_dirty(leaf); | 5231 | btrfs_mark_buffer_dirty(leaf); |
5222 | } | 5232 | } |
5223 | set_extent_uptodate(io_tree, em->start, | 5233 | set_extent_uptodate(io_tree, em->start, |
5224 | extent_map_end(em) - 1, GFP_NOFS); | 5234 | extent_map_end(em) - 1, NULL, GFP_NOFS); |
5225 | goto insert; | 5235 | goto insert; |
5226 | } else { | 5236 | } else { |
5227 | printk(KERN_ERR "btrfs unknown found_type %d\n", found_type); | 5237 | printk(KERN_ERR "btrfs unknown found_type %d\n", found_type); |
@@ -5428,17 +5438,30 @@ out: | |||
5428 | } | 5438 | } |
5429 | 5439 | ||
5430 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | 5440 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, |
5441 | struct extent_map *em, | ||
5431 | u64 start, u64 len) | 5442 | u64 start, u64 len) |
5432 | { | 5443 | { |
5433 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5444 | struct btrfs_root *root = BTRFS_I(inode)->root; |
5434 | struct btrfs_trans_handle *trans; | 5445 | struct btrfs_trans_handle *trans; |
5435 | struct extent_map *em; | ||
5436 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 5446 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
5437 | struct btrfs_key ins; | 5447 | struct btrfs_key ins; |
5438 | u64 alloc_hint; | 5448 | u64 alloc_hint; |
5439 | int ret; | 5449 | int ret; |
5450 | bool insert = false; | ||
5440 | 5451 | ||
5441 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | 5452 | /* |
5453 | * Ok if the extent map we looked up is a hole and is for the exact | ||
5454 | * range we want, there is no reason to allocate a new one, however if | ||
5455 | * it is not right then we need to free this one and drop the cache for | ||
5456 | * our range. | ||
5457 | */ | ||
5458 | if (em->block_start != EXTENT_MAP_HOLE || em->start != start || | ||
5459 | em->len != len) { | ||
5460 | free_extent_map(em); | ||
5461 | em = NULL; | ||
5462 | insert = true; | ||
5463 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | ||
5464 | } | ||
5442 | 5465 | ||
5443 | trans = btrfs_join_transaction(root, 0); | 5466 | trans = btrfs_join_transaction(root, 0); |
5444 | if (IS_ERR(trans)) | 5467 | if (IS_ERR(trans)) |
@@ -5454,10 +5477,12 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
5454 | goto out; | 5477 | goto out; |
5455 | } | 5478 | } |
5456 | 5479 | ||
5457 | em = alloc_extent_map(GFP_NOFS); | ||
5458 | if (!em) { | 5480 | if (!em) { |
5459 | em = ERR_PTR(-ENOMEM); | 5481 | em = alloc_extent_map(GFP_NOFS); |
5460 | goto out; | 5482 | if (!em) { |
5483 | em = ERR_PTR(-ENOMEM); | ||
5484 | goto out; | ||
5485 | } | ||
5461 | } | 5486 | } |
5462 | 5487 | ||
5463 | em->start = start; | 5488 | em->start = start; |
@@ -5467,9 +5492,15 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
5467 | em->block_start = ins.objectid; | 5492 | em->block_start = ins.objectid; |
5468 | em->block_len = ins.offset; | 5493 | em->block_len = ins.offset; |
5469 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 5494 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
5495 | |||
5496 | /* | ||
5497 | * We need to do this because if we're using the original em we searched | ||
5498 | * for, we could have EXTENT_FLAG_VACANCY set, and we don't want that. | ||
5499 | */ | ||
5500 | em->flags = 0; | ||
5470 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 5501 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
5471 | 5502 | ||
5472 | while (1) { | 5503 | while (insert) { |
5473 | write_lock(&em_tree->lock); | 5504 | write_lock(&em_tree->lock); |
5474 | ret = add_extent_mapping(em_tree, em); | 5505 | ret = add_extent_mapping(em_tree, em); |
5475 | write_unlock(&em_tree->lock); | 5506 | write_unlock(&em_tree->lock); |
@@ -5687,8 +5718,7 @@ must_cow: | |||
5687 | * it above | 5718 | * it above |
5688 | */ | 5719 | */ |
5689 | len = bh_result->b_size; | 5720 | len = bh_result->b_size; |
5690 | free_extent_map(em); | 5721 | em = btrfs_new_extent_direct(inode, em, start, len); |
5691 | em = btrfs_new_extent_direct(inode, start, len); | ||
5692 | if (IS_ERR(em)) | 5722 | if (IS_ERR(em)) |
5693 | return PTR_ERR(em); | 5723 | return PTR_ERR(em); |
5694 | len = min(len, em->len - (start - em->start)); | 5724 | len = min(len, em->len - (start - em->start)); |
@@ -5851,8 +5881,10 @@ again: | |||
5851 | } | 5881 | } |
5852 | 5882 | ||
5853 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); | 5883 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); |
5854 | btrfs_ordered_update_i_size(inode, 0, ordered); | 5884 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
5855 | btrfs_update_inode(trans, root, inode); | 5885 | if (!ret) |
5886 | btrfs_update_inode(trans, root, inode); | ||
5887 | ret = 0; | ||
5856 | out_unlock: | 5888 | out_unlock: |
5857 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, | 5889 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, |
5858 | ordered->file_offset + ordered->len - 1, | 5890 | ordered->file_offset + ordered->len - 1, |
@@ -5938,7 +5970,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, | |||
5938 | 5970 | ||
5939 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | 5971 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, |
5940 | int rw, u64 file_offset, int skip_sum, | 5972 | int rw, u64 file_offset, int skip_sum, |
5941 | u32 *csums) | 5973 | u32 *csums, int async_submit) |
5942 | { | 5974 | { |
5943 | int write = rw & REQ_WRITE; | 5975 | int write = rw & REQ_WRITE; |
5944 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5976 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -5949,13 +5981,24 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
5949 | if (ret) | 5981 | if (ret) |
5950 | goto err; | 5982 | goto err; |
5951 | 5983 | ||
5952 | if (write && !skip_sum) { | 5984 | if (skip_sum) |
5985 | goto map; | ||
5986 | |||
5987 | if (write && async_submit) { | ||
5953 | ret = btrfs_wq_submit_bio(root->fs_info, | 5988 | ret = btrfs_wq_submit_bio(root->fs_info, |
5954 | inode, rw, bio, 0, 0, | 5989 | inode, rw, bio, 0, 0, |
5955 | file_offset, | 5990 | file_offset, |
5956 | __btrfs_submit_bio_start_direct_io, | 5991 | __btrfs_submit_bio_start_direct_io, |
5957 | __btrfs_submit_bio_done); | 5992 | __btrfs_submit_bio_done); |
5958 | goto err; | 5993 | goto err; |
5994 | } else if (write) { | ||
5995 | /* | ||
5996 | * If we aren't doing async submit, calculate the csum of the | ||
5997 | * bio now. | ||
5998 | */ | ||
5999 | ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1); | ||
6000 | if (ret) | ||
6001 | goto err; | ||
5959 | } else if (!skip_sum) { | 6002 | } else if (!skip_sum) { |
5960 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, | 6003 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, |
5961 | file_offset, csums); | 6004 | file_offset, csums); |
@@ -5963,7 +6006,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
5963 | goto err; | 6006 | goto err; |
5964 | } | 6007 | } |
5965 | 6008 | ||
5966 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | 6009 | map: |
6010 | ret = btrfs_map_bio(root, rw, bio, 0, async_submit); | ||
5967 | err: | 6011 | err: |
5968 | bio_put(bio); | 6012 | bio_put(bio); |
5969 | return ret; | 6013 | return ret; |
@@ -5985,15 +6029,9 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
5985 | int nr_pages = 0; | 6029 | int nr_pages = 0; |
5986 | u32 *csums = dip->csums; | 6030 | u32 *csums = dip->csums; |
5987 | int ret = 0; | 6031 | int ret = 0; |
6032 | int async_submit = 0; | ||
5988 | int write = rw & REQ_WRITE; | 6033 | int write = rw & REQ_WRITE; |
5989 | 6034 | ||
5990 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
5991 | if (!bio) | ||
5992 | return -ENOMEM; | ||
5993 | bio->bi_private = dip; | ||
5994 | bio->bi_end_io = btrfs_end_dio_bio; | ||
5995 | atomic_inc(&dip->pending_bios); | ||
5996 | |||
5997 | map_length = orig_bio->bi_size; | 6035 | map_length = orig_bio->bi_size; |
5998 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | 6036 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, |
5999 | &map_length, NULL, 0); | 6037 | &map_length, NULL, 0); |
@@ -6002,6 +6040,19 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6002 | return -EIO; | 6040 | return -EIO; |
6003 | } | 6041 | } |
6004 | 6042 | ||
6043 | if (map_length >= orig_bio->bi_size) { | ||
6044 | bio = orig_bio; | ||
6045 | goto submit; | ||
6046 | } | ||
6047 | |||
6048 | async_submit = 1; | ||
6049 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
6050 | if (!bio) | ||
6051 | return -ENOMEM; | ||
6052 | bio->bi_private = dip; | ||
6053 | bio->bi_end_io = btrfs_end_dio_bio; | ||
6054 | atomic_inc(&dip->pending_bios); | ||
6055 | |||
6005 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { | 6056 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { |
6006 | if (unlikely(map_length < submit_len + bvec->bv_len || | 6057 | if (unlikely(map_length < submit_len + bvec->bv_len || |
6007 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, | 6058 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, |
@@ -6015,7 +6066,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6015 | atomic_inc(&dip->pending_bios); | 6066 | atomic_inc(&dip->pending_bios); |
6016 | ret = __btrfs_submit_dio_bio(bio, inode, rw, | 6067 | ret = __btrfs_submit_dio_bio(bio, inode, rw, |
6017 | file_offset, skip_sum, | 6068 | file_offset, skip_sum, |
6018 | csums); | 6069 | csums, async_submit); |
6019 | if (ret) { | 6070 | if (ret) { |
6020 | bio_put(bio); | 6071 | bio_put(bio); |
6021 | atomic_dec(&dip->pending_bios); | 6072 | atomic_dec(&dip->pending_bios); |
@@ -6052,8 +6103,9 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6052 | } | 6103 | } |
6053 | } | 6104 | } |
6054 | 6105 | ||
6106 | submit: | ||
6055 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, | 6107 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, |
6056 | csums); | 6108 | csums, async_submit); |
6057 | if (!ret) | 6109 | if (!ret) |
6058 | return 0; | 6110 | return 0; |
6059 | 6111 | ||
@@ -6148,6 +6200,7 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io | |||
6148 | unsigned long nr_segs) | 6200 | unsigned long nr_segs) |
6149 | { | 6201 | { |
6150 | int seg; | 6202 | int seg; |
6203 | int i; | ||
6151 | size_t size; | 6204 | size_t size; |
6152 | unsigned long addr; | 6205 | unsigned long addr; |
6153 | unsigned blocksize_mask = root->sectorsize - 1; | 6206 | unsigned blocksize_mask = root->sectorsize - 1; |
@@ -6162,8 +6215,22 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io | |||
6162 | addr = (unsigned long)iov[seg].iov_base; | 6215 | addr = (unsigned long)iov[seg].iov_base; |
6163 | size = iov[seg].iov_len; | 6216 | size = iov[seg].iov_len; |
6164 | end += size; | 6217 | end += size; |
6165 | if ((addr & blocksize_mask) || (size & blocksize_mask)) | 6218 | if ((addr & blocksize_mask) || (size & blocksize_mask)) |
6166 | goto out; | 6219 | goto out; |
6220 | |||
6221 | /* If this is a write we don't need to check anymore */ | ||
6222 | if (rw & WRITE) | ||
6223 | continue; | ||
6224 | |||
6225 | /* | ||
6226 | * Check to make sure we don't have duplicate iov_base's in this | ||
6227 | * iovec, if so return EINVAL, otherwise we'll get csum errors | ||
6228 | * when reading back. | ||
6229 | */ | ||
6230 | for (i = seg + 1; i < nr_segs; i++) { | ||
6231 | if (iov[seg].iov_base == iov[i].iov_base) | ||
6232 | goto out; | ||
6233 | } | ||
6167 | } | 6234 | } |
6168 | retval = 0; | 6235 | retval = 0; |
6169 | out: | 6236 | out: |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index cfc264fefdb0..ffb48d6c5433 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2287,7 +2287,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
2287 | struct btrfs_ioctl_space_info space; | 2287 | struct btrfs_ioctl_space_info space; |
2288 | struct btrfs_ioctl_space_info *dest; | 2288 | struct btrfs_ioctl_space_info *dest; |
2289 | struct btrfs_ioctl_space_info *dest_orig; | 2289 | struct btrfs_ioctl_space_info *dest_orig; |
2290 | struct btrfs_ioctl_space_info *user_dest; | 2290 | struct btrfs_ioctl_space_info __user *user_dest; |
2291 | struct btrfs_space_info *info; | 2291 | struct btrfs_space_info *info; |
2292 | u64 types[] = {BTRFS_BLOCK_GROUP_DATA, | 2292 | u64 types[] = {BTRFS_BLOCK_GROUP_DATA, |
2293 | BTRFS_BLOCK_GROUP_SYSTEM, | 2293 | BTRFS_BLOCK_GROUP_SYSTEM, |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 58e7de9cc90c..0ac712efcdf2 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -159,7 +159,7 @@ enum { | |||
159 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, | 159 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, |
160 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, | 160 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, |
161 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, | 161 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, |
162 | Opt_enospc_debug, Opt_err, | 162 | Opt_enospc_debug, Opt_subvolrootid, Opt_err, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static match_table_t tokens = { | 165 | static match_table_t tokens = { |
@@ -189,6 +189,7 @@ static match_table_t tokens = { | |||
189 | {Opt_clear_cache, "clear_cache"}, | 189 | {Opt_clear_cache, "clear_cache"}, |
190 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, | 190 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, |
191 | {Opt_enospc_debug, "enospc_debug"}, | 191 | {Opt_enospc_debug, "enospc_debug"}, |
192 | {Opt_subvolrootid, "subvolrootid=%d"}, | ||
192 | {Opt_err, NULL}, | 193 | {Opt_err, NULL}, |
193 | }; | 194 | }; |
194 | 195 | ||
@@ -232,6 +233,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
232 | break; | 233 | break; |
233 | case Opt_subvol: | 234 | case Opt_subvol: |
234 | case Opt_subvolid: | 235 | case Opt_subvolid: |
236 | case Opt_subvolrootid: | ||
235 | case Opt_device: | 237 | case Opt_device: |
236 | /* | 238 | /* |
237 | * These are parsed by btrfs_parse_early_options | 239 | * These are parsed by btrfs_parse_early_options |
@@ -388,7 +390,7 @@ out: | |||
388 | */ | 390 | */ |
389 | static int btrfs_parse_early_options(const char *options, fmode_t flags, | 391 | static int btrfs_parse_early_options(const char *options, fmode_t flags, |
390 | void *holder, char **subvol_name, u64 *subvol_objectid, | 392 | void *holder, char **subvol_name, u64 *subvol_objectid, |
391 | struct btrfs_fs_devices **fs_devices) | 393 | u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices) |
392 | { | 394 | { |
393 | substring_t args[MAX_OPT_ARGS]; | 395 | substring_t args[MAX_OPT_ARGS]; |
394 | char *opts, *orig, *p; | 396 | char *opts, *orig, *p; |
@@ -429,6 +431,18 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
429 | *subvol_objectid = intarg; | 431 | *subvol_objectid = intarg; |
430 | } | 432 | } |
431 | break; | 433 | break; |
434 | case Opt_subvolrootid: | ||
435 | intarg = 0; | ||
436 | error = match_int(&args[0], &intarg); | ||
437 | if (!error) { | ||
438 | /* we want the original fs_tree */ | ||
439 | if (!intarg) | ||
440 | *subvol_rootid = | ||
441 | BTRFS_FS_TREE_OBJECTID; | ||
442 | else | ||
443 | *subvol_rootid = intarg; | ||
444 | } | ||
445 | break; | ||
432 | case Opt_device: | 446 | case Opt_device: |
433 | error = btrfs_scan_one_device(match_strdup(&args[0]), | 447 | error = btrfs_scan_one_device(match_strdup(&args[0]), |
434 | flags, holder, fs_devices); | 448 | flags, holder, fs_devices); |
@@ -736,6 +750,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
736 | fmode_t mode = FMODE_READ; | 750 | fmode_t mode = FMODE_READ; |
737 | char *subvol_name = NULL; | 751 | char *subvol_name = NULL; |
738 | u64 subvol_objectid = 0; | 752 | u64 subvol_objectid = 0; |
753 | u64 subvol_rootid = 0; | ||
739 | int error = 0; | 754 | int error = 0; |
740 | 755 | ||
741 | if (!(flags & MS_RDONLY)) | 756 | if (!(flags & MS_RDONLY)) |
@@ -743,7 +758,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
743 | 758 | ||
744 | error = btrfs_parse_early_options(data, mode, fs_type, | 759 | error = btrfs_parse_early_options(data, mode, fs_type, |
745 | &subvol_name, &subvol_objectid, | 760 | &subvol_name, &subvol_objectid, |
746 | &fs_devices); | 761 | &subvol_rootid, &fs_devices); |
747 | if (error) | 762 | if (error) |
748 | return ERR_PTR(error); | 763 | return ERR_PTR(error); |
749 | 764 | ||
@@ -807,15 +822,17 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
807 | s->s_flags |= MS_ACTIVE; | 822 | s->s_flags |= MS_ACTIVE; |
808 | } | 823 | } |
809 | 824 | ||
810 | root = get_default_root(s, subvol_objectid); | ||
811 | if (IS_ERR(root)) { | ||
812 | error = PTR_ERR(root); | ||
813 | deactivate_locked_super(s); | ||
814 | goto error_free_subvol_name; | ||
815 | } | ||
816 | /* if they gave us a subvolume name bind mount into that */ | 825 | /* if they gave us a subvolume name bind mount into that */ |
817 | if (strcmp(subvol_name, ".")) { | 826 | if (strcmp(subvol_name, ".")) { |
818 | struct dentry *new_root; | 827 | struct dentry *new_root; |
828 | |||
829 | root = get_default_root(s, subvol_rootid); | ||
830 | if (IS_ERR(root)) { | ||
831 | error = PTR_ERR(root); | ||
832 | deactivate_locked_super(s); | ||
833 | goto error_free_subvol_name; | ||
834 | } | ||
835 | |||
819 | mutex_lock(&root->d_inode->i_mutex); | 836 | mutex_lock(&root->d_inode->i_mutex); |
820 | new_root = lookup_one_len(subvol_name, root, | 837 | new_root = lookup_one_len(subvol_name, root, |
821 | strlen(subvol_name)); | 838 | strlen(subvol_name)); |
@@ -836,6 +853,13 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
836 | } | 853 | } |
837 | dput(root); | 854 | dput(root); |
838 | root = new_root; | 855 | root = new_root; |
856 | } else { | ||
857 | root = get_default_root(s, subvol_objectid); | ||
858 | if (IS_ERR(root)) { | ||
859 | error = PTR_ERR(root); | ||
860 | deactivate_locked_super(s); | ||
861 | goto error_free_subvol_name; | ||
862 | } | ||
839 | } | 863 | } |
840 | 864 | ||
841 | kfree(subvol_name); | 865 | kfree(subvol_name); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 5b158da7e0bb..c571734d5e5a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -32,10 +32,8 @@ | |||
32 | 32 | ||
33 | static noinline void put_transaction(struct btrfs_transaction *transaction) | 33 | static noinline void put_transaction(struct btrfs_transaction *transaction) |
34 | { | 34 | { |
35 | WARN_ON(transaction->use_count == 0); | 35 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
36 | transaction->use_count--; | 36 | if (atomic_dec_and_test(&transaction->use_count)) { |
37 | if (transaction->use_count == 0) { | ||
38 | list_del_init(&transaction->list); | ||
39 | memset(transaction, 0, sizeof(*transaction)); | 37 | memset(transaction, 0, sizeof(*transaction)); |
40 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 38 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
41 | } | 39 | } |
@@ -60,14 +58,14 @@ static noinline int join_transaction(struct btrfs_root *root) | |||
60 | if (!cur_trans) | 58 | if (!cur_trans) |
61 | return -ENOMEM; | 59 | return -ENOMEM; |
62 | root->fs_info->generation++; | 60 | root->fs_info->generation++; |
63 | cur_trans->num_writers = 1; | 61 | atomic_set(&cur_trans->num_writers, 1); |
64 | cur_trans->num_joined = 0; | 62 | cur_trans->num_joined = 0; |
65 | cur_trans->transid = root->fs_info->generation; | 63 | cur_trans->transid = root->fs_info->generation; |
66 | init_waitqueue_head(&cur_trans->writer_wait); | 64 | init_waitqueue_head(&cur_trans->writer_wait); |
67 | init_waitqueue_head(&cur_trans->commit_wait); | 65 | init_waitqueue_head(&cur_trans->commit_wait); |
68 | cur_trans->in_commit = 0; | 66 | cur_trans->in_commit = 0; |
69 | cur_trans->blocked = 0; | 67 | cur_trans->blocked = 0; |
70 | cur_trans->use_count = 1; | 68 | atomic_set(&cur_trans->use_count, 1); |
71 | cur_trans->commit_done = 0; | 69 | cur_trans->commit_done = 0; |
72 | cur_trans->start_time = get_seconds(); | 70 | cur_trans->start_time = get_seconds(); |
73 | 71 | ||
@@ -88,7 +86,7 @@ static noinline int join_transaction(struct btrfs_root *root) | |||
88 | root->fs_info->running_transaction = cur_trans; | 86 | root->fs_info->running_transaction = cur_trans; |
89 | spin_unlock(&root->fs_info->new_trans_lock); | 87 | spin_unlock(&root->fs_info->new_trans_lock); |
90 | } else { | 88 | } else { |
91 | cur_trans->num_writers++; | 89 | atomic_inc(&cur_trans->num_writers); |
92 | cur_trans->num_joined++; | 90 | cur_trans->num_joined++; |
93 | } | 91 | } |
94 | 92 | ||
@@ -145,7 +143,7 @@ static void wait_current_trans(struct btrfs_root *root) | |||
145 | cur_trans = root->fs_info->running_transaction; | 143 | cur_trans = root->fs_info->running_transaction; |
146 | if (cur_trans && cur_trans->blocked) { | 144 | if (cur_trans && cur_trans->blocked) { |
147 | DEFINE_WAIT(wait); | 145 | DEFINE_WAIT(wait); |
148 | cur_trans->use_count++; | 146 | atomic_inc(&cur_trans->use_count); |
149 | while (1) { | 147 | while (1) { |
150 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, | 148 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, |
151 | TASK_UNINTERRUPTIBLE); | 149 | TASK_UNINTERRUPTIBLE); |
@@ -181,6 +179,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | |||
181 | { | 179 | { |
182 | struct btrfs_trans_handle *h; | 180 | struct btrfs_trans_handle *h; |
183 | struct btrfs_transaction *cur_trans; | 181 | struct btrfs_transaction *cur_trans; |
182 | int retries = 0; | ||
184 | int ret; | 183 | int ret; |
185 | 184 | ||
186 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) | 185 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) |
@@ -204,7 +203,7 @@ again: | |||
204 | } | 203 | } |
205 | 204 | ||
206 | cur_trans = root->fs_info->running_transaction; | 205 | cur_trans = root->fs_info->running_transaction; |
207 | cur_trans->use_count++; | 206 | atomic_inc(&cur_trans->use_count); |
208 | if (type != TRANS_JOIN_NOLOCK) | 207 | if (type != TRANS_JOIN_NOLOCK) |
209 | mutex_unlock(&root->fs_info->trans_mutex); | 208 | mutex_unlock(&root->fs_info->trans_mutex); |
210 | 209 | ||
@@ -224,10 +223,18 @@ again: | |||
224 | 223 | ||
225 | if (num_items > 0) { | 224 | if (num_items > 0) { |
226 | ret = btrfs_trans_reserve_metadata(h, root, num_items); | 225 | ret = btrfs_trans_reserve_metadata(h, root, num_items); |
227 | if (ret == -EAGAIN) { | 226 | if (ret == -EAGAIN && !retries) { |
227 | retries++; | ||
228 | btrfs_commit_transaction(h, root); | 228 | btrfs_commit_transaction(h, root); |
229 | goto again; | 229 | goto again; |
230 | } else if (ret == -EAGAIN) { | ||
231 | /* | ||
232 | * We have already retried and got EAGAIN, so really we | ||
233 | * don't have space, so set ret to -ENOSPC. | ||
234 | */ | ||
235 | ret = -ENOSPC; | ||
230 | } | 236 | } |
237 | |||
231 | if (ret < 0) { | 238 | if (ret < 0) { |
232 | btrfs_end_transaction(h, root); | 239 | btrfs_end_transaction(h, root); |
233 | return ERR_PTR(ret); | 240 | return ERR_PTR(ret); |
@@ -327,7 +334,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
327 | goto out_unlock; /* nothing committing|committed */ | 334 | goto out_unlock; /* nothing committing|committed */ |
328 | } | 335 | } |
329 | 336 | ||
330 | cur_trans->use_count++; | 337 | atomic_inc(&cur_trans->use_count); |
331 | mutex_unlock(&root->fs_info->trans_mutex); | 338 | mutex_unlock(&root->fs_info->trans_mutex); |
332 | 339 | ||
333 | wait_for_commit(root, cur_trans); | 340 | wait_for_commit(root, cur_trans); |
@@ -457,18 +464,14 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
457 | wake_up_process(info->transaction_kthread); | 464 | wake_up_process(info->transaction_kthread); |
458 | } | 465 | } |
459 | 466 | ||
460 | if (lock) | ||
461 | mutex_lock(&info->trans_mutex); | ||
462 | WARN_ON(cur_trans != info->running_transaction); | 467 | WARN_ON(cur_trans != info->running_transaction); |
463 | WARN_ON(cur_trans->num_writers < 1); | 468 | WARN_ON(atomic_read(&cur_trans->num_writers) < 1); |
464 | cur_trans->num_writers--; | 469 | atomic_dec(&cur_trans->num_writers); |
465 | 470 | ||
466 | smp_mb(); | 471 | smp_mb(); |
467 | if (waitqueue_active(&cur_trans->writer_wait)) | 472 | if (waitqueue_active(&cur_trans->writer_wait)) |
468 | wake_up(&cur_trans->writer_wait); | 473 | wake_up(&cur_trans->writer_wait); |
469 | put_transaction(cur_trans); | 474 | put_transaction(cur_trans); |
470 | if (lock) | ||
471 | mutex_unlock(&info->trans_mutex); | ||
472 | 475 | ||
473 | if (current->journal_info == trans) | 476 | if (current->journal_info == trans) |
474 | current->journal_info = NULL; | 477 | current->journal_info = NULL; |
@@ -1178,7 +1181,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1178 | /* take transaction reference */ | 1181 | /* take transaction reference */ |
1179 | mutex_lock(&root->fs_info->trans_mutex); | 1182 | mutex_lock(&root->fs_info->trans_mutex); |
1180 | cur_trans = trans->transaction; | 1183 | cur_trans = trans->transaction; |
1181 | cur_trans->use_count++; | 1184 | atomic_inc(&cur_trans->use_count); |
1182 | mutex_unlock(&root->fs_info->trans_mutex); | 1185 | mutex_unlock(&root->fs_info->trans_mutex); |
1183 | 1186 | ||
1184 | btrfs_end_transaction(trans, root); | 1187 | btrfs_end_transaction(trans, root); |
@@ -1237,7 +1240,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1237 | 1240 | ||
1238 | mutex_lock(&root->fs_info->trans_mutex); | 1241 | mutex_lock(&root->fs_info->trans_mutex); |
1239 | if (cur_trans->in_commit) { | 1242 | if (cur_trans->in_commit) { |
1240 | cur_trans->use_count++; | 1243 | atomic_inc(&cur_trans->use_count); |
1241 | mutex_unlock(&root->fs_info->trans_mutex); | 1244 | mutex_unlock(&root->fs_info->trans_mutex); |
1242 | btrfs_end_transaction(trans, root); | 1245 | btrfs_end_transaction(trans, root); |
1243 | 1246 | ||
@@ -1259,7 +1262,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1259 | prev_trans = list_entry(cur_trans->list.prev, | 1262 | prev_trans = list_entry(cur_trans->list.prev, |
1260 | struct btrfs_transaction, list); | 1263 | struct btrfs_transaction, list); |
1261 | if (!prev_trans->commit_done) { | 1264 | if (!prev_trans->commit_done) { |
1262 | prev_trans->use_count++; | 1265 | atomic_inc(&prev_trans->use_count); |
1263 | mutex_unlock(&root->fs_info->trans_mutex); | 1266 | mutex_unlock(&root->fs_info->trans_mutex); |
1264 | 1267 | ||
1265 | wait_for_commit(root, prev_trans); | 1268 | wait_for_commit(root, prev_trans); |
@@ -1300,14 +1303,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1300 | TASK_UNINTERRUPTIBLE); | 1303 | TASK_UNINTERRUPTIBLE); |
1301 | 1304 | ||
1302 | smp_mb(); | 1305 | smp_mb(); |
1303 | if (cur_trans->num_writers > 1) | 1306 | if (atomic_read(&cur_trans->num_writers) > 1) |
1304 | schedule_timeout(MAX_SCHEDULE_TIMEOUT); | 1307 | schedule_timeout(MAX_SCHEDULE_TIMEOUT); |
1305 | else if (should_grow) | 1308 | else if (should_grow) |
1306 | schedule_timeout(1); | 1309 | schedule_timeout(1); |
1307 | 1310 | ||
1308 | mutex_lock(&root->fs_info->trans_mutex); | 1311 | mutex_lock(&root->fs_info->trans_mutex); |
1309 | finish_wait(&cur_trans->writer_wait, &wait); | 1312 | finish_wait(&cur_trans->writer_wait, &wait); |
1310 | } while (cur_trans->num_writers > 1 || | 1313 | } while (atomic_read(&cur_trans->num_writers) > 1 || |
1311 | (should_grow && cur_trans->num_joined != joined)); | 1314 | (should_grow && cur_trans->num_joined != joined)); |
1312 | 1315 | ||
1313 | ret = create_pending_snapshots(trans, root->fs_info); | 1316 | ret = create_pending_snapshots(trans, root->fs_info); |
@@ -1394,6 +1397,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1394 | 1397 | ||
1395 | wake_up(&cur_trans->commit_wait); | 1398 | wake_up(&cur_trans->commit_wait); |
1396 | 1399 | ||
1400 | list_del_init(&cur_trans->list); | ||
1397 | put_transaction(cur_trans); | 1401 | put_transaction(cur_trans); |
1398 | put_transaction(cur_trans); | 1402 | put_transaction(cur_trans); |
1399 | 1403 | ||
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 229a594cacd5..e441acc6c584 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -27,11 +27,11 @@ struct btrfs_transaction { | |||
27 | * total writers in this transaction, it must be zero before the | 27 | * total writers in this transaction, it must be zero before the |
28 | * transaction can end | 28 | * transaction can end |
29 | */ | 29 | */ |
30 | unsigned long num_writers; | 30 | atomic_t num_writers; |
31 | 31 | ||
32 | unsigned long num_joined; | 32 | unsigned long num_joined; |
33 | int in_commit; | 33 | int in_commit; |
34 | int use_count; | 34 | atomic_t use_count; |
35 | int commit_done; | 35 | int commit_done; |
36 | int blocked; | 36 | int blocked; |
37 | struct list_head list; | 37 | struct list_head list; |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index a5303b871b13..cfd660550ded 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -180,11 +180,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
180 | struct btrfs_path *path; | 180 | struct btrfs_path *path; |
181 | struct extent_buffer *leaf; | 181 | struct extent_buffer *leaf; |
182 | struct btrfs_dir_item *di; | 182 | struct btrfs_dir_item *di; |
183 | int ret = 0, slot, advance; | 183 | int ret = 0, slot; |
184 | size_t total_size = 0, size_left = size; | 184 | size_t total_size = 0, size_left = size; |
185 | unsigned long name_ptr; | 185 | unsigned long name_ptr; |
186 | size_t name_len; | 186 | size_t name_len; |
187 | u32 nritems; | ||
188 | 187 | ||
189 | /* | 188 | /* |
190 | * ok we want all objects associated with this id. | 189 | * ok we want all objects associated with this id. |
@@ -204,34 +203,24 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
204 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 203 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
205 | if (ret < 0) | 204 | if (ret < 0) |
206 | goto err; | 205 | goto err; |
207 | advance = 0; | 206 | |
208 | while (1) { | 207 | while (1) { |
209 | leaf = path->nodes[0]; | 208 | leaf = path->nodes[0]; |
210 | nritems = btrfs_header_nritems(leaf); | ||
211 | slot = path->slots[0]; | 209 | slot = path->slots[0]; |
212 | 210 | ||
213 | /* this is where we start walking through the path */ | 211 | /* this is where we start walking through the path */ |
214 | if (advance || slot >= nritems) { | 212 | if (slot >= btrfs_header_nritems(leaf)) { |
215 | /* | 213 | /* |
216 | * if we've reached the last slot in this leaf we need | 214 | * if we've reached the last slot in this leaf we need |
217 | * to go to the next leaf and reset everything | 215 | * to go to the next leaf and reset everything |
218 | */ | 216 | */ |
219 | if (slot >= nritems-1) { | 217 | ret = btrfs_next_leaf(root, path); |
220 | ret = btrfs_next_leaf(root, path); | 218 | if (ret < 0) |
221 | if (ret) | 219 | goto err; |
222 | break; | 220 | else if (ret > 0) |
223 | leaf = path->nodes[0]; | 221 | break; |
224 | nritems = btrfs_header_nritems(leaf); | 222 | continue; |
225 | slot = path->slots[0]; | ||
226 | } else { | ||
227 | /* | ||
228 | * just walking through the slots on this leaf | ||
229 | */ | ||
230 | slot++; | ||
231 | path->slots[0]++; | ||
232 | } | ||
233 | } | 223 | } |
234 | advance = 1; | ||
235 | 224 | ||
236 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 225 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
237 | 226 | ||
@@ -250,7 +239,7 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
250 | 239 | ||
251 | /* we are just looking for how big our buffer needs to be */ | 240 | /* we are just looking for how big our buffer needs to be */ |
252 | if (!size) | 241 | if (!size) |
253 | continue; | 242 | goto next; |
254 | 243 | ||
255 | if (!buffer || (name_len + 1) > size_left) { | 244 | if (!buffer || (name_len + 1) > size_left) { |
256 | ret = -ERANGE; | 245 | ret = -ERANGE; |
@@ -263,6 +252,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
263 | 252 | ||
264 | size_left -= name_len + 1; | 253 | size_left -= name_len + 1; |
265 | buffer += name_len + 1; | 254 | buffer += name_len + 1; |
255 | next: | ||
256 | path->slots[0]++; | ||
266 | } | 257 | } |
267 | ret = total_size; | 258 | ret = total_size; |
268 | 259 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index ad25c4cec7d5..129a35730994 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2131,7 +2131,7 @@ EXPORT_SYMBOL(d_rehash); | |||
2131 | */ | 2131 | */ |
2132 | void dentry_update_name_case(struct dentry *dentry, struct qstr *name) | 2132 | void dentry_update_name_case(struct dentry *dentry, struct qstr *name) |
2133 | { | 2133 | { |
2134 | BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); | 2134 | BUG_ON(!mutex_is_locked(&dentry->d_parent->d_inode->i_mutex)); |
2135 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ | 2135 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ |
2136 | 2136 | ||
2137 | spin_lock(&dentry->d_lock); | 2137 | spin_lock(&dentry->d_lock); |
diff --git a/fs/fhandle.c b/fs/fhandle.c index bf93ad2bee07..6b088641f5bf 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/exportfs.h> | 7 | #include <linux/exportfs.h> |
8 | #include <linux/fs_struct.h> | 8 | #include <linux/fs_struct.h> |
9 | #include <linux/fsnotify.h> | 9 | #include <linux/fsnotify.h> |
10 | #include <linux/personality.h> | ||
10 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
11 | #include "internal.h" | 12 | #include "internal.h" |
12 | 13 | ||
diff --git a/fs/filesystems.c b/fs/filesystems.c index 751d6b255a12..0845f84f2a5f 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c | |||
@@ -110,14 +110,13 @@ int unregister_filesystem(struct file_system_type * fs) | |||
110 | *tmp = fs->next; | 110 | *tmp = fs->next; |
111 | fs->next = NULL; | 111 | fs->next = NULL; |
112 | write_unlock(&file_systems_lock); | 112 | write_unlock(&file_systems_lock); |
113 | synchronize_rcu(); | ||
113 | return 0; | 114 | return 0; |
114 | } | 115 | } |
115 | tmp = &(*tmp)->next; | 116 | tmp = &(*tmp)->next; |
116 | } | 117 | } |
117 | write_unlock(&file_systems_lock); | 118 | write_unlock(&file_systems_lock); |
118 | 119 | ||
119 | synchronize_rcu(); | ||
120 | |||
121 | return -EINVAL; | 120 | return -EINVAL; |
122 | } | 121 | } |
123 | 122 | ||
diff --git a/fs/namei.c b/fs/namei.c index e6cd6113872c..54fc993e3027 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -697,6 +697,7 @@ static __always_inline void set_root_rcu(struct nameidata *nd) | |||
697 | do { | 697 | do { |
698 | seq = read_seqcount_begin(&fs->seq); | 698 | seq = read_seqcount_begin(&fs->seq); |
699 | nd->root = fs->root; | 699 | nd->root = fs->root; |
700 | nd->seq = __read_seqcount_begin(&nd->root.dentry->d_seq); | ||
700 | } while (read_seqcount_retry(&fs->seq, seq)); | 701 | } while (read_seqcount_retry(&fs->seq, seq)); |
701 | } | 702 | } |
702 | } | 703 | } |
diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c index b10e3540d5b7..ce4f62440425 100644 --- a/fs/partitions/ldm.c +++ b/fs/partitions/ldm.c | |||
@@ -1299,6 +1299,11 @@ static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags) | |||
1299 | 1299 | ||
1300 | BUG_ON (!data || !frags); | 1300 | BUG_ON (!data || !frags); |
1301 | 1301 | ||
1302 | if (size < 2 * VBLK_SIZE_HEAD) { | ||
1303 | ldm_error("Value of size is to small."); | ||
1304 | return false; | ||
1305 | } | ||
1306 | |||
1302 | group = get_unaligned_be32(data + 0x08); | 1307 | group = get_unaligned_be32(data + 0x08); |
1303 | rec = get_unaligned_be16(data + 0x0C); | 1308 | rec = get_unaligned_be16(data + 0x0C); |
1304 | num = get_unaligned_be16(data + 0x0E); | 1309 | num = get_unaligned_be16(data + 0x0E); |
@@ -1306,6 +1311,10 @@ static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags) | |||
1306 | ldm_error ("A VBLK claims to have %d parts.", num); | 1311 | ldm_error ("A VBLK claims to have %d parts.", num); |
1307 | return false; | 1312 | return false; |
1308 | } | 1313 | } |
1314 | if (rec >= num) { | ||
1315 | ldm_error("REC value (%d) exceeds NUM value (%d)", rec, num); | ||
1316 | return false; | ||
1317 | } | ||
1309 | 1318 | ||
1310 | list_for_each (item, frags) { | 1319 | list_for_each (item, frags) { |
1311 | f = list_entry (item, struct frag, list); | 1320 | f = list_entry (item, struct frag, list); |
@@ -1334,10 +1343,9 @@ found: | |||
1334 | 1343 | ||
1335 | f->map |= (1 << rec); | 1344 | f->map |= (1 << rec); |
1336 | 1345 | ||
1337 | if (num > 0) { | 1346 | data += VBLK_SIZE_HEAD; |
1338 | data += VBLK_SIZE_HEAD; | 1347 | size -= VBLK_SIZE_HEAD; |
1339 | size -= VBLK_SIZE_HEAD; | 1348 | |
1340 | } | ||
1341 | memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size); | 1349 | memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size); |
1342 | 1350 | ||
1343 | return true; | 1351 | return true; |
diff --git a/fs/proc/base.c b/fs/proc/base.c index dd6628d3ba42..dfa532730e55 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -3124,11 +3124,16 @@ static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldi | |||
3124 | /* for the /proc/ directory itself, after non-process stuff has been done */ | 3124 | /* for the /proc/ directory itself, after non-process stuff has been done */ |
3125 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | 3125 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) |
3126 | { | 3126 | { |
3127 | unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; | 3127 | unsigned int nr; |
3128 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); | 3128 | struct task_struct *reaper; |
3129 | struct tgid_iter iter; | 3129 | struct tgid_iter iter; |
3130 | struct pid_namespace *ns; | 3130 | struct pid_namespace *ns; |
3131 | 3131 | ||
3132 | if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET) | ||
3133 | goto out_no_task; | ||
3134 | nr = filp->f_pos - FIRST_PROCESS_ENTRY; | ||
3135 | |||
3136 | reaper = get_proc_task(filp->f_path.dentry->d_inode); | ||
3132 | if (!reaper) | 3137 | if (!reaper) |
3133 | goto out_no_task; | 3138 | goto out_no_task; |
3134 | 3139 | ||
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 9eead2c796b7..fbb0b478a346 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -112,6 +112,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
112 | SetPageDirty(page); | 112 | SetPageDirty(page); |
113 | 113 | ||
114 | unlock_page(page); | 114 | unlock_page(page); |
115 | put_page(page); | ||
115 | } | 116 | } |
116 | 117 | ||
117 | return 0; | 118 | return 0; |
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 919f0de29d8f..e6493cac193d 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
@@ -23,6 +23,12 @@ | |||
23 | #ifndef __UBIFS_DEBUG_H__ | 23 | #ifndef __UBIFS_DEBUG_H__ |
24 | #define __UBIFS_DEBUG_H__ | 24 | #define __UBIFS_DEBUG_H__ |
25 | 25 | ||
26 | /* Checking helper functions */ | ||
27 | typedef int (*dbg_leaf_callback)(struct ubifs_info *c, | ||
28 | struct ubifs_zbranch *zbr, void *priv); | ||
29 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, | ||
30 | struct ubifs_znode *znode, void *priv); | ||
31 | |||
26 | #ifdef CONFIG_UBIFS_FS_DEBUG | 32 | #ifdef CONFIG_UBIFS_FS_DEBUG |
27 | 33 | ||
28 | /** | 34 | /** |
@@ -270,11 +276,6 @@ void dbg_dump_tnc(struct ubifs_info *c); | |||
270 | void dbg_dump_index(struct ubifs_info *c); | 276 | void dbg_dump_index(struct ubifs_info *c); |
271 | void dbg_dump_lpt_lebs(const struct ubifs_info *c); | 277 | void dbg_dump_lpt_lebs(const struct ubifs_info *c); |
272 | 278 | ||
273 | /* Checking helper functions */ | ||
274 | typedef int (*dbg_leaf_callback)(struct ubifs_info *c, | ||
275 | struct ubifs_zbranch *zbr, void *priv); | ||
276 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, | ||
277 | struct ubifs_znode *znode, void *priv); | ||
278 | int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, | 279 | int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, |
279 | dbg_znode_callback znode_cb, void *priv); | 280 | dbg_znode_callback znode_cb, void *priv); |
280 | 281 | ||
@@ -295,7 +296,6 @@ int dbg_check_idx_size(struct ubifs_info *c, long long idx_size); | |||
295 | int dbg_check_filesystem(struct ubifs_info *c); | 296 | int dbg_check_filesystem(struct ubifs_info *c); |
296 | void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, | 297 | void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, |
297 | int add_pos); | 298 | int add_pos); |
298 | int dbg_check_lprops(struct ubifs_info *c); | ||
299 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, | 299 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, |
300 | int row, int col); | 300 | int row, int col); |
301 | int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, | 301 | int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, |
@@ -401,58 +401,94 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c); | |||
401 | #define DBGKEY(key) ((char *)(key)) | 401 | #define DBGKEY(key) ((char *)(key)) |
402 | #define DBGKEY1(key) ((char *)(key)) | 402 | #define DBGKEY1(key) ((char *)(key)) |
403 | 403 | ||
404 | #define ubifs_debugging_init(c) 0 | 404 | static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; } |
405 | #define ubifs_debugging_exit(c) ({}) | 405 | static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; } |
406 | 406 | static inline const char *dbg_ntype(int type) { return ""; } | |
407 | #define dbg_ntype(type) "" | 407 | static inline const char *dbg_cstate(int cmt_state) { return ""; } |
408 | #define dbg_cstate(cmt_state) "" | 408 | static inline const char *dbg_jhead(int jhead) { return ""; } |
409 | #define dbg_jhead(jhead) "" | 409 | static inline const char * |
410 | #define dbg_get_key_dump(c, key) ({}) | 410 | dbg_get_key_dump(const struct ubifs_info *c, |
411 | #define dbg_dump_inode(c, inode) ({}) | 411 | const union ubifs_key *key) { return ""; } |
412 | #define dbg_dump_node(c, node) ({}) | 412 | static inline void dbg_dump_inode(const struct ubifs_info *c, |
413 | #define dbg_dump_lpt_node(c, node, lnum, offs) ({}) | 413 | const struct inode *inode) { return; } |
414 | #define dbg_dump_budget_req(req) ({}) | 414 | static inline void dbg_dump_node(const struct ubifs_info *c, |
415 | #define dbg_dump_lstats(lst) ({}) | 415 | const void *node) { return; } |
416 | #define dbg_dump_budg(c) ({}) | 416 | static inline void dbg_dump_lpt_node(const struct ubifs_info *c, |
417 | #define dbg_dump_lprop(c, lp) ({}) | 417 | void *node, int lnum, |
418 | #define dbg_dump_lprops(c) ({}) | 418 | int offs) { return; } |
419 | #define dbg_dump_lpt_info(c) ({}) | 419 | static inline void |
420 | #define dbg_dump_leb(c, lnum) ({}) | 420 | dbg_dump_budget_req(const struct ubifs_budget_req *req) { return; } |
421 | #define dbg_dump_znode(c, znode) ({}) | 421 | static inline void |
422 | #define dbg_dump_heap(c, heap, cat) ({}) | 422 | dbg_dump_lstats(const struct ubifs_lp_stats *lst) { return; } |
423 | #define dbg_dump_pnode(c, pnode, parent, iip) ({}) | 423 | static inline void dbg_dump_budg(struct ubifs_info *c) { return; } |
424 | #define dbg_dump_tnc(c) ({}) | 424 | static inline void dbg_dump_lprop(const struct ubifs_info *c, |
425 | #define dbg_dump_index(c) ({}) | 425 | const struct ubifs_lprops *lp) { return; } |
426 | #define dbg_dump_lpt_lebs(c) ({}) | 426 | static inline void dbg_dump_lprops(struct ubifs_info *c) { return; } |
427 | 427 | static inline void dbg_dump_lpt_info(struct ubifs_info *c) { return; } | |
428 | #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 | 428 | static inline void dbg_dump_leb(const struct ubifs_info *c, |
429 | #define dbg_old_index_check_init(c, zroot) 0 | 429 | int lnum) { return; } |
430 | #define dbg_save_space_info(c) ({}) | 430 | static inline void |
431 | #define dbg_check_space_info(c) 0 | 431 | dbg_dump_znode(const struct ubifs_info *c, |
432 | #define dbg_check_old_index(c, zroot) 0 | 432 | const struct ubifs_znode *znode) { return; } |
433 | #define dbg_check_cats(c) 0 | 433 | static inline void dbg_dump_heap(struct ubifs_info *c, |
434 | #define dbg_check_ltab(c) 0 | 434 | struct ubifs_lpt_heap *heap, |
435 | #define dbg_chk_lpt_free_spc(c) 0 | 435 | int cat) { return; } |
436 | #define dbg_chk_lpt_sz(c, action, len) 0 | 436 | static inline void dbg_dump_pnode(struct ubifs_info *c, |
437 | #define dbg_check_synced_i_size(inode) 0 | 437 | struct ubifs_pnode *pnode, |
438 | #define dbg_check_dir_size(c, dir) 0 | 438 | struct ubifs_nnode *parent, |
439 | #define dbg_check_tnc(c, x) 0 | 439 | int iip) { return; } |
440 | #define dbg_check_idx_size(c, idx_size) 0 | 440 | static inline void dbg_dump_tnc(struct ubifs_info *c) { return; } |
441 | #define dbg_check_filesystem(c) 0 | 441 | static inline void dbg_dump_index(struct ubifs_info *c) { return; } |
442 | #define dbg_check_heap(c, heap, cat, add_pos) ({}) | 442 | static inline void dbg_dump_lpt_lebs(const struct ubifs_info *c) { return; } |
443 | #define dbg_check_lprops(c) 0 | 443 | |
444 | #define dbg_check_lpt_nodes(c, cnode, row, col) 0 | 444 | static inline int dbg_walk_index(struct ubifs_info *c, |
445 | #define dbg_check_inode_size(c, inode, size) 0 | 445 | dbg_leaf_callback leaf_cb, |
446 | #define dbg_check_data_nodes_order(c, head) 0 | 446 | dbg_znode_callback znode_cb, |
447 | #define dbg_check_nondata_nodes_order(c, head) 0 | 447 | void *priv) { return 0; } |
448 | #define dbg_force_in_the_gaps_enabled 0 | 448 | static inline void dbg_save_space_info(struct ubifs_info *c) { return; } |
449 | #define dbg_force_in_the_gaps() 0 | 449 | static inline int dbg_check_space_info(struct ubifs_info *c) { return 0; } |
450 | #define dbg_failure_mode 0 | 450 | static inline int dbg_check_lprops(struct ubifs_info *c) { return 0; } |
451 | 451 | static inline int | |
452 | #define dbg_debugfs_init() 0 | 452 | dbg_old_index_check_init(struct ubifs_info *c, |
453 | #define dbg_debugfs_exit() | 453 | struct ubifs_zbranch *zroot) { return 0; } |
454 | #define dbg_debugfs_init_fs(c) 0 | 454 | static inline int |
455 | #define dbg_debugfs_exit_fs(c) 0 | 455 | dbg_check_old_index(struct ubifs_info *c, |
456 | struct ubifs_zbranch *zroot) { return 0; } | ||
457 | static inline int dbg_check_cats(struct ubifs_info *c) { return 0; } | ||
458 | static inline int dbg_check_ltab(struct ubifs_info *c) { return 0; } | ||
459 | static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; } | ||
460 | static inline int dbg_chk_lpt_sz(struct ubifs_info *c, | ||
461 | int action, int len) { return 0; } | ||
462 | static inline int dbg_check_synced_i_size(struct inode *inode) { return 0; } | ||
463 | static inline int dbg_check_dir_size(struct ubifs_info *c, | ||
464 | const struct inode *dir) { return 0; } | ||
465 | static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; } | ||
466 | static inline int dbg_check_idx_size(struct ubifs_info *c, | ||
467 | long long idx_size) { return 0; } | ||
468 | static inline int dbg_check_filesystem(struct ubifs_info *c) { return 0; } | ||
469 | static inline void dbg_check_heap(struct ubifs_info *c, | ||
470 | struct ubifs_lpt_heap *heap, | ||
471 | int cat, int add_pos) { return; } | ||
472 | static inline int dbg_check_lpt_nodes(struct ubifs_info *c, | ||
473 | struct ubifs_cnode *cnode, int row, int col) { return 0; } | ||
474 | static inline int dbg_check_inode_size(struct ubifs_info *c, | ||
475 | const struct inode *inode, | ||
476 | loff_t size) { return 0; } | ||
477 | static inline int | ||
478 | dbg_check_data_nodes_order(struct ubifs_info *c, | ||
479 | struct list_head *head) { return 0; } | ||
480 | static inline int | ||
481 | dbg_check_nondata_nodes_order(struct ubifs_info *c, | ||
482 | struct list_head *head) { return 0; } | ||
483 | |||
484 | static inline int dbg_force_in_the_gaps(void) { return 0; } | ||
485 | #define dbg_force_in_the_gaps_enabled 0 | ||
486 | #define dbg_failure_mode 0 | ||
487 | |||
488 | static inline int dbg_debugfs_init(void) { return 0; } | ||
489 | static inline void dbg_debugfs_exit(void) { return; } | ||
490 | static inline int dbg_debugfs_init_fs(struct ubifs_info *c) { return 0; } | ||
491 | static inline int dbg_debugfs_exit_fs(struct ubifs_info *c) { return 0; } | ||
456 | 492 | ||
457 | #endif /* !CONFIG_UBIFS_FS_DEBUG */ | 493 | #endif /* !CONFIG_UBIFS_FS_DEBUG */ |
458 | #endif /* !__UBIFS_DEBUG_H__ */ | 494 | #endif /* !__UBIFS_DEBUG_H__ */ |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 28be1e6a65e8..b286db79c686 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -1312,6 +1312,9 @@ int ubifs_fsync(struct file *file, int datasync) | |||
1312 | 1312 | ||
1313 | dbg_gen("syncing inode %lu", inode->i_ino); | 1313 | dbg_gen("syncing inode %lu", inode->i_ino); |
1314 | 1314 | ||
1315 | if (inode->i_sb->s_flags & MS_RDONLY) | ||
1316 | return 0; | ||
1317 | |||
1315 | /* | 1318 | /* |
1316 | * VFS has already synchronized dirty pages for this inode. Synchronize | 1319 | * VFS has already synchronized dirty pages for this inode. Synchronize |
1317 | * the inode unless this is a 'datasync()' call. | 1320 | * the inode unless this is a 'datasync()' call. |