diff options
Diffstat (limited to 'fs')
117 files changed, 1542 insertions, 1211 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 20c106f24927..1b0b19550015 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -584,11 +584,11 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | |||
584 | 584 | ||
585 | success: | 585 | success: |
586 | d_add(dentry, inode); | 586 | d_add(dentry, inode); |
587 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }", | 587 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }", |
588 | fid.vnode, | 588 | fid.vnode, |
589 | fid.unique, | 589 | fid.unique, |
590 | dentry->d_inode->i_ino, | 590 | dentry->d_inode->i_ino, |
591 | (unsigned long long)dentry->d_inode->i_version); | 591 | dentry->d_inode->i_generation); |
592 | 592 | ||
593 | return NULL; | 593 | return NULL; |
594 | } | 594 | } |
@@ -671,10 +671,10 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
671 | * been deleted and replaced, and the original vnode ID has | 671 | * been deleted and replaced, and the original vnode ID has |
672 | * been reused */ | 672 | * been reused */ |
673 | if (fid.unique != vnode->fid.unique) { | 673 | if (fid.unique != vnode->fid.unique) { |
674 | _debug("%s: file deleted (uq %u -> %u I:%llu)", | 674 | _debug("%s: file deleted (uq %u -> %u I:%u)", |
675 | dentry->d_name.name, fid.unique, | 675 | dentry->d_name.name, fid.unique, |
676 | vnode->fid.unique, | 676 | vnode->fid.unique, |
677 | (unsigned long long)dentry->d_inode->i_version); | 677 | dentry->d_inode->i_generation); |
678 | spin_lock(&vnode->lock); | 678 | spin_lock(&vnode->lock); |
679 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | 679 | set_bit(AFS_VNODE_DELETED, &vnode->flags); |
680 | spin_unlock(&vnode->lock); | 680 | spin_unlock(&vnode->lock); |
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 4bd0218473a9..346e3289abd7 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -89,7 +89,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
89 | i_size_write(&vnode->vfs_inode, size); | 89 | i_size_write(&vnode->vfs_inode, size); |
90 | vnode->vfs_inode.i_uid = status->owner; | 90 | vnode->vfs_inode.i_uid = status->owner; |
91 | vnode->vfs_inode.i_gid = status->group; | 91 | vnode->vfs_inode.i_gid = status->group; |
92 | vnode->vfs_inode.i_version = vnode->fid.unique; | 92 | vnode->vfs_inode.i_generation = vnode->fid.unique; |
93 | vnode->vfs_inode.i_nlink = status->nlink; | 93 | vnode->vfs_inode.i_nlink = status->nlink; |
94 | 94 | ||
95 | mode = vnode->vfs_inode.i_mode; | 95 | mode = vnode->vfs_inode.i_mode; |
@@ -102,6 +102,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
102 | vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server; | 102 | vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server; |
103 | vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; | 103 | vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; |
104 | vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; | 104 | vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; |
105 | vnode->vfs_inode.i_version = data_version; | ||
105 | } | 106 | } |
106 | 107 | ||
107 | expected_version = status->data_version; | 108 | expected_version = status->data_version; |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index db66c5201474..0fdab6e03d87 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -75,7 +75,8 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
75 | inode->i_ctime.tv_nsec = 0; | 75 | inode->i_ctime.tv_nsec = 0; |
76 | inode->i_atime = inode->i_mtime = inode->i_ctime; | 76 | inode->i_atime = inode->i_mtime = inode->i_ctime; |
77 | inode->i_blocks = 0; | 77 | inode->i_blocks = 0; |
78 | inode->i_version = vnode->fid.unique; | 78 | inode->i_generation = vnode->fid.unique; |
79 | inode->i_version = vnode->status.data_version; | ||
79 | inode->i_mapping->a_ops = &afs_fs_aops; | 80 | inode->i_mapping->a_ops = &afs_fs_aops; |
80 | 81 | ||
81 | /* check to see whether a symbolic link is really a mountpoint */ | 82 | /* check to see whether a symbolic link is really a mountpoint */ |
@@ -100,7 +101,7 @@ static int afs_iget5_test(struct inode *inode, void *opaque) | |||
100 | struct afs_iget_data *data = opaque; | 101 | struct afs_iget_data *data = opaque; |
101 | 102 | ||
102 | return inode->i_ino == data->fid.vnode && | 103 | return inode->i_ino == data->fid.vnode && |
103 | inode->i_version == data->fid.unique; | 104 | inode->i_generation == data->fid.unique; |
104 | } | 105 | } |
105 | 106 | ||
106 | /* | 107 | /* |
@@ -122,7 +123,7 @@ static int afs_iget5_set(struct inode *inode, void *opaque) | |||
122 | struct afs_vnode *vnode = AFS_FS_I(inode); | 123 | struct afs_vnode *vnode = AFS_FS_I(inode); |
123 | 124 | ||
124 | inode->i_ino = data->fid.vnode; | 125 | inode->i_ino = data->fid.vnode; |
125 | inode->i_version = data->fid.unique; | 126 | inode->i_generation = data->fid.unique; |
126 | vnode->fid = data->fid; | 127 | vnode->fid = data->fid; |
127 | vnode->volume = data->volume; | 128 | vnode->volume = data->volume; |
128 | 129 | ||
@@ -380,8 +381,7 @@ int afs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
380 | 381 | ||
381 | inode = dentry->d_inode; | 382 | inode = dentry->d_inode; |
382 | 383 | ||
383 | _enter("{ ino=%lu v=%llu }", inode->i_ino, | 384 | _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation); |
384 | (unsigned long long)inode->i_version); | ||
385 | 385 | ||
386 | generic_fillattr(inode, stat); | 386 | generic_fillattr(inode, stat); |
387 | return 0; | 387 | return 0; |
diff --git a/fs/afs/super.c b/fs/afs/super.c index fb240e8766d6..356dcf0929e8 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -31,8 +31,8 @@ | |||
31 | static void afs_i_init_once(void *foo); | 31 | static void afs_i_init_once(void *foo); |
32 | static struct dentry *afs_mount(struct file_system_type *fs_type, | 32 | static struct dentry *afs_mount(struct file_system_type *fs_type, |
33 | int flags, const char *dev_name, void *data); | 33 | int flags, const char *dev_name, void *data); |
34 | static void afs_kill_super(struct super_block *sb); | ||
34 | static struct inode *afs_alloc_inode(struct super_block *sb); | 35 | static struct inode *afs_alloc_inode(struct super_block *sb); |
35 | static void afs_put_super(struct super_block *sb); | ||
36 | static void afs_destroy_inode(struct inode *inode); | 36 | static void afs_destroy_inode(struct inode *inode); |
37 | static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); | 37 | static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); |
38 | 38 | ||
@@ -40,7 +40,7 @@ struct file_system_type afs_fs_type = { | |||
40 | .owner = THIS_MODULE, | 40 | .owner = THIS_MODULE, |
41 | .name = "afs", | 41 | .name = "afs", |
42 | .mount = afs_mount, | 42 | .mount = afs_mount, |
43 | .kill_sb = kill_anon_super, | 43 | .kill_sb = afs_kill_super, |
44 | .fs_flags = 0, | 44 | .fs_flags = 0, |
45 | }; | 45 | }; |
46 | 46 | ||
@@ -50,7 +50,6 @@ static const struct super_operations afs_super_ops = { | |||
50 | .drop_inode = afs_drop_inode, | 50 | .drop_inode = afs_drop_inode, |
51 | .destroy_inode = afs_destroy_inode, | 51 | .destroy_inode = afs_destroy_inode, |
52 | .evict_inode = afs_evict_inode, | 52 | .evict_inode = afs_evict_inode, |
53 | .put_super = afs_put_super, | ||
54 | .show_options = generic_show_options, | 53 | .show_options = generic_show_options, |
55 | }; | 54 | }; |
56 | 55 | ||
@@ -282,19 +281,25 @@ static int afs_parse_device_name(struct afs_mount_params *params, | |||
282 | */ | 281 | */ |
283 | static int afs_test_super(struct super_block *sb, void *data) | 282 | static int afs_test_super(struct super_block *sb, void *data) |
284 | { | 283 | { |
285 | struct afs_mount_params *params = data; | 284 | struct afs_super_info *as1 = data; |
286 | struct afs_super_info *as = sb->s_fs_info; | 285 | struct afs_super_info *as = sb->s_fs_info; |
287 | 286 | ||
288 | return as->volume == params->volume; | 287 | return as->volume == as1->volume; |
288 | } | ||
289 | |||
290 | static int afs_set_super(struct super_block *sb, void *data) | ||
291 | { | ||
292 | sb->s_fs_info = data; | ||
293 | return set_anon_super(sb, NULL); | ||
289 | } | 294 | } |
290 | 295 | ||
291 | /* | 296 | /* |
292 | * fill in the superblock | 297 | * fill in the superblock |
293 | */ | 298 | */ |
294 | static int afs_fill_super(struct super_block *sb, void *data) | 299 | static int afs_fill_super(struct super_block *sb, |
300 | struct afs_mount_params *params) | ||
295 | { | 301 | { |
296 | struct afs_mount_params *params = data; | 302 | struct afs_super_info *as = sb->s_fs_info; |
297 | struct afs_super_info *as = NULL; | ||
298 | struct afs_fid fid; | 303 | struct afs_fid fid; |
299 | struct dentry *root = NULL; | 304 | struct dentry *root = NULL; |
300 | struct inode *inode = NULL; | 305 | struct inode *inode = NULL; |
@@ -302,23 +307,13 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
302 | 307 | ||
303 | _enter(""); | 308 | _enter(""); |
304 | 309 | ||
305 | /* allocate a superblock info record */ | ||
306 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); | ||
307 | if (!as) { | ||
308 | _leave(" = -ENOMEM"); | ||
309 | return -ENOMEM; | ||
310 | } | ||
311 | |||
312 | afs_get_volume(params->volume); | ||
313 | as->volume = params->volume; | ||
314 | |||
315 | /* fill in the superblock */ | 310 | /* fill in the superblock */ |
316 | sb->s_blocksize = PAGE_CACHE_SIZE; | 311 | sb->s_blocksize = PAGE_CACHE_SIZE; |
317 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 312 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
318 | sb->s_magic = AFS_FS_MAGIC; | 313 | sb->s_magic = AFS_FS_MAGIC; |
319 | sb->s_op = &afs_super_ops; | 314 | sb->s_op = &afs_super_ops; |
320 | sb->s_fs_info = as; | ||
321 | sb->s_bdi = &as->volume->bdi; | 315 | sb->s_bdi = &as->volume->bdi; |
316 | strlcpy(sb->s_id, as->volume->vlocation->vldb.name, sizeof(sb->s_id)); | ||
322 | 317 | ||
323 | /* allocate the root inode and dentry */ | 318 | /* allocate the root inode and dentry */ |
324 | fid.vid = as->volume->vid; | 319 | fid.vid = as->volume->vid; |
@@ -326,7 +321,7 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
326 | fid.unique = 1; | 321 | fid.unique = 1; |
327 | inode = afs_iget(sb, params->key, &fid, NULL, NULL); | 322 | inode = afs_iget(sb, params->key, &fid, NULL, NULL); |
328 | if (IS_ERR(inode)) | 323 | if (IS_ERR(inode)) |
329 | goto error_inode; | 324 | return PTR_ERR(inode); |
330 | 325 | ||
331 | if (params->autocell) | 326 | if (params->autocell) |
332 | set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags); | 327 | set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags); |
@@ -342,16 +337,8 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
342 | _leave(" = 0"); | 337 | _leave(" = 0"); |
343 | return 0; | 338 | return 0; |
344 | 339 | ||
345 | error_inode: | ||
346 | ret = PTR_ERR(inode); | ||
347 | inode = NULL; | ||
348 | error: | 340 | error: |
349 | iput(inode); | 341 | iput(inode); |
350 | afs_put_volume(as->volume); | ||
351 | kfree(as); | ||
352 | |||
353 | sb->s_fs_info = NULL; | ||
354 | |||
355 | _leave(" = %d", ret); | 342 | _leave(" = %d", ret); |
356 | return ret; | 343 | return ret; |
357 | } | 344 | } |
@@ -367,6 +354,7 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
367 | struct afs_volume *vol; | 354 | struct afs_volume *vol; |
368 | struct key *key; | 355 | struct key *key; |
369 | char *new_opts = kstrdup(options, GFP_KERNEL); | 356 | char *new_opts = kstrdup(options, GFP_KERNEL); |
357 | struct afs_super_info *as; | ||
370 | int ret; | 358 | int ret; |
371 | 359 | ||
372 | _enter(",,%s,%p", dev_name, options); | 360 | _enter(",,%s,%p", dev_name, options); |
@@ -399,12 +387,22 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
399 | ret = PTR_ERR(vol); | 387 | ret = PTR_ERR(vol); |
400 | goto error; | 388 | goto error; |
401 | } | 389 | } |
402 | params.volume = vol; | 390 | |
391 | /* allocate a superblock info record */ | ||
392 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); | ||
393 | if (!as) { | ||
394 | ret = -ENOMEM; | ||
395 | afs_put_volume(vol); | ||
396 | goto error; | ||
397 | } | ||
398 | as->volume = vol; | ||
403 | 399 | ||
404 | /* allocate a deviceless superblock */ | 400 | /* allocate a deviceless superblock */ |
405 | sb = sget(fs_type, afs_test_super, set_anon_super, ¶ms); | 401 | sb = sget(fs_type, afs_test_super, afs_set_super, as); |
406 | if (IS_ERR(sb)) { | 402 | if (IS_ERR(sb)) { |
407 | ret = PTR_ERR(sb); | 403 | ret = PTR_ERR(sb); |
404 | afs_put_volume(vol); | ||
405 | kfree(as); | ||
408 | goto error; | 406 | goto error; |
409 | } | 407 | } |
410 | 408 | ||
@@ -422,16 +420,16 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
422 | } else { | 420 | } else { |
423 | _debug("reuse"); | 421 | _debug("reuse"); |
424 | ASSERTCMP(sb->s_flags, &, MS_ACTIVE); | 422 | ASSERTCMP(sb->s_flags, &, MS_ACTIVE); |
423 | afs_put_volume(vol); | ||
424 | kfree(as); | ||
425 | } | 425 | } |
426 | 426 | ||
427 | afs_put_volume(params.volume); | ||
428 | afs_put_cell(params.cell); | 427 | afs_put_cell(params.cell); |
429 | kfree(new_opts); | 428 | kfree(new_opts); |
430 | _leave(" = 0 [%p]", sb); | 429 | _leave(" = 0 [%p]", sb); |
431 | return dget(sb->s_root); | 430 | return dget(sb->s_root); |
432 | 431 | ||
433 | error: | 432 | error: |
434 | afs_put_volume(params.volume); | ||
435 | afs_put_cell(params.cell); | 433 | afs_put_cell(params.cell); |
436 | key_put(params.key); | 434 | key_put(params.key); |
437 | kfree(new_opts); | 435 | kfree(new_opts); |
@@ -439,18 +437,12 @@ error: | |||
439 | return ERR_PTR(ret); | 437 | return ERR_PTR(ret); |
440 | } | 438 | } |
441 | 439 | ||
442 | /* | 440 | static void afs_kill_super(struct super_block *sb) |
443 | * finish the unmounting process on the superblock | ||
444 | */ | ||
445 | static void afs_put_super(struct super_block *sb) | ||
446 | { | 441 | { |
447 | struct afs_super_info *as = sb->s_fs_info; | 442 | struct afs_super_info *as = sb->s_fs_info; |
448 | 443 | kill_anon_super(sb); | |
449 | _enter(""); | ||
450 | |||
451 | afs_put_volume(as->volume); | 444 | afs_put_volume(as->volume); |
452 | 445 | kfree(as); | |
453 | _leave(""); | ||
454 | } | 446 | } |
455 | 447 | ||
456 | /* | 448 | /* |
diff --git a/fs/afs/write.c b/fs/afs/write.c index 789b3afb3423..b806285ff853 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
@@ -84,23 +84,21 @@ void afs_put_writeback(struct afs_writeback *wb) | |||
84 | * partly or wholly fill a page that's under preparation for writing | 84 | * partly or wholly fill a page that's under preparation for writing |
85 | */ | 85 | */ |
86 | static int afs_fill_page(struct afs_vnode *vnode, struct key *key, | 86 | static int afs_fill_page(struct afs_vnode *vnode, struct key *key, |
87 | loff_t pos, unsigned len, struct page *page) | 87 | loff_t pos, struct page *page) |
88 | { | 88 | { |
89 | loff_t i_size; | 89 | loff_t i_size; |
90 | unsigned eof; | ||
91 | int ret; | 90 | int ret; |
91 | int len; | ||
92 | 92 | ||
93 | _enter(",,%llu,%u", (unsigned long long)pos, len); | 93 | _enter(",,%llu", (unsigned long long)pos); |
94 | |||
95 | ASSERTCMP(len, <=, PAGE_CACHE_SIZE); | ||
96 | 94 | ||
97 | i_size = i_size_read(&vnode->vfs_inode); | 95 | i_size = i_size_read(&vnode->vfs_inode); |
98 | if (pos + len > i_size) | 96 | if (pos + PAGE_CACHE_SIZE > i_size) |
99 | eof = i_size; | 97 | len = i_size - pos; |
100 | else | 98 | else |
101 | eof = PAGE_CACHE_SIZE; | 99 | len = PAGE_CACHE_SIZE; |
102 | 100 | ||
103 | ret = afs_vnode_fetch_data(vnode, key, 0, eof, page); | 101 | ret = afs_vnode_fetch_data(vnode, key, pos, len, page); |
104 | if (ret < 0) { | 102 | if (ret < 0) { |
105 | if (ret == -ENOENT) { | 103 | if (ret == -ENOENT) { |
106 | _debug("got NOENT from server" | 104 | _debug("got NOENT from server" |
@@ -153,9 +151,8 @@ int afs_write_begin(struct file *file, struct address_space *mapping, | |||
153 | *pagep = page; | 151 | *pagep = page; |
154 | /* page won't leak in error case: it eventually gets cleaned off LRU */ | 152 | /* page won't leak in error case: it eventually gets cleaned off LRU */ |
155 | 153 | ||
156 | if (!PageUptodate(page)) { | 154 | if (!PageUptodate(page) && len != PAGE_CACHE_SIZE) { |
157 | _debug("not up to date"); | 155 | ret = afs_fill_page(vnode, key, index << PAGE_CACHE_SHIFT, page); |
158 | ret = afs_fill_page(vnode, key, pos, len, page); | ||
159 | if (ret < 0) { | 156 | if (ret < 0) { |
160 | kfree(candidate); | 157 | kfree(candidate); |
161 | _leave(" = %d [prep]", ret); | 158 | _leave(" = %d [prep]", ret); |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 9ad2369d9e35..bfcb18feb1df 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -231,9 +231,6 @@ static int bad_inode_readlink(struct dentry *dentry, char __user *buffer, | |||
231 | 231 | ||
232 | static int bad_inode_permission(struct inode *inode, int mask, unsigned int flags) | 232 | static int bad_inode_permission(struct inode *inode, int mask, unsigned int flags) |
233 | { | 233 | { |
234 | if (flags & IPERM_FLAG_RCU) | ||
235 | return -ECHILD; | ||
236 | |||
237 | return -EIO; | 234 | return -EIO; |
238 | } | 235 | } |
239 | 236 | ||
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 63039ed9576f..2bc5dc644b4c 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1864,6 +1864,7 @@ cleanup: | |||
1864 | kfree(psinfo); | 1864 | kfree(psinfo); |
1865 | kfree(notes); | 1865 | kfree(notes); |
1866 | kfree(fpu); | 1866 | kfree(fpu); |
1867 | kfree(shdr4extnum); | ||
1867 | #ifdef ELF_CORE_COPY_XFPREGS | 1868 | #ifdef ELF_CORE_COPY_XFPREGS |
1868 | kfree(xfpu); | 1869 | kfree(xfpu); |
1869 | #endif | 1870 | #endif |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 1a2421f908f0..610e8e0b04b8 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -762,7 +762,19 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, | |||
762 | if (!disk) | 762 | if (!disk) |
763 | return ERR_PTR(-ENXIO); | 763 | return ERR_PTR(-ENXIO); |
764 | 764 | ||
765 | whole = bdget_disk(disk, 0); | 765 | /* |
766 | * Normally, @bdev should equal what's returned from bdget_disk() | ||
767 | * if partno is 0; however, some drivers (floppy) use multiple | ||
768 | * bdev's for the same physical device and @bdev may be one of the | ||
769 | * aliases. Keep @bdev if partno is 0. This means claimer | ||
770 | * tracking is broken for those devices but it has always been that | ||
771 | * way. | ||
772 | */ | ||
773 | if (partno) | ||
774 | whole = bdget_disk(disk, 0); | ||
775 | else | ||
776 | whole = bdgrab(bdev); | ||
777 | |||
766 | module_put(disk->fops->owner); | 778 | module_put(disk->fops->owner); |
767 | put_disk(disk); | 779 | put_disk(disk); |
768 | if (!whole) | 780 | if (!whole) |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index d84089349c82..2e667868e0d2 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1228,6 +1228,7 @@ static void reada_for_search(struct btrfs_root *root, | |||
1228 | u32 nr; | 1228 | u32 nr; |
1229 | u32 blocksize; | 1229 | u32 blocksize; |
1230 | u32 nscan = 0; | 1230 | u32 nscan = 0; |
1231 | bool map = true; | ||
1231 | 1232 | ||
1232 | if (level != 1) | 1233 | if (level != 1) |
1233 | return; | 1234 | return; |
@@ -1249,8 +1250,11 @@ static void reada_for_search(struct btrfs_root *root, | |||
1249 | 1250 | ||
1250 | nritems = btrfs_header_nritems(node); | 1251 | nritems = btrfs_header_nritems(node); |
1251 | nr = slot; | 1252 | nr = slot; |
1253 | if (node->map_token || path->skip_locking) | ||
1254 | map = false; | ||
1255 | |||
1252 | while (1) { | 1256 | while (1) { |
1253 | if (!node->map_token) { | 1257 | if (map && !node->map_token) { |
1254 | unsigned long offset = btrfs_node_key_ptr_offset(nr); | 1258 | unsigned long offset = btrfs_node_key_ptr_offset(nr); |
1255 | map_private_extent_buffer(node, offset, | 1259 | map_private_extent_buffer(node, offset, |
1256 | sizeof(struct btrfs_key_ptr), | 1260 | sizeof(struct btrfs_key_ptr), |
@@ -1277,7 +1281,7 @@ static void reada_for_search(struct btrfs_root *root, | |||
1277 | if ((search <= target && target - search <= 65536) || | 1281 | if ((search <= target && target - search <= 65536) || |
1278 | (search > target && search - target <= 65536)) { | 1282 | (search > target && search - target <= 65536)) { |
1279 | gen = btrfs_node_ptr_generation(node, nr); | 1283 | gen = btrfs_node_ptr_generation(node, nr); |
1280 | if (node->map_token) { | 1284 | if (map && node->map_token) { |
1281 | unmap_extent_buffer(node, node->map_token, | 1285 | unmap_extent_buffer(node, node->map_token, |
1282 | KM_USER1); | 1286 | KM_USER1); |
1283 | node->map_token = NULL; | 1287 | node->map_token = NULL; |
@@ -1289,7 +1293,7 @@ static void reada_for_search(struct btrfs_root *root, | |||
1289 | if ((nread > 65536 || nscan > 32)) | 1293 | if ((nread > 65536 || nscan > 32)) |
1290 | break; | 1294 | break; |
1291 | } | 1295 | } |
1292 | if (node->map_token) { | 1296 | if (map && node->map_token) { |
1293 | unmap_extent_buffer(node, node->map_token, KM_USER1); | 1297 | unmap_extent_buffer(node, node->map_token, KM_USER1); |
1294 | node->map_token = NULL; | 1298 | node->map_token = NULL; |
1295 | } | 1299 | } |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 378b5b4443f3..3b859a3e6a0e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -19,7 +19,6 @@ | |||
19 | #ifndef __BTRFS_CTREE__ | 19 | #ifndef __BTRFS_CTREE__ |
20 | #define __BTRFS_CTREE__ | 20 | #define __BTRFS_CTREE__ |
21 | 21 | ||
22 | #include <linux/version.h> | ||
23 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
24 | #include <linux/highmem.h> | 23 | #include <linux/highmem.h> |
25 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
@@ -967,6 +966,12 @@ struct btrfs_fs_info { | |||
967 | struct srcu_struct subvol_srcu; | 966 | struct srcu_struct subvol_srcu; |
968 | 967 | ||
969 | spinlock_t trans_lock; | 968 | spinlock_t trans_lock; |
969 | /* | ||
970 | * the reloc mutex goes with the trans lock, it is taken | ||
971 | * during commit to protect us from the relocation code | ||
972 | */ | ||
973 | struct mutex reloc_mutex; | ||
974 | |||
970 | struct list_head trans_list; | 975 | struct list_head trans_list; |
971 | struct list_head hashers; | 976 | struct list_head hashers; |
972 | struct list_head dead_roots; | 977 | struct list_head dead_roots; |
@@ -1172,6 +1177,14 @@ struct btrfs_root { | |||
1172 | u32 type; | 1177 | u32 type; |
1173 | 1178 | ||
1174 | u64 highest_objectid; | 1179 | u64 highest_objectid; |
1180 | |||
1181 | /* btrfs_record_root_in_trans is a multi-step process, | ||
1182 | * and it can race with the balancing code. But the | ||
1183 | * race is very small, and only the first time the root | ||
1184 | * is added to each transaction. So in_trans_setup | ||
1185 | * is used to tell us when more checks are required | ||
1186 | */ | ||
1187 | unsigned long in_trans_setup; | ||
1175 | int ref_cows; | 1188 | int ref_cows; |
1176 | int track_dirty; | 1189 | int track_dirty; |
1177 | int in_radix; | 1190 | int in_radix; |
@@ -1181,7 +1194,6 @@ struct btrfs_root { | |||
1181 | struct btrfs_key defrag_max; | 1194 | struct btrfs_key defrag_max; |
1182 | int defrag_running; | 1195 | int defrag_running; |
1183 | char *name; | 1196 | char *name; |
1184 | int in_sysfs; | ||
1185 | 1197 | ||
1186 | /* the dirty list is only used by non-reference counted roots */ | 1198 | /* the dirty list is only used by non-reference counted roots */ |
1187 | struct list_head dirty_list; | 1199 | struct list_head dirty_list; |
@@ -1323,6 +1335,11 @@ struct btrfs_ioctl_defrag_range_args { | |||
1323 | */ | 1335 | */ |
1324 | #define BTRFS_STRING_ITEM_KEY 253 | 1336 | #define BTRFS_STRING_ITEM_KEY 253 |
1325 | 1337 | ||
1338 | /* | ||
1339 | * Flags for mount options. | ||
1340 | * | ||
1341 | * Note: don't forget to add new options to btrfs_show_options() | ||
1342 | */ | ||
1326 | #define BTRFS_MOUNT_NODATASUM (1 << 0) | 1343 | #define BTRFS_MOUNT_NODATASUM (1 << 0) |
1327 | #define BTRFS_MOUNT_NODATACOW (1 << 1) | 1344 | #define BTRFS_MOUNT_NODATACOW (1 << 1) |
1328 | #define BTRFS_MOUNT_NOBARRIER (1 << 2) | 1345 | #define BTRFS_MOUNT_NOBARRIER (1 << 2) |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 6462c29d2d37..98c68e658a9b 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -82,19 +82,16 @@ static inline struct btrfs_delayed_root *btrfs_get_delayed_root( | |||
82 | return root->fs_info->delayed_root; | 82 | return root->fs_info->delayed_root; |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( | 85 | static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode) |
86 | struct inode *inode) | ||
87 | { | 86 | { |
88 | struct btrfs_delayed_node *node; | ||
89 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); | 87 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); |
90 | struct btrfs_root *root = btrfs_inode->root; | 88 | struct btrfs_root *root = btrfs_inode->root; |
91 | u64 ino = btrfs_ino(inode); | 89 | u64 ino = btrfs_ino(inode); |
92 | int ret; | 90 | struct btrfs_delayed_node *node; |
93 | 91 | ||
94 | again: | ||
95 | node = ACCESS_ONCE(btrfs_inode->delayed_node); | 92 | node = ACCESS_ONCE(btrfs_inode->delayed_node); |
96 | if (node) { | 93 | if (node) { |
97 | atomic_inc(&node->refs); /* can be accessed */ | 94 | atomic_inc(&node->refs); |
98 | return node; | 95 | return node; |
99 | } | 96 | } |
100 | 97 | ||
@@ -102,8 +99,10 @@ again: | |||
102 | node = radix_tree_lookup(&root->delayed_nodes_tree, ino); | 99 | node = radix_tree_lookup(&root->delayed_nodes_tree, ino); |
103 | if (node) { | 100 | if (node) { |
104 | if (btrfs_inode->delayed_node) { | 101 | if (btrfs_inode->delayed_node) { |
102 | atomic_inc(&node->refs); /* can be accessed */ | ||
103 | BUG_ON(btrfs_inode->delayed_node != node); | ||
105 | spin_unlock(&root->inode_lock); | 104 | spin_unlock(&root->inode_lock); |
106 | goto again; | 105 | return node; |
107 | } | 106 | } |
108 | btrfs_inode->delayed_node = node; | 107 | btrfs_inode->delayed_node = node; |
109 | atomic_inc(&node->refs); /* can be accessed */ | 108 | atomic_inc(&node->refs); /* can be accessed */ |
@@ -113,6 +112,23 @@ again: | |||
113 | } | 112 | } |
114 | spin_unlock(&root->inode_lock); | 113 | spin_unlock(&root->inode_lock); |
115 | 114 | ||
115 | return NULL; | ||
116 | } | ||
117 | |||
118 | static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( | ||
119 | struct inode *inode) | ||
120 | { | ||
121 | struct btrfs_delayed_node *node; | ||
122 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); | ||
123 | struct btrfs_root *root = btrfs_inode->root; | ||
124 | u64 ino = btrfs_ino(inode); | ||
125 | int ret; | ||
126 | |||
127 | again: | ||
128 | node = btrfs_get_delayed_node(inode); | ||
129 | if (node) | ||
130 | return node; | ||
131 | |||
116 | node = kmem_cache_alloc(delayed_node_cache, GFP_NOFS); | 132 | node = kmem_cache_alloc(delayed_node_cache, GFP_NOFS); |
117 | if (!node) | 133 | if (!node) |
118 | return ERR_PTR(-ENOMEM); | 134 | return ERR_PTR(-ENOMEM); |
@@ -297,7 +313,6 @@ struct btrfs_delayed_item *btrfs_alloc_delayed_item(u32 data_len) | |||
297 | item->data_len = data_len; | 313 | item->data_len = data_len; |
298 | item->ins_or_del = 0; | 314 | item->ins_or_del = 0; |
299 | item->bytes_reserved = 0; | 315 | item->bytes_reserved = 0; |
300 | item->block_rsv = NULL; | ||
301 | item->delayed_node = NULL; | 316 | item->delayed_node = NULL; |
302 | atomic_set(&item->refs, 1); | 317 | atomic_set(&item->refs, 1); |
303 | } | 318 | } |
@@ -549,19 +564,6 @@ struct btrfs_delayed_item *__btrfs_next_delayed_item( | |||
549 | return next; | 564 | return next; |
550 | } | 565 | } |
551 | 566 | ||
552 | static inline struct btrfs_delayed_node *btrfs_get_delayed_node( | ||
553 | struct inode *inode) | ||
554 | { | ||
555 | struct btrfs_inode *btrfs_inode = BTRFS_I(inode); | ||
556 | struct btrfs_delayed_node *delayed_node; | ||
557 | |||
558 | delayed_node = btrfs_inode->delayed_node; | ||
559 | if (delayed_node) | ||
560 | atomic_inc(&delayed_node->refs); | ||
561 | |||
562 | return delayed_node; | ||
563 | } | ||
564 | |||
565 | static inline struct btrfs_root *btrfs_get_fs_root(struct btrfs_root *root, | 567 | static inline struct btrfs_root *btrfs_get_fs_root(struct btrfs_root *root, |
566 | u64 root_id) | 568 | u64 root_id) |
567 | { | 569 | { |
@@ -593,10 +595,8 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, | |||
593 | 595 | ||
594 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 596 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
595 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 597 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
596 | if (!ret) { | 598 | if (!ret) |
597 | item->bytes_reserved = num_bytes; | 599 | item->bytes_reserved = num_bytes; |
598 | item->block_rsv = dst_rsv; | ||
599 | } | ||
600 | 600 | ||
601 | return ret; | 601 | return ret; |
602 | } | 602 | } |
@@ -604,10 +604,13 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, | |||
604 | static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, | 604 | static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, |
605 | struct btrfs_delayed_item *item) | 605 | struct btrfs_delayed_item *item) |
606 | { | 606 | { |
607 | struct btrfs_block_rsv *rsv; | ||
608 | |||
607 | if (!item->bytes_reserved) | 609 | if (!item->bytes_reserved) |
608 | return; | 610 | return; |
609 | 611 | ||
610 | btrfs_block_rsv_release(root, item->block_rsv, | 612 | rsv = &root->fs_info->global_block_rsv; |
613 | btrfs_block_rsv_release(root, rsv, | ||
611 | item->bytes_reserved); | 614 | item->bytes_reserved); |
612 | } | 615 | } |
613 | 616 | ||
@@ -1014,6 +1017,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1014 | struct btrfs_delayed_root *delayed_root; | 1017 | struct btrfs_delayed_root *delayed_root; |
1015 | struct btrfs_delayed_node *curr_node, *prev_node; | 1018 | struct btrfs_delayed_node *curr_node, *prev_node; |
1016 | struct btrfs_path *path; | 1019 | struct btrfs_path *path; |
1020 | struct btrfs_block_rsv *block_rsv; | ||
1017 | int ret = 0; | 1021 | int ret = 0; |
1018 | 1022 | ||
1019 | path = btrfs_alloc_path(); | 1023 | path = btrfs_alloc_path(); |
@@ -1021,6 +1025,9 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1021 | return -ENOMEM; | 1025 | return -ENOMEM; |
1022 | path->leave_spinning = 1; | 1026 | path->leave_spinning = 1; |
1023 | 1027 | ||
1028 | block_rsv = trans->block_rsv; | ||
1029 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
1030 | |||
1024 | delayed_root = btrfs_get_delayed_root(root); | 1031 | delayed_root = btrfs_get_delayed_root(root); |
1025 | 1032 | ||
1026 | curr_node = btrfs_first_delayed_node(delayed_root); | 1033 | curr_node = btrfs_first_delayed_node(delayed_root); |
@@ -1045,6 +1052,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, | |||
1045 | } | 1052 | } |
1046 | 1053 | ||
1047 | btrfs_free_path(path); | 1054 | btrfs_free_path(path); |
1055 | trans->block_rsv = block_rsv; | ||
1048 | return ret; | 1056 | return ret; |
1049 | } | 1057 | } |
1050 | 1058 | ||
@@ -1052,6 +1060,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
1052 | struct btrfs_delayed_node *node) | 1060 | struct btrfs_delayed_node *node) |
1053 | { | 1061 | { |
1054 | struct btrfs_path *path; | 1062 | struct btrfs_path *path; |
1063 | struct btrfs_block_rsv *block_rsv; | ||
1055 | int ret; | 1064 | int ret; |
1056 | 1065 | ||
1057 | path = btrfs_alloc_path(); | 1066 | path = btrfs_alloc_path(); |
@@ -1059,6 +1068,9 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
1059 | return -ENOMEM; | 1068 | return -ENOMEM; |
1060 | path->leave_spinning = 1; | 1069 | path->leave_spinning = 1; |
1061 | 1070 | ||
1071 | block_rsv = trans->block_rsv; | ||
1072 | trans->block_rsv = &node->root->fs_info->global_block_rsv; | ||
1073 | |||
1062 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); | 1074 | ret = btrfs_insert_delayed_items(trans, path, node->root, node); |
1063 | if (!ret) | 1075 | if (!ret) |
1064 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); | 1076 | ret = btrfs_delete_delayed_items(trans, path, node->root, node); |
@@ -1066,6 +1078,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
1066 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); | 1078 | ret = btrfs_update_delayed_inode(trans, node->root, path, node); |
1067 | btrfs_free_path(path); | 1079 | btrfs_free_path(path); |
1068 | 1080 | ||
1081 | trans->block_rsv = block_rsv; | ||
1069 | return ret; | 1082 | return ret; |
1070 | } | 1083 | } |
1071 | 1084 | ||
@@ -1116,6 +1129,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1116 | struct btrfs_path *path; | 1129 | struct btrfs_path *path; |
1117 | struct btrfs_delayed_node *delayed_node = NULL; | 1130 | struct btrfs_delayed_node *delayed_node = NULL; |
1118 | struct btrfs_root *root; | 1131 | struct btrfs_root *root; |
1132 | struct btrfs_block_rsv *block_rsv; | ||
1119 | unsigned long nr = 0; | 1133 | unsigned long nr = 0; |
1120 | int need_requeue = 0; | 1134 | int need_requeue = 0; |
1121 | int ret; | 1135 | int ret; |
@@ -1134,6 +1148,9 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1134 | if (IS_ERR(trans)) | 1148 | if (IS_ERR(trans)) |
1135 | goto free_path; | 1149 | goto free_path; |
1136 | 1150 | ||
1151 | block_rsv = trans->block_rsv; | ||
1152 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
1153 | |||
1137 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); | 1154 | ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); |
1138 | if (!ret) | 1155 | if (!ret) |
1139 | ret = btrfs_delete_delayed_items(trans, path, root, | 1156 | ret = btrfs_delete_delayed_items(trans, path, root, |
@@ -1176,6 +1193,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1176 | 1193 | ||
1177 | nr = trans->blocks_used; | 1194 | nr = trans->blocks_used; |
1178 | 1195 | ||
1196 | trans->block_rsv = block_rsv; | ||
1179 | btrfs_end_transaction_dmeta(trans, root); | 1197 | btrfs_end_transaction_dmeta(trans, root); |
1180 | __btrfs_btree_balance_dirty(root, nr); | 1198 | __btrfs_btree_balance_dirty(root, nr); |
1181 | free_path: | 1199 | free_path: |
@@ -1222,6 +1240,13 @@ again: | |||
1222 | return 0; | 1240 | return 0; |
1223 | } | 1241 | } |
1224 | 1242 | ||
1243 | void btrfs_assert_delayed_root_empty(struct btrfs_root *root) | ||
1244 | { | ||
1245 | struct btrfs_delayed_root *delayed_root; | ||
1246 | delayed_root = btrfs_get_delayed_root(root); | ||
1247 | WARN_ON(btrfs_first_delayed_node(delayed_root)); | ||
1248 | } | ||
1249 | |||
1225 | void btrfs_balance_delayed_items(struct btrfs_root *root) | 1250 | void btrfs_balance_delayed_items(struct btrfs_root *root) |
1226 | { | 1251 | { |
1227 | struct btrfs_delayed_root *delayed_root; | 1252 | struct btrfs_delayed_root *delayed_root; |
@@ -1382,8 +1407,7 @@ end: | |||
1382 | 1407 | ||
1383 | int btrfs_inode_delayed_dir_index_count(struct inode *inode) | 1408 | int btrfs_inode_delayed_dir_index_count(struct inode *inode) |
1384 | { | 1409 | { |
1385 | struct btrfs_delayed_node *delayed_node = BTRFS_I(inode)->delayed_node; | 1410 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); |
1386 | int ret = 0; | ||
1387 | 1411 | ||
1388 | if (!delayed_node) | 1412 | if (!delayed_node) |
1389 | return -ENOENT; | 1413 | return -ENOENT; |
@@ -1393,11 +1417,14 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode) | |||
1393 | * a new directory index is added into the delayed node and index_cnt | 1417 | * a new directory index is added into the delayed node and index_cnt |
1394 | * is updated now. So we needn't lock the delayed node. | 1418 | * is updated now. So we needn't lock the delayed node. |
1395 | */ | 1419 | */ |
1396 | if (!delayed_node->index_cnt) | 1420 | if (!delayed_node->index_cnt) { |
1421 | btrfs_release_delayed_node(delayed_node); | ||
1397 | return -EINVAL; | 1422 | return -EINVAL; |
1423 | } | ||
1398 | 1424 | ||
1399 | BTRFS_I(inode)->index_cnt = delayed_node->index_cnt; | 1425 | BTRFS_I(inode)->index_cnt = delayed_node->index_cnt; |
1400 | return ret; | 1426 | btrfs_release_delayed_node(delayed_node); |
1427 | return 0; | ||
1401 | } | 1428 | } |
1402 | 1429 | ||
1403 | void btrfs_get_delayed_items(struct inode *inode, struct list_head *ins_list, | 1430 | void btrfs_get_delayed_items(struct inode *inode, struct list_head *ins_list, |
@@ -1591,6 +1618,57 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans, | |||
1591 | inode->i_ctime.tv_nsec); | 1618 | inode->i_ctime.tv_nsec); |
1592 | } | 1619 | } |
1593 | 1620 | ||
1621 | int btrfs_fill_inode(struct inode *inode, u32 *rdev) | ||
1622 | { | ||
1623 | struct btrfs_delayed_node *delayed_node; | ||
1624 | struct btrfs_inode_item *inode_item; | ||
1625 | struct btrfs_timespec *tspec; | ||
1626 | |||
1627 | delayed_node = btrfs_get_delayed_node(inode); | ||
1628 | if (!delayed_node) | ||
1629 | return -ENOENT; | ||
1630 | |||
1631 | mutex_lock(&delayed_node->mutex); | ||
1632 | if (!delayed_node->inode_dirty) { | ||
1633 | mutex_unlock(&delayed_node->mutex); | ||
1634 | btrfs_release_delayed_node(delayed_node); | ||
1635 | return -ENOENT; | ||
1636 | } | ||
1637 | |||
1638 | inode_item = &delayed_node->inode_item; | ||
1639 | |||
1640 | inode->i_uid = btrfs_stack_inode_uid(inode_item); | ||
1641 | inode->i_gid = btrfs_stack_inode_gid(inode_item); | ||
1642 | btrfs_i_size_write(inode, btrfs_stack_inode_size(inode_item)); | ||
1643 | inode->i_mode = btrfs_stack_inode_mode(inode_item); | ||
1644 | inode->i_nlink = btrfs_stack_inode_nlink(inode_item); | ||
1645 | inode_set_bytes(inode, btrfs_stack_inode_nbytes(inode_item)); | ||
1646 | BTRFS_I(inode)->generation = btrfs_stack_inode_generation(inode_item); | ||
1647 | BTRFS_I(inode)->sequence = btrfs_stack_inode_sequence(inode_item); | ||
1648 | inode->i_rdev = 0; | ||
1649 | *rdev = btrfs_stack_inode_rdev(inode_item); | ||
1650 | BTRFS_I(inode)->flags = btrfs_stack_inode_flags(inode_item); | ||
1651 | |||
1652 | tspec = btrfs_inode_atime(inode_item); | ||
1653 | inode->i_atime.tv_sec = btrfs_stack_timespec_sec(tspec); | ||
1654 | inode->i_atime.tv_nsec = btrfs_stack_timespec_nsec(tspec); | ||
1655 | |||
1656 | tspec = btrfs_inode_mtime(inode_item); | ||
1657 | inode->i_mtime.tv_sec = btrfs_stack_timespec_sec(tspec); | ||
1658 | inode->i_mtime.tv_nsec = btrfs_stack_timespec_nsec(tspec); | ||
1659 | |||
1660 | tspec = btrfs_inode_ctime(inode_item); | ||
1661 | inode->i_ctime.tv_sec = btrfs_stack_timespec_sec(tspec); | ||
1662 | inode->i_ctime.tv_nsec = btrfs_stack_timespec_nsec(tspec); | ||
1663 | |||
1664 | inode->i_generation = BTRFS_I(inode)->generation; | ||
1665 | BTRFS_I(inode)->index_cnt = (u64)-1; | ||
1666 | |||
1667 | mutex_unlock(&delayed_node->mutex); | ||
1668 | btrfs_release_delayed_node(delayed_node); | ||
1669 | return 0; | ||
1670 | } | ||
1671 | |||
1594 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | 1672 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, |
1595 | struct btrfs_root *root, struct inode *inode) | 1673 | struct btrfs_root *root, struct inode *inode) |
1596 | { | 1674 | { |
diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h index eb7d240aa648..8d27af4bd8b9 100644 --- a/fs/btrfs/delayed-inode.h +++ b/fs/btrfs/delayed-inode.h | |||
@@ -75,7 +75,6 @@ struct btrfs_delayed_item { | |||
75 | struct list_head tree_list; /* used for batch insert/delete items */ | 75 | struct list_head tree_list; /* used for batch insert/delete items */ |
76 | struct list_head readdir_list; /* used for readdir items */ | 76 | struct list_head readdir_list; /* used for readdir items */ |
77 | u64 bytes_reserved; | 77 | u64 bytes_reserved; |
78 | struct btrfs_block_rsv *block_rsv; | ||
79 | struct btrfs_delayed_node *delayed_node; | 78 | struct btrfs_delayed_node *delayed_node; |
80 | atomic_t refs; | 79 | atomic_t refs; |
81 | int ins_or_del; | 80 | int ins_or_del; |
@@ -120,6 +119,7 @@ void btrfs_kill_delayed_inode_items(struct inode *inode); | |||
120 | 119 | ||
121 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | 120 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, |
122 | struct btrfs_root *root, struct inode *inode); | 121 | struct btrfs_root *root, struct inode *inode); |
122 | int btrfs_fill_inode(struct inode *inode, u32 *rdev); | ||
123 | 123 | ||
124 | /* Used for drop dead root */ | 124 | /* Used for drop dead root */ |
125 | void btrfs_kill_all_delayed_nodes(struct btrfs_root *root); | 125 | void btrfs_kill_all_delayed_nodes(struct btrfs_root *root); |
@@ -138,4 +138,8 @@ int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent, | |||
138 | /* for init */ | 138 | /* for init */ |
139 | int __init btrfs_delayed_inode_init(void); | 139 | int __init btrfs_delayed_inode_init(void); |
140 | void btrfs_delayed_inode_exit(void); | 140 | void btrfs_delayed_inode_exit(void); |
141 | |||
142 | /* for debugging */ | ||
143 | void btrfs_assert_delayed_root_empty(struct btrfs_root *root); | ||
144 | |||
141 | #endif | 145 | #endif |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index a203d363184d..1ac8db5dc0a3 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1044,7 +1044,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
1044 | root->last_trans = 0; | 1044 | root->last_trans = 0; |
1045 | root->highest_objectid = 0; | 1045 | root->highest_objectid = 0; |
1046 | root->name = NULL; | 1046 | root->name = NULL; |
1047 | root->in_sysfs = 0; | ||
1048 | root->inode_tree = RB_ROOT; | 1047 | root->inode_tree = RB_ROOT; |
1049 | INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC); | 1048 | INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC); |
1050 | root->block_rsv = NULL; | 1049 | root->block_rsv = NULL; |
@@ -1300,19 +1299,21 @@ again: | |||
1300 | return root; | 1299 | return root; |
1301 | 1300 | ||
1302 | root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS); | 1301 | root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS); |
1303 | if (!root->free_ino_ctl) | ||
1304 | goto fail; | ||
1305 | root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned), | 1302 | root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned), |
1306 | GFP_NOFS); | 1303 | GFP_NOFS); |
1307 | if (!root->free_ino_pinned) | 1304 | if (!root->free_ino_pinned || !root->free_ino_ctl) { |
1305 | ret = -ENOMEM; | ||
1308 | goto fail; | 1306 | goto fail; |
1307 | } | ||
1309 | 1308 | ||
1310 | btrfs_init_free_ino_ctl(root); | 1309 | btrfs_init_free_ino_ctl(root); |
1311 | mutex_init(&root->fs_commit_mutex); | 1310 | mutex_init(&root->fs_commit_mutex); |
1312 | spin_lock_init(&root->cache_lock); | 1311 | spin_lock_init(&root->cache_lock); |
1313 | init_waitqueue_head(&root->cache_wait); | 1312 | init_waitqueue_head(&root->cache_wait); |
1314 | 1313 | ||
1315 | set_anon_super(&root->anon_super, NULL); | 1314 | ret = set_anon_super(&root->anon_super, NULL); |
1315 | if (ret) | ||
1316 | goto fail; | ||
1316 | 1317 | ||
1317 | if (btrfs_root_refs(&root->root_item) == 0) { | 1318 | if (btrfs_root_refs(&root->root_item) == 0) { |
1318 | ret = -ENOENT; | 1319 | ret = -ENOENT; |
@@ -1618,6 +1619,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1618 | spin_lock_init(&fs_info->fs_roots_radix_lock); | 1619 | spin_lock_init(&fs_info->fs_roots_radix_lock); |
1619 | spin_lock_init(&fs_info->delayed_iput_lock); | 1620 | spin_lock_init(&fs_info->delayed_iput_lock); |
1620 | spin_lock_init(&fs_info->defrag_inodes_lock); | 1621 | spin_lock_init(&fs_info->defrag_inodes_lock); |
1622 | mutex_init(&fs_info->reloc_mutex); | ||
1621 | 1623 | ||
1622 | init_completion(&fs_info->kobj_unregister); | 1624 | init_completion(&fs_info->kobj_unregister); |
1623 | fs_info->tree_root = tree_root; | 1625 | fs_info->tree_root = tree_root; |
@@ -1668,8 +1670,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1668 | init_waitqueue_head(&fs_info->scrub_pause_wait); | 1670 | init_waitqueue_head(&fs_info->scrub_pause_wait); |
1669 | init_rwsem(&fs_info->scrub_super_lock); | 1671 | init_rwsem(&fs_info->scrub_super_lock); |
1670 | fs_info->scrub_workers_refcnt = 0; | 1672 | fs_info->scrub_workers_refcnt = 0; |
1671 | btrfs_init_workers(&fs_info->scrub_workers, "scrub", | ||
1672 | fs_info->thread_pool_size, &fs_info->generic_worker); | ||
1673 | 1673 | ||
1674 | sb->s_blocksize = 4096; | 1674 | sb->s_blocksize = 4096; |
1675 | sb->s_blocksize_bits = blksize_bits(4096); | 1675 | sb->s_blocksize_bits = blksize_bits(4096); |
@@ -2911,9 +2911,8 @@ static int btrfs_destroy_delalloc_inodes(struct btrfs_root *root) | |||
2911 | 2911 | ||
2912 | INIT_LIST_HEAD(&splice); | 2912 | INIT_LIST_HEAD(&splice); |
2913 | 2913 | ||
2914 | list_splice_init(&root->fs_info->delalloc_inodes, &splice); | ||
2915 | |||
2916 | spin_lock(&root->fs_info->delalloc_lock); | 2914 | spin_lock(&root->fs_info->delalloc_lock); |
2915 | list_splice_init(&root->fs_info->delalloc_inodes, &splice); | ||
2917 | 2916 | ||
2918 | while (!list_empty(&splice)) { | 2917 | while (!list_empty(&splice)) { |
2919 | btrfs_inode = list_entry(splice.next, struct btrfs_inode, | 2918 | btrfs_inode = list_entry(splice.next, struct btrfs_inode, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5b9b6b6df242..71cd456fdb60 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3089,6 +3089,13 @@ alloc: | |||
3089 | } | 3089 | } |
3090 | goto again; | 3090 | goto again; |
3091 | } | 3091 | } |
3092 | |||
3093 | /* | ||
3094 | * If we have less pinned bytes than we want to allocate then | ||
3095 | * don't bother committing the transaction, it won't help us. | ||
3096 | */ | ||
3097 | if (data_sinfo->bytes_pinned < bytes) | ||
3098 | committed = 1; | ||
3092 | spin_unlock(&data_sinfo->lock); | 3099 | spin_unlock(&data_sinfo->lock); |
3093 | 3100 | ||
3094 | /* commit the current transaction and try again */ | 3101 | /* commit the current transaction and try again */ |
@@ -3307,10 +3314,6 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3307 | if (reserved == 0) | 3314 | if (reserved == 0) |
3308 | return 0; | 3315 | return 0; |
3309 | 3316 | ||
3310 | /* nothing to shrink - nothing to reclaim */ | ||
3311 | if (root->fs_info->delalloc_bytes == 0) | ||
3312 | return 0; | ||
3313 | |||
3314 | max_reclaim = min(reserved, to_reclaim); | 3317 | max_reclaim = min(reserved, to_reclaim); |
3315 | 3318 | ||
3316 | while (loops < 1024) { | 3319 | while (loops < 1024) { |
@@ -4839,7 +4842,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
4839 | u64 num_bytes, u64 empty_size, | 4842 | u64 num_bytes, u64 empty_size, |
4840 | u64 search_start, u64 search_end, | 4843 | u64 search_start, u64 search_end, |
4841 | u64 hint_byte, struct btrfs_key *ins, | 4844 | u64 hint_byte, struct btrfs_key *ins, |
4842 | int data) | 4845 | u64 data) |
4843 | { | 4846 | { |
4844 | int ret = 0; | 4847 | int ret = 0; |
4845 | struct btrfs_root *root = orig_root->fs_info->extent_root; | 4848 | struct btrfs_root *root = orig_root->fs_info->extent_root; |
@@ -4866,7 +4869,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
4866 | 4869 | ||
4867 | space_info = __find_space_info(root->fs_info, data); | 4870 | space_info = __find_space_info(root->fs_info, data); |
4868 | if (!space_info) { | 4871 | if (!space_info) { |
4869 | printk(KERN_ERR "No space info for %d\n", data); | 4872 | printk(KERN_ERR "No space info for %llu\n", data); |
4870 | return -ENOSPC; | 4873 | return -ENOSPC; |
4871 | } | 4874 | } |
4872 | 4875 | ||
@@ -5211,9 +5214,7 @@ loop: | |||
5211 | * LOOP_NO_EMPTY_SIZE, set empty_size and empty_cluster to 0 and try | 5214 | * LOOP_NO_EMPTY_SIZE, set empty_size and empty_cluster to 0 and try |
5212 | * again | 5215 | * again |
5213 | */ | 5216 | */ |
5214 | if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE && | 5217 | if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE) { |
5215 | (found_uncached_bg || empty_size || empty_cluster || | ||
5216 | allowed_chunk_alloc)) { | ||
5217 | index = 0; | 5218 | index = 0; |
5218 | if (loop == LOOP_FIND_IDEAL && found_uncached_bg) { | 5219 | if (loop == LOOP_FIND_IDEAL && found_uncached_bg) { |
5219 | found_uncached_bg = false; | 5220 | found_uncached_bg = false; |
@@ -5253,32 +5254,36 @@ loop: | |||
5253 | goto search; | 5254 | goto search; |
5254 | } | 5255 | } |
5255 | 5256 | ||
5256 | if (loop < LOOP_CACHING_WAIT) { | 5257 | loop++; |
5257 | loop++; | ||
5258 | goto search; | ||
5259 | } | ||
5260 | 5258 | ||
5261 | if (loop == LOOP_ALLOC_CHUNK) { | 5259 | if (loop == LOOP_ALLOC_CHUNK) { |
5262 | empty_size = 0; | 5260 | if (allowed_chunk_alloc) { |
5263 | empty_cluster = 0; | 5261 | ret = do_chunk_alloc(trans, root, num_bytes + |
5264 | } | 5262 | 2 * 1024 * 1024, data, |
5263 | CHUNK_ALLOC_LIMITED); | ||
5264 | allowed_chunk_alloc = 0; | ||
5265 | if (ret == 1) | ||
5266 | done_chunk_alloc = 1; | ||
5267 | } else if (!done_chunk_alloc && | ||
5268 | space_info->force_alloc == | ||
5269 | CHUNK_ALLOC_NO_FORCE) { | ||
5270 | space_info->force_alloc = CHUNK_ALLOC_LIMITED; | ||
5271 | } | ||
5265 | 5272 | ||
5266 | if (allowed_chunk_alloc) { | 5273 | /* |
5267 | ret = do_chunk_alloc(trans, root, num_bytes + | 5274 | * We didn't allocate a chunk, go ahead and drop the |
5268 | 2 * 1024 * 1024, data, | 5275 | * empty size and loop again. |
5269 | CHUNK_ALLOC_LIMITED); | 5276 | */ |
5270 | allowed_chunk_alloc = 0; | 5277 | if (!done_chunk_alloc) |
5271 | done_chunk_alloc = 1; | 5278 | loop = LOOP_NO_EMPTY_SIZE; |
5272 | } else if (!done_chunk_alloc && | ||
5273 | space_info->force_alloc == CHUNK_ALLOC_NO_FORCE) { | ||
5274 | space_info->force_alloc = CHUNK_ALLOC_LIMITED; | ||
5275 | } | 5279 | } |
5276 | 5280 | ||
5277 | if (loop < LOOP_NO_EMPTY_SIZE) { | 5281 | if (loop == LOOP_NO_EMPTY_SIZE) { |
5278 | loop++; | 5282 | empty_size = 0; |
5279 | goto search; | 5283 | empty_cluster = 0; |
5280 | } | 5284 | } |
5281 | ret = -ENOSPC; | 5285 | |
5286 | goto search; | ||
5282 | } else if (!ins->objectid) { | 5287 | } else if (!ins->objectid) { |
5283 | ret = -ENOSPC; | 5288 | ret = -ENOSPC; |
5284 | } else if (ins->objectid) { | 5289 | } else if (ins->objectid) { |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 4e8445a4757c..a11a92ee2d30 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -126,9 +126,9 @@ struct extent_buffer { | |||
126 | unsigned long map_len; | 126 | unsigned long map_len; |
127 | struct page *first_page; | 127 | struct page *first_page; |
128 | unsigned long bflags; | 128 | unsigned long bflags; |
129 | atomic_t refs; | ||
130 | struct list_head leak_list; | 129 | struct list_head leak_list; |
131 | struct rcu_head rcu_head; | 130 | struct rcu_head rcu_head; |
131 | atomic_t refs; | ||
132 | 132 | ||
133 | /* the spinlock is used to protect most operations */ | 133 | /* the spinlock is used to protect most operations */ |
134 | spinlock_t lock; | 134 | spinlock_t lock; |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index ad144736a5fd..bf0d61567f3d 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -250,7 +250,7 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
250 | pgoff_t index = 0; | 250 | pgoff_t index = 0; |
251 | unsigned long first_page_offset; | 251 | unsigned long first_page_offset; |
252 | int num_checksums; | 252 | int num_checksums; |
253 | int ret = 0, ret2; | 253 | int ret = 0; |
254 | 254 | ||
255 | INIT_LIST_HEAD(&bitmaps); | 255 | INIT_LIST_HEAD(&bitmaps); |
256 | 256 | ||
@@ -421,11 +421,10 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
421 | goto free_cache; | 421 | goto free_cache; |
422 | } | 422 | } |
423 | spin_lock(&ctl->tree_lock); | 423 | spin_lock(&ctl->tree_lock); |
424 | ret2 = link_free_space(ctl, e); | 424 | ret = link_free_space(ctl, e); |
425 | ctl->total_bitmaps++; | 425 | ctl->total_bitmaps++; |
426 | ctl->op->recalc_thresholds(ctl); | 426 | ctl->op->recalc_thresholds(ctl); |
427 | spin_unlock(&ctl->tree_lock); | 427 | spin_unlock(&ctl->tree_lock); |
428 | list_add_tail(&e->list, &bitmaps); | ||
429 | if (ret) { | 428 | if (ret) { |
430 | printk(KERN_ERR "Duplicate entries in " | 429 | printk(KERN_ERR "Duplicate entries in " |
431 | "free space cache, dumping\n"); | 430 | "free space cache, dumping\n"); |
@@ -434,6 +433,7 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
434 | page_cache_release(page); | 433 | page_cache_release(page); |
435 | goto free_cache; | 434 | goto free_cache; |
436 | } | 435 | } |
436 | list_add_tail(&e->list, &bitmaps); | ||
437 | } | 437 | } |
438 | 438 | ||
439 | num_entries--; | 439 | num_entries--; |
@@ -1417,6 +1417,23 @@ again: | |||
1417 | return 0; | 1417 | return 0; |
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | static u64 add_bytes_to_bitmap(struct btrfs_free_space_ctl *ctl, | ||
1421 | struct btrfs_free_space *info, u64 offset, | ||
1422 | u64 bytes) | ||
1423 | { | ||
1424 | u64 bytes_to_set = 0; | ||
1425 | u64 end; | ||
1426 | |||
1427 | end = info->offset + (u64)(BITS_PER_BITMAP * ctl->unit); | ||
1428 | |||
1429 | bytes_to_set = min(end - offset, bytes); | ||
1430 | |||
1431 | bitmap_set_bits(ctl, info, offset, bytes_to_set); | ||
1432 | |||
1433 | return bytes_to_set; | ||
1434 | |||
1435 | } | ||
1436 | |||
1420 | static bool use_bitmap(struct btrfs_free_space_ctl *ctl, | 1437 | static bool use_bitmap(struct btrfs_free_space_ctl *ctl, |
1421 | struct btrfs_free_space *info) | 1438 | struct btrfs_free_space *info) |
1422 | { | 1439 | { |
@@ -1453,12 +1470,18 @@ static bool use_bitmap(struct btrfs_free_space_ctl *ctl, | |||
1453 | return true; | 1470 | return true; |
1454 | } | 1471 | } |
1455 | 1472 | ||
1473 | static struct btrfs_free_space_op free_space_op = { | ||
1474 | .recalc_thresholds = recalculate_thresholds, | ||
1475 | .use_bitmap = use_bitmap, | ||
1476 | }; | ||
1477 | |||
1456 | static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl, | 1478 | static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl, |
1457 | struct btrfs_free_space *info) | 1479 | struct btrfs_free_space *info) |
1458 | { | 1480 | { |
1459 | struct btrfs_free_space *bitmap_info; | 1481 | struct btrfs_free_space *bitmap_info; |
1482 | struct btrfs_block_group_cache *block_group = NULL; | ||
1460 | int added = 0; | 1483 | int added = 0; |
1461 | u64 bytes, offset, end; | 1484 | u64 bytes, offset, bytes_added; |
1462 | int ret; | 1485 | int ret; |
1463 | 1486 | ||
1464 | bytes = info->bytes; | 1487 | bytes = info->bytes; |
@@ -1467,7 +1490,49 @@ static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl, | |||
1467 | if (!ctl->op->use_bitmap(ctl, info)) | 1490 | if (!ctl->op->use_bitmap(ctl, info)) |
1468 | return 0; | 1491 | return 0; |
1469 | 1492 | ||
1493 | if (ctl->op == &free_space_op) | ||
1494 | block_group = ctl->private; | ||
1470 | again: | 1495 | again: |
1496 | /* | ||
1497 | * Since we link bitmaps right into the cluster we need to see if we | ||
1498 | * have a cluster here, and if so and it has our bitmap we need to add | ||
1499 | * the free space to that bitmap. | ||
1500 | */ | ||
1501 | if (block_group && !list_empty(&block_group->cluster_list)) { | ||
1502 | struct btrfs_free_cluster *cluster; | ||
1503 | struct rb_node *node; | ||
1504 | struct btrfs_free_space *entry; | ||
1505 | |||
1506 | cluster = list_entry(block_group->cluster_list.next, | ||
1507 | struct btrfs_free_cluster, | ||
1508 | block_group_list); | ||
1509 | spin_lock(&cluster->lock); | ||
1510 | node = rb_first(&cluster->root); | ||
1511 | if (!node) { | ||
1512 | spin_unlock(&cluster->lock); | ||
1513 | goto no_cluster_bitmap; | ||
1514 | } | ||
1515 | |||
1516 | entry = rb_entry(node, struct btrfs_free_space, offset_index); | ||
1517 | if (!entry->bitmap) { | ||
1518 | spin_unlock(&cluster->lock); | ||
1519 | goto no_cluster_bitmap; | ||
1520 | } | ||
1521 | |||
1522 | if (entry->offset == offset_to_bitmap(ctl, offset)) { | ||
1523 | bytes_added = add_bytes_to_bitmap(ctl, entry, | ||
1524 | offset, bytes); | ||
1525 | bytes -= bytes_added; | ||
1526 | offset += bytes_added; | ||
1527 | } | ||
1528 | spin_unlock(&cluster->lock); | ||
1529 | if (!bytes) { | ||
1530 | ret = 1; | ||
1531 | goto out; | ||
1532 | } | ||
1533 | } | ||
1534 | |||
1535 | no_cluster_bitmap: | ||
1471 | bitmap_info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), | 1536 | bitmap_info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), |
1472 | 1, 0); | 1537 | 1, 0); |
1473 | if (!bitmap_info) { | 1538 | if (!bitmap_info) { |
@@ -1475,19 +1540,10 @@ again: | |||
1475 | goto new_bitmap; | 1540 | goto new_bitmap; |
1476 | } | 1541 | } |
1477 | 1542 | ||
1478 | end = bitmap_info->offset + (u64)(BITS_PER_BITMAP * ctl->unit); | 1543 | bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes); |
1479 | 1544 | bytes -= bytes_added; | |
1480 | if (offset >= bitmap_info->offset && offset + bytes > end) { | 1545 | offset += bytes_added; |
1481 | bitmap_set_bits(ctl, bitmap_info, offset, end - offset); | 1546 | added = 0; |
1482 | bytes -= end - offset; | ||
1483 | offset = end; | ||
1484 | added = 0; | ||
1485 | } else if (offset >= bitmap_info->offset && offset + bytes <= end) { | ||
1486 | bitmap_set_bits(ctl, bitmap_info, offset, bytes); | ||
1487 | bytes = 0; | ||
1488 | } else { | ||
1489 | BUG(); | ||
1490 | } | ||
1491 | 1547 | ||
1492 | if (!bytes) { | 1548 | if (!bytes) { |
1493 | ret = 1; | 1549 | ret = 1; |
@@ -1766,11 +1822,6 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group, | |||
1766 | "\n", count); | 1822 | "\n", count); |
1767 | } | 1823 | } |
1768 | 1824 | ||
1769 | static struct btrfs_free_space_op free_space_op = { | ||
1770 | .recalc_thresholds = recalculate_thresholds, | ||
1771 | .use_bitmap = use_bitmap, | ||
1772 | }; | ||
1773 | |||
1774 | void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group) | 1825 | void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group) |
1775 | { | 1826 | { |
1776 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 1827 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
@@ -1842,9 +1893,12 @@ void __btrfs_remove_free_space_cache_locked(struct btrfs_free_space_ctl *ctl) | |||
1842 | 1893 | ||
1843 | while ((node = rb_last(&ctl->free_space_offset)) != NULL) { | 1894 | while ((node = rb_last(&ctl->free_space_offset)) != NULL) { |
1844 | info = rb_entry(node, struct btrfs_free_space, offset_index); | 1895 | info = rb_entry(node, struct btrfs_free_space, offset_index); |
1845 | unlink_free_space(ctl, info); | 1896 | if (!info->bitmap) { |
1846 | kfree(info->bitmap); | 1897 | unlink_free_space(ctl, info); |
1847 | kmem_cache_free(btrfs_free_space_cachep, info); | 1898 | kmem_cache_free(btrfs_free_space_cachep, info); |
1899 | } else { | ||
1900 | free_bitmap(ctl, info); | ||
1901 | } | ||
1848 | if (need_resched()) { | 1902 | if (need_resched()) { |
1849 | spin_unlock(&ctl->tree_lock); | 1903 | spin_unlock(&ctl->tree_lock); |
1850 | cond_resched(); | 1904 | cond_resched(); |
@@ -2142,9 +2196,11 @@ again: | |||
2142 | /* | 2196 | /* |
2143 | * This searches the block group for just extents to fill the cluster with. | 2197 | * This searches the block group for just extents to fill the cluster with. |
2144 | */ | 2198 | */ |
2145 | static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, | 2199 | static noinline int |
2146 | struct btrfs_free_cluster *cluster, | 2200 | setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, |
2147 | u64 offset, u64 bytes, u64 min_bytes) | 2201 | struct btrfs_free_cluster *cluster, |
2202 | struct list_head *bitmaps, u64 offset, u64 bytes, | ||
2203 | u64 min_bytes) | ||
2148 | { | 2204 | { |
2149 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 2205 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
2150 | struct btrfs_free_space *first = NULL; | 2206 | struct btrfs_free_space *first = NULL; |
@@ -2166,6 +2222,8 @@ static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, | |||
2166 | * extent entry. | 2222 | * extent entry. |
2167 | */ | 2223 | */ |
2168 | while (entry->bitmap) { | 2224 | while (entry->bitmap) { |
2225 | if (list_empty(&entry->list)) | ||
2226 | list_add_tail(&entry->list, bitmaps); | ||
2169 | node = rb_next(&entry->offset_index); | 2227 | node = rb_next(&entry->offset_index); |
2170 | if (!node) | 2228 | if (!node) |
2171 | return -ENOSPC; | 2229 | return -ENOSPC; |
@@ -2185,8 +2243,12 @@ static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, | |||
2185 | return -ENOSPC; | 2243 | return -ENOSPC; |
2186 | entry = rb_entry(node, struct btrfs_free_space, offset_index); | 2244 | entry = rb_entry(node, struct btrfs_free_space, offset_index); |
2187 | 2245 | ||
2188 | if (entry->bitmap) | 2246 | if (entry->bitmap) { |
2247 | if (list_empty(&entry->list)) | ||
2248 | list_add_tail(&entry->list, bitmaps); | ||
2189 | continue; | 2249 | continue; |
2250 | } | ||
2251 | |||
2190 | /* | 2252 | /* |
2191 | * we haven't filled the empty size and the window is | 2253 | * we haven't filled the empty size and the window is |
2192 | * very large. reset and try again | 2254 | * very large. reset and try again |
@@ -2238,9 +2300,11 @@ static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, | |||
2238 | * This specifically looks for bitmaps that may work in the cluster, we assume | 2300 | * This specifically looks for bitmaps that may work in the cluster, we assume |
2239 | * that we have already failed to find extents that will work. | 2301 | * that we have already failed to find extents that will work. |
2240 | */ | 2302 | */ |
2241 | static int setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, | 2303 | static noinline int |
2242 | struct btrfs_free_cluster *cluster, | 2304 | setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, |
2243 | u64 offset, u64 bytes, u64 min_bytes) | 2305 | struct btrfs_free_cluster *cluster, |
2306 | struct list_head *bitmaps, u64 offset, u64 bytes, | ||
2307 | u64 min_bytes) | ||
2244 | { | 2308 | { |
2245 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 2309 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
2246 | struct btrfs_free_space *entry; | 2310 | struct btrfs_free_space *entry; |
@@ -2250,10 +2314,39 @@ static int setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, | |||
2250 | if (ctl->total_bitmaps == 0) | 2314 | if (ctl->total_bitmaps == 0) |
2251 | return -ENOSPC; | 2315 | return -ENOSPC; |
2252 | 2316 | ||
2317 | /* | ||
2318 | * First check our cached list of bitmaps and see if there is an entry | ||
2319 | * here that will work. | ||
2320 | */ | ||
2321 | list_for_each_entry(entry, bitmaps, list) { | ||
2322 | if (entry->bytes < min_bytes) | ||
2323 | continue; | ||
2324 | ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset, | ||
2325 | bytes, min_bytes); | ||
2326 | if (!ret) | ||
2327 | return 0; | ||
2328 | } | ||
2329 | |||
2330 | /* | ||
2331 | * If we do have entries on our list and we are here then we didn't find | ||
2332 | * anything, so go ahead and get the next entry after the last entry in | ||
2333 | * this list and start the search from there. | ||
2334 | */ | ||
2335 | if (!list_empty(bitmaps)) { | ||
2336 | entry = list_entry(bitmaps->prev, struct btrfs_free_space, | ||
2337 | list); | ||
2338 | node = rb_next(&entry->offset_index); | ||
2339 | if (!node) | ||
2340 | return -ENOSPC; | ||
2341 | entry = rb_entry(node, struct btrfs_free_space, offset_index); | ||
2342 | goto search; | ||
2343 | } | ||
2344 | |||
2253 | entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1); | 2345 | entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1); |
2254 | if (!entry) | 2346 | if (!entry) |
2255 | return -ENOSPC; | 2347 | return -ENOSPC; |
2256 | 2348 | ||
2349 | search: | ||
2257 | node = &entry->offset_index; | 2350 | node = &entry->offset_index; |
2258 | do { | 2351 | do { |
2259 | entry = rb_entry(node, struct btrfs_free_space, offset_index); | 2352 | entry = rb_entry(node, struct btrfs_free_space, offset_index); |
@@ -2284,6 +2377,8 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, | |||
2284 | u64 offset, u64 bytes, u64 empty_size) | 2377 | u64 offset, u64 bytes, u64 empty_size) |
2285 | { | 2378 | { |
2286 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 2379 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
2380 | struct list_head bitmaps; | ||
2381 | struct btrfs_free_space *entry, *tmp; | ||
2287 | u64 min_bytes; | 2382 | u64 min_bytes; |
2288 | int ret; | 2383 | int ret; |
2289 | 2384 | ||
@@ -2322,11 +2417,16 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, | |||
2322 | goto out; | 2417 | goto out; |
2323 | } | 2418 | } |
2324 | 2419 | ||
2325 | ret = setup_cluster_no_bitmap(block_group, cluster, offset, bytes, | 2420 | INIT_LIST_HEAD(&bitmaps); |
2326 | min_bytes); | 2421 | ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset, |
2422 | bytes, min_bytes); | ||
2327 | if (ret) | 2423 | if (ret) |
2328 | ret = setup_cluster_bitmap(block_group, cluster, offset, | 2424 | ret = setup_cluster_bitmap(block_group, cluster, &bitmaps, |
2329 | bytes, min_bytes); | 2425 | offset, bytes, min_bytes); |
2426 | |||
2427 | /* Clear our temporary list */ | ||
2428 | list_for_each_entry_safe(entry, tmp, &bitmaps, list) | ||
2429 | list_del_init(&entry->list); | ||
2330 | 2430 | ||
2331 | if (!ret) { | 2431 | if (!ret) { |
2332 | atomic_inc(&block_group->count); | 2432 | atomic_inc(&block_group->count); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ebf95f7a44d6..3601f0aebddf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1986,7 +1986,7 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
1986 | } | 1986 | } |
1987 | 1987 | ||
1988 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM) | 1988 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM) |
1989 | return 0; | 1989 | goto good; |
1990 | 1990 | ||
1991 | if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID && | 1991 | if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID && |
1992 | test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) { | 1992 | test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) { |
@@ -2509,6 +2509,11 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2509 | int maybe_acls; | 2509 | int maybe_acls; |
2510 | u32 rdev; | 2510 | u32 rdev; |
2511 | int ret; | 2511 | int ret; |
2512 | bool filled = false; | ||
2513 | |||
2514 | ret = btrfs_fill_inode(inode, &rdev); | ||
2515 | if (!ret) | ||
2516 | filled = true; | ||
2512 | 2517 | ||
2513 | path = btrfs_alloc_path(); | 2518 | path = btrfs_alloc_path(); |
2514 | BUG_ON(!path); | 2519 | BUG_ON(!path); |
@@ -2520,6 +2525,10 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2520 | goto make_bad; | 2525 | goto make_bad; |
2521 | 2526 | ||
2522 | leaf = path->nodes[0]; | 2527 | leaf = path->nodes[0]; |
2528 | |||
2529 | if (filled) | ||
2530 | goto cache_acl; | ||
2531 | |||
2523 | inode_item = btrfs_item_ptr(leaf, path->slots[0], | 2532 | inode_item = btrfs_item_ptr(leaf, path->slots[0], |
2524 | struct btrfs_inode_item); | 2533 | struct btrfs_inode_item); |
2525 | if (!leaf->map_token) | 2534 | if (!leaf->map_token) |
@@ -2556,7 +2565,7 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2556 | 2565 | ||
2557 | BTRFS_I(inode)->index_cnt = (u64)-1; | 2566 | BTRFS_I(inode)->index_cnt = (u64)-1; |
2558 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); | 2567 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); |
2559 | 2568 | cache_acl: | |
2560 | /* | 2569 | /* |
2561 | * try to precache a NULL acl entry for files that don't have | 2570 | * try to precache a NULL acl entry for files that don't have |
2562 | * any xattrs or acls | 2571 | * any xattrs or acls |
@@ -2572,7 +2581,6 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2572 | } | 2581 | } |
2573 | 2582 | ||
2574 | btrfs_free_path(path); | 2583 | btrfs_free_path(path); |
2575 | inode_item = NULL; | ||
2576 | 2584 | ||
2577 | switch (inode->i_mode & S_IFMT) { | 2585 | switch (inode->i_mode & S_IFMT) { |
2578 | case S_IFREG: | 2586 | case S_IFREG: |
@@ -2670,12 +2678,14 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
2670 | int ret; | 2678 | int ret; |
2671 | 2679 | ||
2672 | /* | 2680 | /* |
2673 | * If root is tree root, it means this inode is used to | 2681 | * If the inode is a free space inode, we can deadlock during commit |
2674 | * store free space information. And these inodes are updated | 2682 | * if we put it into the delayed code. |
2675 | * when committing the transaction, so they needn't delaye to | 2683 | * |
2676 | * be updated, or deadlock will occured. | 2684 | * The data relocation inode should also be directly updated |
2685 | * without delay | ||
2677 | */ | 2686 | */ |
2678 | if (!is_free_space_inode(root, inode)) { | 2687 | if (!is_free_space_inode(root, inode) |
2688 | && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) { | ||
2679 | ret = btrfs_delayed_update_inode(trans, root, inode); | 2689 | ret = btrfs_delayed_update_inode(trans, root, inode); |
2680 | if (!ret) | 2690 | if (!ret) |
2681 | btrfs_set_inode_last_trans(trans, inode); | 2691 | btrfs_set_inode_last_trans(trans, inode); |
@@ -3076,6 +3086,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, | |||
3076 | ret = btrfs_update_inode(trans, root, dir); | 3086 | ret = btrfs_update_inode(trans, root, dir); |
3077 | BUG_ON(ret); | 3087 | BUG_ON(ret); |
3078 | 3088 | ||
3089 | btrfs_free_path(path); | ||
3079 | return 0; | 3090 | return 0; |
3080 | } | 3091 | } |
3081 | 3092 | ||
@@ -3646,7 +3657,7 @@ void btrfs_evict_inode(struct inode *inode) | |||
3646 | btrfs_i_size_write(inode, 0); | 3657 | btrfs_i_size_write(inode, 0); |
3647 | 3658 | ||
3648 | while (1) { | 3659 | while (1) { |
3649 | trans = btrfs_start_transaction(root, 0); | 3660 | trans = btrfs_join_transaction(root); |
3650 | BUG_ON(IS_ERR(trans)); | 3661 | BUG_ON(IS_ERR(trans)); |
3651 | trans->block_rsv = root->orphan_block_rsv; | 3662 | trans->block_rsv = root->orphan_block_rsv; |
3652 | 3663 | ||
@@ -4519,6 +4530,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
4519 | inode_tree_add(inode); | 4530 | inode_tree_add(inode); |
4520 | 4531 | ||
4521 | trace_btrfs_inode_new(inode); | 4532 | trace_btrfs_inode_new(inode); |
4533 | btrfs_set_inode_last_trans(trans, inode); | ||
4522 | 4534 | ||
4523 | return inode; | 4535 | return inode; |
4524 | fail: | 4536 | fail: |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index ac37040e426a..a3c4751e07db 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -482,8 +482,10 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
482 | ret = btrfs_snap_reserve_metadata(trans, pending_snapshot); | 482 | ret = btrfs_snap_reserve_metadata(trans, pending_snapshot); |
483 | BUG_ON(ret); | 483 | BUG_ON(ret); |
484 | 484 | ||
485 | spin_lock(&root->fs_info->trans_lock); | ||
485 | list_add(&pending_snapshot->list, | 486 | list_add(&pending_snapshot->list, |
486 | &trans->transaction->pending_snapshots); | 487 | &trans->transaction->pending_snapshots); |
488 | spin_unlock(&root->fs_info->trans_lock); | ||
487 | if (async_transid) { | 489 | if (async_transid) { |
488 | *async_transid = trans->transid; | 490 | *async_transid = trans->transid; |
489 | ret = btrfs_commit_transaction_async(trans, | 491 | ret = btrfs_commit_transaction_async(trans, |
@@ -2054,29 +2056,34 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) | |||
2054 | 2056 | ||
2055 | static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) | 2057 | static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) |
2056 | { | 2058 | { |
2057 | struct btrfs_ioctl_fs_info_args fi_args; | 2059 | struct btrfs_ioctl_fs_info_args *fi_args; |
2058 | struct btrfs_device *device; | 2060 | struct btrfs_device *device; |
2059 | struct btrfs_device *next; | 2061 | struct btrfs_device *next; |
2060 | struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; | 2062 | struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; |
2063 | int ret = 0; | ||
2061 | 2064 | ||
2062 | if (!capable(CAP_SYS_ADMIN)) | 2065 | if (!capable(CAP_SYS_ADMIN)) |
2063 | return -EPERM; | 2066 | return -EPERM; |
2064 | 2067 | ||
2065 | fi_args.num_devices = fs_devices->num_devices; | 2068 | fi_args = kzalloc(sizeof(*fi_args), GFP_KERNEL); |
2066 | fi_args.max_id = 0; | 2069 | if (!fi_args) |
2067 | memcpy(&fi_args.fsid, root->fs_info->fsid, sizeof(fi_args.fsid)); | 2070 | return -ENOMEM; |
2071 | |||
2072 | fi_args->num_devices = fs_devices->num_devices; | ||
2073 | memcpy(&fi_args->fsid, root->fs_info->fsid, sizeof(fi_args->fsid)); | ||
2068 | 2074 | ||
2069 | mutex_lock(&fs_devices->device_list_mutex); | 2075 | mutex_lock(&fs_devices->device_list_mutex); |
2070 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { | 2076 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { |
2071 | if (device->devid > fi_args.max_id) | 2077 | if (device->devid > fi_args->max_id) |
2072 | fi_args.max_id = device->devid; | 2078 | fi_args->max_id = device->devid; |
2073 | } | 2079 | } |
2074 | mutex_unlock(&fs_devices->device_list_mutex); | 2080 | mutex_unlock(&fs_devices->device_list_mutex); |
2075 | 2081 | ||
2076 | if (copy_to_user(arg, &fi_args, sizeof(fi_args))) | 2082 | if (copy_to_user(arg, fi_args, sizeof(*fi_args))) |
2077 | return -EFAULT; | 2083 | ret = -EFAULT; |
2078 | 2084 | ||
2079 | return 0; | 2085 | kfree(fi_args); |
2086 | return ret; | ||
2080 | } | 2087 | } |
2081 | 2088 | ||
2082 | static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg) | 2089 | static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg) |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index b1ef27cc673b..5e0a3dc79a45 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -1368,7 +1368,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, | |||
1368 | int ret; | 1368 | int ret; |
1369 | 1369 | ||
1370 | if (!root->reloc_root) | 1370 | if (!root->reloc_root) |
1371 | return 0; | 1371 | goto out; |
1372 | 1372 | ||
1373 | reloc_root = root->reloc_root; | 1373 | reloc_root = root->reloc_root; |
1374 | root_item = &reloc_root->root_item; | 1374 | root_item = &reloc_root->root_item; |
@@ -1390,6 +1390,8 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, | |||
1390 | ret = btrfs_update_root(trans, root->fs_info->tree_root, | 1390 | ret = btrfs_update_root(trans, root->fs_info->tree_root, |
1391 | &reloc_root->root_key, root_item); | 1391 | &reloc_root->root_key, root_item); |
1392 | BUG_ON(ret); | 1392 | BUG_ON(ret); |
1393 | |||
1394 | out: | ||
1393 | return 0; | 1395 | return 0; |
1394 | } | 1396 | } |
1395 | 1397 | ||
@@ -2142,10 +2144,11 @@ int prepare_to_merge(struct reloc_control *rc, int err) | |||
2142 | u64 num_bytes = 0; | 2144 | u64 num_bytes = 0; |
2143 | int ret; | 2145 | int ret; |
2144 | 2146 | ||
2145 | spin_lock(&root->fs_info->trans_lock); | 2147 | mutex_lock(&root->fs_info->reloc_mutex); |
2146 | rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2; | 2148 | rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2; |
2147 | rc->merging_rsv_size += rc->nodes_relocated * 2; | 2149 | rc->merging_rsv_size += rc->nodes_relocated * 2; |
2148 | spin_unlock(&root->fs_info->trans_lock); | 2150 | mutex_unlock(&root->fs_info->reloc_mutex); |
2151 | |||
2149 | again: | 2152 | again: |
2150 | if (!err) { | 2153 | if (!err) { |
2151 | num_bytes = rc->merging_rsv_size; | 2154 | num_bytes = rc->merging_rsv_size; |
@@ -2214,9 +2217,16 @@ int merge_reloc_roots(struct reloc_control *rc) | |||
2214 | int ret; | 2217 | int ret; |
2215 | again: | 2218 | again: |
2216 | root = rc->extent_root; | 2219 | root = rc->extent_root; |
2217 | spin_lock(&root->fs_info->trans_lock); | 2220 | |
2221 | /* | ||
2222 | * this serializes us with btrfs_record_root_in_transaction, | ||
2223 | * we have to make sure nobody is in the middle of | ||
2224 | * adding their roots to the list while we are | ||
2225 | * doing this splice | ||
2226 | */ | ||
2227 | mutex_lock(&root->fs_info->reloc_mutex); | ||
2218 | list_splice_init(&rc->reloc_roots, &reloc_roots); | 2228 | list_splice_init(&rc->reloc_roots, &reloc_roots); |
2219 | spin_unlock(&root->fs_info->trans_lock); | 2229 | mutex_unlock(&root->fs_info->reloc_mutex); |
2220 | 2230 | ||
2221 | while (!list_empty(&reloc_roots)) { | 2231 | while (!list_empty(&reloc_roots)) { |
2222 | found = 1; | 2232 | found = 1; |
@@ -3590,17 +3600,19 @@ next: | |||
3590 | static void set_reloc_control(struct reloc_control *rc) | 3600 | static void set_reloc_control(struct reloc_control *rc) |
3591 | { | 3601 | { |
3592 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; | 3602 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; |
3593 | spin_lock(&fs_info->trans_lock); | 3603 | |
3604 | mutex_lock(&fs_info->reloc_mutex); | ||
3594 | fs_info->reloc_ctl = rc; | 3605 | fs_info->reloc_ctl = rc; |
3595 | spin_unlock(&fs_info->trans_lock); | 3606 | mutex_unlock(&fs_info->reloc_mutex); |
3596 | } | 3607 | } |
3597 | 3608 | ||
3598 | static void unset_reloc_control(struct reloc_control *rc) | 3609 | static void unset_reloc_control(struct reloc_control *rc) |
3599 | { | 3610 | { |
3600 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; | 3611 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; |
3601 | spin_lock(&fs_info->trans_lock); | 3612 | |
3613 | mutex_lock(&fs_info->reloc_mutex); | ||
3602 | fs_info->reloc_ctl = NULL; | 3614 | fs_info->reloc_ctl = NULL; |
3603 | spin_unlock(&fs_info->trans_lock); | 3615 | mutex_unlock(&fs_info->reloc_mutex); |
3604 | } | 3616 | } |
3605 | 3617 | ||
3606 | static int check_extent_flags(u64 flags) | 3618 | static int check_extent_flags(u64 flags) |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index df50fd1eca8f..a8d03d5efb5d 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -16,13 +16,7 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/pagemap.h> | ||
21 | #include <linux/writeback.h> | ||
22 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
23 | #include <linux/rbtree.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | #include "ctree.h" | 20 | #include "ctree.h" |
27 | #include "volumes.h" | 21 | #include "volumes.h" |
28 | #include "disk-io.h" | 22 | #include "disk-io.h" |
@@ -804,18 +798,12 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev, | |||
804 | 798 | ||
805 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 799 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
806 | if (ret < 0) | 800 | if (ret < 0) |
807 | goto out; | 801 | goto out_noplug; |
808 | |||
809 | l = path->nodes[0]; | ||
810 | slot = path->slots[0]; | ||
811 | btrfs_item_key_to_cpu(l, &key, slot); | ||
812 | if (key.objectid != logical) { | ||
813 | ret = btrfs_previous_item(root, path, 0, | ||
814 | BTRFS_EXTENT_ITEM_KEY); | ||
815 | if (ret < 0) | ||
816 | goto out; | ||
817 | } | ||
818 | 802 | ||
803 | /* | ||
804 | * we might miss half an extent here, but that doesn't matter, | ||
805 | * as it's only the prefetch | ||
806 | */ | ||
819 | while (1) { | 807 | while (1) { |
820 | l = path->nodes[0]; | 808 | l = path->nodes[0]; |
821 | slot = path->slots[0]; | 809 | slot = path->slots[0]; |
@@ -824,7 +812,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev, | |||
824 | if (ret == 0) | 812 | if (ret == 0) |
825 | continue; | 813 | continue; |
826 | if (ret < 0) | 814 | if (ret < 0) |
827 | goto out; | 815 | goto out_noplug; |
828 | 816 | ||
829 | break; | 817 | break; |
830 | } | 818 | } |
@@ -906,15 +894,20 @@ again: | |||
906 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 894 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
907 | if (ret < 0) | 895 | if (ret < 0) |
908 | goto out; | 896 | goto out; |
909 | 897 | if (ret > 0) { | |
910 | l = path->nodes[0]; | ||
911 | slot = path->slots[0]; | ||
912 | btrfs_item_key_to_cpu(l, &key, slot); | ||
913 | if (key.objectid != logical) { | ||
914 | ret = btrfs_previous_item(root, path, 0, | 898 | ret = btrfs_previous_item(root, path, 0, |
915 | BTRFS_EXTENT_ITEM_KEY); | 899 | BTRFS_EXTENT_ITEM_KEY); |
916 | if (ret < 0) | 900 | if (ret < 0) |
917 | goto out; | 901 | goto out; |
902 | if (ret > 0) { | ||
903 | /* there's no smaller item, so stick with the | ||
904 | * larger one */ | ||
905 | btrfs_release_path(path); | ||
906 | ret = btrfs_search_slot(NULL, root, &key, | ||
907 | path, 0, 0); | ||
908 | if (ret < 0) | ||
909 | goto out; | ||
910 | } | ||
918 | } | 911 | } |
919 | 912 | ||
920 | while (1) { | 913 | while (1) { |
@@ -989,6 +982,7 @@ next: | |||
989 | 982 | ||
990 | out: | 983 | out: |
991 | blk_finish_plug(&plug); | 984 | blk_finish_plug(&plug); |
985 | out_noplug: | ||
992 | btrfs_free_path(path); | 986 | btrfs_free_path(path); |
993 | return ret < 0 ? ret : 0; | 987 | return ret < 0 ? ret : 0; |
994 | } | 988 | } |
@@ -1064,8 +1058,15 @@ int scrub_enumerate_chunks(struct scrub_dev *sdev, u64 start, u64 end) | |||
1064 | while (1) { | 1058 | while (1) { |
1065 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 1059 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
1066 | if (ret < 0) | 1060 | if (ret < 0) |
1067 | goto out; | 1061 | break; |
1068 | ret = 0; | 1062 | if (ret > 0) { |
1063 | if (path->slots[0] >= | ||
1064 | btrfs_header_nritems(path->nodes[0])) { | ||
1065 | ret = btrfs_next_leaf(root, path); | ||
1066 | if (ret) | ||
1067 | break; | ||
1068 | } | ||
1069 | } | ||
1069 | 1070 | ||
1070 | l = path->nodes[0]; | 1071 | l = path->nodes[0]; |
1071 | slot = path->slots[0]; | 1072 | slot = path->slots[0]; |
@@ -1075,7 +1076,7 @@ int scrub_enumerate_chunks(struct scrub_dev *sdev, u64 start, u64 end) | |||
1075 | if (found_key.objectid != sdev->dev->devid) | 1076 | if (found_key.objectid != sdev->dev->devid) |
1076 | break; | 1077 | break; |
1077 | 1078 | ||
1078 | if (btrfs_key_type(&key) != BTRFS_DEV_EXTENT_KEY) | 1079 | if (btrfs_key_type(&found_key) != BTRFS_DEV_EXTENT_KEY) |
1079 | break; | 1080 | break; |
1080 | 1081 | ||
1081 | if (found_key.offset >= end) | 1082 | if (found_key.offset >= end) |
@@ -1104,7 +1105,7 @@ int scrub_enumerate_chunks(struct scrub_dev *sdev, u64 start, u64 end) | |||
1104 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); | 1105 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); |
1105 | if (!cache) { | 1106 | if (!cache) { |
1106 | ret = -ENOENT; | 1107 | ret = -ENOENT; |
1107 | goto out; | 1108 | break; |
1108 | } | 1109 | } |
1109 | ret = scrub_chunk(sdev, chunk_tree, chunk_objectid, | 1110 | ret = scrub_chunk(sdev, chunk_tree, chunk_objectid, |
1110 | chunk_offset, length); | 1111 | chunk_offset, length); |
@@ -1116,9 +1117,13 @@ int scrub_enumerate_chunks(struct scrub_dev *sdev, u64 start, u64 end) | |||
1116 | btrfs_release_path(path); | 1117 | btrfs_release_path(path); |
1117 | } | 1118 | } |
1118 | 1119 | ||
1119 | out: | ||
1120 | btrfs_free_path(path); | 1120 | btrfs_free_path(path); |
1121 | return ret; | 1121 | |
1122 | /* | ||
1123 | * ret can still be 1 from search_slot or next_leaf, | ||
1124 | * that's not an error | ||
1125 | */ | ||
1126 | return ret < 0 ? ret : 0; | ||
1122 | } | 1127 | } |
1123 | 1128 | ||
1124 | static noinline_for_stack int scrub_supers(struct scrub_dev *sdev) | 1129 | static noinline_for_stack int scrub_supers(struct scrub_dev *sdev) |
@@ -1155,8 +1160,12 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_root *root) | |||
1155 | struct btrfs_fs_info *fs_info = root->fs_info; | 1160 | struct btrfs_fs_info *fs_info = root->fs_info; |
1156 | 1161 | ||
1157 | mutex_lock(&fs_info->scrub_lock); | 1162 | mutex_lock(&fs_info->scrub_lock); |
1158 | if (fs_info->scrub_workers_refcnt == 0) | 1163 | if (fs_info->scrub_workers_refcnt == 0) { |
1164 | btrfs_init_workers(&fs_info->scrub_workers, "scrub", | ||
1165 | fs_info->thread_pool_size, &fs_info->generic_worker); | ||
1166 | fs_info->scrub_workers.idle_thresh = 4; | ||
1159 | btrfs_start_workers(&fs_info->scrub_workers, 1); | 1167 | btrfs_start_workers(&fs_info->scrub_workers, 1); |
1168 | } | ||
1160 | ++fs_info->scrub_workers_refcnt; | 1169 | ++fs_info->scrub_workers_refcnt; |
1161 | mutex_unlock(&fs_info->scrub_lock); | 1170 | mutex_unlock(&fs_info->scrub_lock); |
1162 | 1171 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 117e74e3604b..15634d4648d7 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -723,6 +723,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
723 | seq_puts(seq, ",clear_cache"); | 723 | seq_puts(seq, ",clear_cache"); |
724 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | 724 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) |
725 | seq_puts(seq, ",user_subvol_rm_allowed"); | 725 | seq_puts(seq, ",user_subvol_rm_allowed"); |
726 | if (btrfs_test_opt(root, ENOSPC_DEBUG)) | ||
727 | seq_puts(seq, ",enospc_debug"); | ||
728 | if (btrfs_test_opt(root, AUTO_DEFRAG)) | ||
729 | seq_puts(seq, ",autodefrag"); | ||
730 | if (btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
731 | seq_puts(seq, ",inode_cache"); | ||
726 | return 0; | 732 | return 0; |
727 | } | 733 | } |
728 | 734 | ||
@@ -825,7 +831,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
825 | } else { | 831 | } else { |
826 | char b[BDEVNAME_SIZE]; | 832 | char b[BDEVNAME_SIZE]; |
827 | 833 | ||
828 | s->s_flags = flags; | 834 | s->s_flags = flags | MS_NOSEC; |
829 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 835 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
830 | error = btrfs_fill_super(s, fs_devices, data, | 836 | error = btrfs_fill_super(s, fs_devices, data, |
831 | flags & MS_SILENT ? 1 : 0); | 837 | flags & MS_SILENT ? 1 : 0); |
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index c3c223ae6691..daac9ae6d731 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c | |||
@@ -28,152 +28,6 @@ | |||
28 | #include "disk-io.h" | 28 | #include "disk-io.h" |
29 | #include "transaction.h" | 29 | #include "transaction.h" |
30 | 30 | ||
31 | static ssize_t root_blocks_used_show(struct btrfs_root *root, char *buf) | ||
32 | { | ||
33 | return snprintf(buf, PAGE_SIZE, "%llu\n", | ||
34 | (unsigned long long)btrfs_root_used(&root->root_item)); | ||
35 | } | ||
36 | |||
37 | static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf) | ||
38 | { | ||
39 | return snprintf(buf, PAGE_SIZE, "%llu\n", | ||
40 | (unsigned long long)btrfs_root_limit(&root->root_item)); | ||
41 | } | ||
42 | |||
43 | static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf) | ||
44 | { | ||
45 | |||
46 | return snprintf(buf, PAGE_SIZE, "%llu\n", | ||
47 | (unsigned long long)btrfs_super_bytes_used(&fs->super_copy)); | ||
48 | } | ||
49 | |||
50 | static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf) | ||
51 | { | ||
52 | return snprintf(buf, PAGE_SIZE, "%llu\n", | ||
53 | (unsigned long long)btrfs_super_total_bytes(&fs->super_copy)); | ||
54 | } | ||
55 | |||
56 | static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf) | ||
57 | { | ||
58 | return snprintf(buf, PAGE_SIZE, "%llu\n", | ||
59 | (unsigned long long)btrfs_super_sectorsize(&fs->super_copy)); | ||
60 | } | ||
61 | |||
62 | /* this is for root attrs (subvols/snapshots) */ | ||
63 | struct btrfs_root_attr { | ||
64 | struct attribute attr; | ||
65 | ssize_t (*show)(struct btrfs_root *, char *); | ||
66 | ssize_t (*store)(struct btrfs_root *, const char *, size_t); | ||
67 | }; | ||
68 | |||
69 | #define ROOT_ATTR(name, mode, show, store) \ | ||
70 | static struct btrfs_root_attr btrfs_root_attr_##name = __ATTR(name, mode, \ | ||
71 | show, store) | ||
72 | |||
73 | ROOT_ATTR(blocks_used, 0444, root_blocks_used_show, NULL); | ||
74 | ROOT_ATTR(block_limit, 0644, root_block_limit_show, NULL); | ||
75 | |||
76 | static struct attribute *btrfs_root_attrs[] = { | ||
77 | &btrfs_root_attr_blocks_used.attr, | ||
78 | &btrfs_root_attr_block_limit.attr, | ||
79 | NULL, | ||
80 | }; | ||
81 | |||
82 | /* this is for super attrs (actual full fs) */ | ||
83 | struct btrfs_super_attr { | ||
84 | struct attribute attr; | ||
85 | ssize_t (*show)(struct btrfs_fs_info *, char *); | ||
86 | ssize_t (*store)(struct btrfs_fs_info *, const char *, size_t); | ||
87 | }; | ||
88 | |||
89 | #define SUPER_ATTR(name, mode, show, store) \ | ||
90 | static struct btrfs_super_attr btrfs_super_attr_##name = __ATTR(name, mode, \ | ||
91 | show, store) | ||
92 | |||
93 | SUPER_ATTR(blocks_used, 0444, super_blocks_used_show, NULL); | ||
94 | SUPER_ATTR(total_blocks, 0444, super_total_blocks_show, NULL); | ||
95 | SUPER_ATTR(blocksize, 0444, super_blocksize_show, NULL); | ||
96 | |||
97 | static struct attribute *btrfs_super_attrs[] = { | ||
98 | &btrfs_super_attr_blocks_used.attr, | ||
99 | &btrfs_super_attr_total_blocks.attr, | ||
100 | &btrfs_super_attr_blocksize.attr, | ||
101 | NULL, | ||
102 | }; | ||
103 | |||
104 | static ssize_t btrfs_super_attr_show(struct kobject *kobj, | ||
105 | struct attribute *attr, char *buf) | ||
106 | { | ||
107 | struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info, | ||
108 | super_kobj); | ||
109 | struct btrfs_super_attr *a = container_of(attr, | ||
110 | struct btrfs_super_attr, | ||
111 | attr); | ||
112 | |||
113 | return a->show ? a->show(fs, buf) : 0; | ||
114 | } | ||
115 | |||
116 | static ssize_t btrfs_super_attr_store(struct kobject *kobj, | ||
117 | struct attribute *attr, | ||
118 | const char *buf, size_t len) | ||
119 | { | ||
120 | struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info, | ||
121 | super_kobj); | ||
122 | struct btrfs_super_attr *a = container_of(attr, | ||
123 | struct btrfs_super_attr, | ||
124 | attr); | ||
125 | |||
126 | return a->store ? a->store(fs, buf, len) : 0; | ||
127 | } | ||
128 | |||
129 | static ssize_t btrfs_root_attr_show(struct kobject *kobj, | ||
130 | struct attribute *attr, char *buf) | ||
131 | { | ||
132 | struct btrfs_root *root = container_of(kobj, struct btrfs_root, | ||
133 | root_kobj); | ||
134 | struct btrfs_root_attr *a = container_of(attr, | ||
135 | struct btrfs_root_attr, | ||
136 | attr); | ||
137 | |||
138 | return a->show ? a->show(root, buf) : 0; | ||
139 | } | ||
140 | |||
141 | static ssize_t btrfs_root_attr_store(struct kobject *kobj, | ||
142 | struct attribute *attr, | ||
143 | const char *buf, size_t len) | ||
144 | { | ||
145 | struct btrfs_root *root = container_of(kobj, struct btrfs_root, | ||
146 | root_kobj); | ||
147 | struct btrfs_root_attr *a = container_of(attr, | ||
148 | struct btrfs_root_attr, | ||
149 | attr); | ||
150 | return a->store ? a->store(root, buf, len) : 0; | ||
151 | } | ||
152 | |||
153 | static void btrfs_super_release(struct kobject *kobj) | ||
154 | { | ||
155 | struct btrfs_fs_info *fs = container_of(kobj, struct btrfs_fs_info, | ||
156 | super_kobj); | ||
157 | complete(&fs->kobj_unregister); | ||
158 | } | ||
159 | |||
160 | static void btrfs_root_release(struct kobject *kobj) | ||
161 | { | ||
162 | struct btrfs_root *root = container_of(kobj, struct btrfs_root, | ||
163 | root_kobj); | ||
164 | complete(&root->kobj_unregister); | ||
165 | } | ||
166 | |||
167 | static const struct sysfs_ops btrfs_super_attr_ops = { | ||
168 | .show = btrfs_super_attr_show, | ||
169 | .store = btrfs_super_attr_store, | ||
170 | }; | ||
171 | |||
172 | static const struct sysfs_ops btrfs_root_attr_ops = { | ||
173 | .show = btrfs_root_attr_show, | ||
174 | .store = btrfs_root_attr_store, | ||
175 | }; | ||
176 | |||
177 | /* /sys/fs/btrfs/ entry */ | 31 | /* /sys/fs/btrfs/ entry */ |
178 | static struct kset *btrfs_kset; | 32 | static struct kset *btrfs_kset; |
179 | 33 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index dd719662340e..51dcec86757f 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -126,28 +126,85 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail) | |||
126 | * to make sure the old root from before we joined the transaction is deleted | 126 | * to make sure the old root from before we joined the transaction is deleted |
127 | * when the transaction commits | 127 | * when the transaction commits |
128 | */ | 128 | */ |
129 | int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, | 129 | static int record_root_in_trans(struct btrfs_trans_handle *trans, |
130 | struct btrfs_root *root) | 130 | struct btrfs_root *root) |
131 | { | 131 | { |
132 | if (root->ref_cows && root->last_trans < trans->transid) { | 132 | if (root->ref_cows && root->last_trans < trans->transid) { |
133 | WARN_ON(root == root->fs_info->extent_root); | 133 | WARN_ON(root == root->fs_info->extent_root); |
134 | WARN_ON(root->commit_root != root->node); | 134 | WARN_ON(root->commit_root != root->node); |
135 | 135 | ||
136 | /* | ||
137 | * see below for in_trans_setup usage rules | ||
138 | * we have the reloc mutex held now, so there | ||
139 | * is only one writer in this function | ||
140 | */ | ||
141 | root->in_trans_setup = 1; | ||
142 | |||
143 | /* make sure readers find in_trans_setup before | ||
144 | * they find our root->last_trans update | ||
145 | */ | ||
146 | smp_wmb(); | ||
147 | |||
136 | spin_lock(&root->fs_info->fs_roots_radix_lock); | 148 | spin_lock(&root->fs_info->fs_roots_radix_lock); |
137 | if (root->last_trans == trans->transid) { | 149 | if (root->last_trans == trans->transid) { |
138 | spin_unlock(&root->fs_info->fs_roots_radix_lock); | 150 | spin_unlock(&root->fs_info->fs_roots_radix_lock); |
139 | return 0; | 151 | return 0; |
140 | } | 152 | } |
141 | root->last_trans = trans->transid; | ||
142 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, | 153 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, |
143 | (unsigned long)root->root_key.objectid, | 154 | (unsigned long)root->root_key.objectid, |
144 | BTRFS_ROOT_TRANS_TAG); | 155 | BTRFS_ROOT_TRANS_TAG); |
145 | spin_unlock(&root->fs_info->fs_roots_radix_lock); | 156 | spin_unlock(&root->fs_info->fs_roots_radix_lock); |
157 | root->last_trans = trans->transid; | ||
158 | |||
159 | /* this is pretty tricky. We don't want to | ||
160 | * take the relocation lock in btrfs_record_root_in_trans | ||
161 | * unless we're really doing the first setup for this root in | ||
162 | * this transaction. | ||
163 | * | ||
164 | * Normally we'd use root->last_trans as a flag to decide | ||
165 | * if we want to take the expensive mutex. | ||
166 | * | ||
167 | * But, we have to set root->last_trans before we | ||
168 | * init the relocation root, otherwise, we trip over warnings | ||
169 | * in ctree.c. The solution used here is to flag ourselves | ||
170 | * with root->in_trans_setup. When this is 1, we're still | ||
171 | * fixing up the reloc trees and everyone must wait. | ||
172 | * | ||
173 | * When this is zero, they can trust root->last_trans and fly | ||
174 | * through btrfs_record_root_in_trans without having to take the | ||
175 | * lock. smp_wmb() makes sure that all the writes above are | ||
176 | * done before we pop in the zero below | ||
177 | */ | ||
146 | btrfs_init_reloc_root(trans, root); | 178 | btrfs_init_reloc_root(trans, root); |
179 | smp_wmb(); | ||
180 | root->in_trans_setup = 0; | ||
147 | } | 181 | } |
148 | return 0; | 182 | return 0; |
149 | } | 183 | } |
150 | 184 | ||
185 | |||
186 | int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, | ||
187 | struct btrfs_root *root) | ||
188 | { | ||
189 | if (!root->ref_cows) | ||
190 | return 0; | ||
191 | |||
192 | /* | ||
193 | * see record_root_in_trans for comments about in_trans_setup usage | ||
194 | * and barriers | ||
195 | */ | ||
196 | smp_rmb(); | ||
197 | if (root->last_trans == trans->transid && | ||
198 | !root->in_trans_setup) | ||
199 | return 0; | ||
200 | |||
201 | mutex_lock(&root->fs_info->reloc_mutex); | ||
202 | record_root_in_trans(trans, root); | ||
203 | mutex_unlock(&root->fs_info->reloc_mutex); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
151 | /* wait for commit against the current transaction to become unblocked | 208 | /* wait for commit against the current transaction to become unblocked |
152 | * when this is done, it is safe to start a new transaction, but the current | 209 | * when this is done, it is safe to start a new transaction, but the current |
153 | * transaction might not be fully on disk. | 210 | * transaction might not be fully on disk. |
@@ -349,7 +406,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
349 | list) { | 406 | list) { |
350 | if (t->in_commit) { | 407 | if (t->in_commit) { |
351 | if (t->commit_done) | 408 | if (t->commit_done) |
352 | goto out; | 409 | break; |
353 | cur_trans = t; | 410 | cur_trans = t; |
354 | atomic_inc(&cur_trans->use_count); | 411 | atomic_inc(&cur_trans->use_count); |
355 | break; | 412 | break; |
@@ -882,7 +939,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
882 | parent = dget_parent(dentry); | 939 | parent = dget_parent(dentry); |
883 | parent_inode = parent->d_inode; | 940 | parent_inode = parent->d_inode; |
884 | parent_root = BTRFS_I(parent_inode)->root; | 941 | parent_root = BTRFS_I(parent_inode)->root; |
885 | btrfs_record_root_in_trans(trans, parent_root); | 942 | record_root_in_trans(trans, parent_root); |
886 | 943 | ||
887 | /* | 944 | /* |
888 | * insert the directory item | 945 | * insert the directory item |
@@ -900,7 +957,16 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
900 | ret = btrfs_update_inode(trans, parent_root, parent_inode); | 957 | ret = btrfs_update_inode(trans, parent_root, parent_inode); |
901 | BUG_ON(ret); | 958 | BUG_ON(ret); |
902 | 959 | ||
903 | btrfs_record_root_in_trans(trans, root); | 960 | /* |
961 | * pull in the delayed directory update | ||
962 | * and the delayed inode item | ||
963 | * otherwise we corrupt the FS during | ||
964 | * snapshot | ||
965 | */ | ||
966 | ret = btrfs_run_delayed_items(trans, root); | ||
967 | BUG_ON(ret); | ||
968 | |||
969 | record_root_in_trans(trans, root); | ||
904 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); | 970 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); |
905 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); | 971 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); |
906 | btrfs_check_and_init_root_item(new_root_item); | 972 | btrfs_check_and_init_root_item(new_root_item); |
@@ -961,14 +1027,6 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, | |||
961 | int ret; | 1027 | int ret; |
962 | 1028 | ||
963 | list_for_each_entry(pending, head, list) { | 1029 | list_for_each_entry(pending, head, list) { |
964 | /* | ||
965 | * We must deal with the delayed items before creating | ||
966 | * snapshots, or we will create a snapthot with inconsistent | ||
967 | * information. | ||
968 | */ | ||
969 | ret = btrfs_run_delayed_items(trans, fs_info->fs_root); | ||
970 | BUG_ON(ret); | ||
971 | |||
972 | ret = create_pending_snapshot(trans, fs_info, pending); | 1030 | ret = create_pending_snapshot(trans, fs_info, pending); |
973 | BUG_ON(ret); | 1031 | BUG_ON(ret); |
974 | } | 1032 | } |
@@ -1118,8 +1176,11 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1118 | wait_current_trans_commit_start_and_unblock(root, cur_trans); | 1176 | wait_current_trans_commit_start_and_unblock(root, cur_trans); |
1119 | else | 1177 | else |
1120 | wait_current_trans_commit_start(root, cur_trans); | 1178 | wait_current_trans_commit_start(root, cur_trans); |
1121 | put_transaction(cur_trans); | ||
1122 | 1179 | ||
1180 | if (current->journal_info == trans) | ||
1181 | current->journal_info = NULL; | ||
1182 | |||
1183 | put_transaction(cur_trans); | ||
1123 | return 0; | 1184 | return 0; |
1124 | } | 1185 | } |
1125 | 1186 | ||
@@ -1238,21 +1299,42 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1238 | schedule_timeout(1); | 1299 | schedule_timeout(1); |
1239 | 1300 | ||
1240 | finish_wait(&cur_trans->writer_wait, &wait); | 1301 | finish_wait(&cur_trans->writer_wait, &wait); |
1241 | spin_lock(&root->fs_info->trans_lock); | ||
1242 | root->fs_info->trans_no_join = 1; | ||
1243 | spin_unlock(&root->fs_info->trans_lock); | ||
1244 | } while (atomic_read(&cur_trans->num_writers) > 1 || | 1302 | } while (atomic_read(&cur_trans->num_writers) > 1 || |
1245 | (should_grow && cur_trans->num_joined != joined)); | 1303 | (should_grow && cur_trans->num_joined != joined)); |
1246 | 1304 | ||
1247 | ret = create_pending_snapshots(trans, root->fs_info); | 1305 | /* |
1248 | BUG_ON(ret); | 1306 | * Ok now we need to make sure to block out any other joins while we |
1307 | * commit the transaction. We could have started a join before setting | ||
1308 | * no_join so make sure to wait for num_writers to == 1 again. | ||
1309 | */ | ||
1310 | spin_lock(&root->fs_info->trans_lock); | ||
1311 | root->fs_info->trans_no_join = 1; | ||
1312 | spin_unlock(&root->fs_info->trans_lock); | ||
1313 | wait_event(cur_trans->writer_wait, | ||
1314 | atomic_read(&cur_trans->num_writers) == 1); | ||
1315 | |||
1316 | /* | ||
1317 | * the reloc mutex makes sure that we stop | ||
1318 | * the balancing code from coming in and moving | ||
1319 | * extents around in the middle of the commit | ||
1320 | */ | ||
1321 | mutex_lock(&root->fs_info->reloc_mutex); | ||
1249 | 1322 | ||
1250 | ret = btrfs_run_delayed_items(trans, root); | 1323 | ret = btrfs_run_delayed_items(trans, root); |
1251 | BUG_ON(ret); | 1324 | BUG_ON(ret); |
1252 | 1325 | ||
1326 | ret = create_pending_snapshots(trans, root->fs_info); | ||
1327 | BUG_ON(ret); | ||
1328 | |||
1253 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 1329 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
1254 | BUG_ON(ret); | 1330 | BUG_ON(ret); |
1255 | 1331 | ||
1332 | /* | ||
1333 | * make sure none of the code above managed to slip in a | ||
1334 | * delayed item | ||
1335 | */ | ||
1336 | btrfs_assert_delayed_root_empty(root); | ||
1337 | |||
1256 | WARN_ON(cur_trans != trans->transaction); | 1338 | WARN_ON(cur_trans != trans->transaction); |
1257 | 1339 | ||
1258 | btrfs_scrub_pause(root); | 1340 | btrfs_scrub_pause(root); |
@@ -1309,6 +1391,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1309 | root->fs_info->running_transaction = NULL; | 1391 | root->fs_info->running_transaction = NULL; |
1310 | root->fs_info->trans_no_join = 0; | 1392 | root->fs_info->trans_no_join = 0; |
1311 | spin_unlock(&root->fs_info->trans_lock); | 1393 | spin_unlock(&root->fs_info->trans_lock); |
1394 | mutex_unlock(&root->fs_info->reloc_mutex); | ||
1312 | 1395 | ||
1313 | wake_up(&root->fs_info->transaction_wait); | 1396 | wake_up(&root->fs_info->transaction_wait); |
1314 | 1397 | ||
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 592396c6dc47..4ce8a9f41d1e 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -3177,7 +3177,7 @@ again: | |||
3177 | tmp_key.offset = (u64)-1; | 3177 | tmp_key.offset = (u64)-1; |
3178 | 3178 | ||
3179 | wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key); | 3179 | wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key); |
3180 | BUG_ON(!wc.replay_dest); | 3180 | BUG_ON(IS_ERR_OR_NULL(wc.replay_dest)); |
3181 | 3181 | ||
3182 | wc.replay_dest->log_root = log; | 3182 | wc.replay_dest->log_root = log; |
3183 | btrfs_record_root_in_trans(trans, wc.replay_dest); | 3183 | btrfs_record_root_in_trans(trans, wc.replay_dest); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index da541dfca2e3..19450bc53632 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -689,12 +689,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
689 | transid = btrfs_super_generation(disk_super); | 689 | transid = btrfs_super_generation(disk_super); |
690 | if (disk_super->label[0]) | 690 | if (disk_super->label[0]) |
691 | printk(KERN_INFO "device label %s ", disk_super->label); | 691 | printk(KERN_INFO "device label %s ", disk_super->label); |
692 | else { | 692 | else |
693 | /* FIXME, make a readl uuid parser */ | 693 | printk(KERN_INFO "device fsid %pU ", disk_super->fsid); |
694 | printk(KERN_INFO "device fsid %llx-%llx ", | ||
695 | *(unsigned long long *)disk_super->fsid, | ||
696 | *(unsigned long long *)(disk_super->fsid + 8)); | ||
697 | } | ||
698 | printk(KERN_CONT "devid %llu transid %llu %s\n", | 694 | printk(KERN_CONT "devid %llu transid %llu %s\n", |
699 | (unsigned long long)devid, (unsigned long long)transid, path); | 695 | (unsigned long long)devid, (unsigned long long)transid, path); |
700 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); | 696 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); |
@@ -2102,7 +2098,8 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
2102 | chunk_root->root_key.objectid, | 2098 | chunk_root->root_key.objectid, |
2103 | found_key.objectid, | 2099 | found_key.objectid, |
2104 | found_key.offset); | 2100 | found_key.offset); |
2105 | BUG_ON(ret && ret != -ENOSPC); | 2101 | if (ret && ret != -ENOSPC) |
2102 | goto error; | ||
2106 | key.offset = found_key.offset - 1; | 2103 | key.offset = found_key.offset - 1; |
2107 | } | 2104 | } |
2108 | ret = 0; | 2105 | ret = 0; |
diff --git a/fs/buffer.c b/fs/buffer.c index 49c9aada0374..1a80b048ade8 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1902,10 +1902,8 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len, | |||
1902 | if (!buffer_uptodate(*wait_bh)) | 1902 | if (!buffer_uptodate(*wait_bh)) |
1903 | err = -EIO; | 1903 | err = -EIO; |
1904 | } | 1904 | } |
1905 | if (unlikely(err)) { | 1905 | if (unlikely(err)) |
1906 | page_zero_new_buffers(page, from, to); | 1906 | page_zero_new_buffers(page, from, to); |
1907 | ClearPageUptodate(page); | ||
1908 | } | ||
1909 | return err; | 1907 | return err; |
1910 | } | 1908 | } |
1911 | EXPORT_SYMBOL(__block_write_begin); | 1909 | EXPORT_SYMBOL(__block_write_begin); |
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 33da49dc3cc6..5a3953db8118 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -453,7 +453,7 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc) | |||
453 | int err; | 453 | int err; |
454 | struct inode *inode = page->mapping->host; | 454 | struct inode *inode = page->mapping->host; |
455 | BUG_ON(!inode); | 455 | BUG_ON(!inode); |
456 | igrab(inode); | 456 | ihold(inode); |
457 | err = writepage_nounlock(page, wbc); | 457 | err = writepage_nounlock(page, wbc); |
458 | unlock_page(page); | 458 | unlock_page(page); |
459 | iput(inode); | 459 | iput(inode); |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 1f72b00447c4..f605753c8fe9 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -2940,14 +2940,12 @@ void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc) | |||
2940 | while (!list_empty(&mdsc->cap_dirty)) { | 2940 | while (!list_empty(&mdsc->cap_dirty)) { |
2941 | ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info, | 2941 | ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info, |
2942 | i_dirty_item); | 2942 | i_dirty_item); |
2943 | inode = igrab(&ci->vfs_inode); | 2943 | inode = &ci->vfs_inode; |
2944 | ihold(inode); | ||
2944 | dout("flush_dirty_caps %p\n", inode); | 2945 | dout("flush_dirty_caps %p\n", inode); |
2945 | spin_unlock(&mdsc->cap_dirty_lock); | 2946 | spin_unlock(&mdsc->cap_dirty_lock); |
2946 | if (inode) { | 2947 | ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, NULL); |
2947 | ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, | 2948 | iput(inode); |
2948 | NULL); | ||
2949 | iput(inode); | ||
2950 | } | ||
2951 | spin_lock(&mdsc->cap_dirty_lock); | 2949 | spin_lock(&mdsc->cap_dirty_lock); |
2952 | } | 2950 | } |
2953 | spin_unlock(&mdsc->cap_dirty_lock); | 2951 | spin_unlock(&mdsc->cap_dirty_lock); |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 33729e822bb9..ef8f08c343e8 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -308,7 +308,8 @@ more: | |||
308 | req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); | 308 | req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); |
309 | if (IS_ERR(req)) | 309 | if (IS_ERR(req)) |
310 | return PTR_ERR(req); | 310 | return PTR_ERR(req); |
311 | req->r_inode = igrab(inode); | 311 | req->r_inode = inode; |
312 | ihold(inode); | ||
312 | req->r_dentry = dget(filp->f_dentry); | 313 | req->r_dentry = dget(filp->f_dentry); |
313 | /* hints to request -> mds selection code */ | 314 | /* hints to request -> mds selection code */ |
314 | req->r_direct_mode = USE_AUTH_MDS; | 315 | req->r_direct_mode = USE_AUTH_MDS; |
@@ -787,10 +788,12 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir, | |||
787 | req->r_dentry_drop = CEPH_CAP_FILE_SHARED; | 788 | req->r_dentry_drop = CEPH_CAP_FILE_SHARED; |
788 | req->r_dentry_unless = CEPH_CAP_FILE_EXCL; | 789 | req->r_dentry_unless = CEPH_CAP_FILE_EXCL; |
789 | err = ceph_mdsc_do_request(mdsc, dir, req); | 790 | err = ceph_mdsc_do_request(mdsc, dir, req); |
790 | if (err) | 791 | if (err) { |
791 | d_drop(dentry); | 792 | d_drop(dentry); |
792 | else if (!req->r_reply_info.head->is_dentry) | 793 | } else if (!req->r_reply_info.head->is_dentry) { |
793 | d_instantiate(dentry, igrab(old_dentry->d_inode)); | 794 | ihold(old_dentry->d_inode); |
795 | d_instantiate(dentry, old_dentry->d_inode); | ||
796 | } | ||
794 | ceph_mdsc_put_request(req); | 797 | ceph_mdsc_put_request(req); |
795 | return err; | 798 | return err; |
796 | } | 799 | } |
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index a610d3d67488..f67b687550de 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
@@ -109,7 +109,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, | |||
109 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 109 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
110 | inode = req->r_target_inode; | 110 | inode = req->r_target_inode; |
111 | if (inode) | 111 | if (inode) |
112 | igrab(inode); | 112 | ihold(inode); |
113 | ceph_mdsc_put_request(req); | 113 | ceph_mdsc_put_request(req); |
114 | if (!inode) | 114 | if (!inode) |
115 | return ERR_PTR(-ESTALE); | 115 | return ERR_PTR(-ESTALE); |
@@ -167,7 +167,7 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb, | |||
167 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 167 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
168 | inode = req->r_target_inode; | 168 | inode = req->r_target_inode; |
169 | if (inode) | 169 | if (inode) |
170 | igrab(inode); | 170 | ihold(inode); |
171 | ceph_mdsc_put_request(req); | 171 | ceph_mdsc_put_request(req); |
172 | if (!inode) | 172 | if (!inode) |
173 | return ERR_PTR(err ? err : -ESTALE); | 173 | return ERR_PTR(err ? err : -ESTALE); |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 203252d88d9f..4698a5c553dc 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -191,7 +191,8 @@ int ceph_open(struct inode *inode, struct file *file) | |||
191 | err = PTR_ERR(req); | 191 | err = PTR_ERR(req); |
192 | goto out; | 192 | goto out; |
193 | } | 193 | } |
194 | req->r_inode = igrab(inode); | 194 | req->r_inode = inode; |
195 | ihold(inode); | ||
195 | req->r_num_caps = 1; | 196 | req->r_num_caps = 1; |
196 | err = ceph_mdsc_do_request(mdsc, parent_inode, req); | 197 | err = ceph_mdsc_do_request(mdsc, parent_inode, req); |
197 | if (!err) | 198 | if (!err) |
@@ -282,14 +283,13 @@ int ceph_release(struct inode *inode, struct file *file) | |||
282 | static int striped_read(struct inode *inode, | 283 | static int striped_read(struct inode *inode, |
283 | u64 off, u64 len, | 284 | u64 off, u64 len, |
284 | struct page **pages, int num_pages, | 285 | struct page **pages, int num_pages, |
285 | int *checkeof, bool align_to_pages, | 286 | int *checkeof, bool o_direct, |
286 | unsigned long buf_align) | 287 | unsigned long buf_align) |
287 | { | 288 | { |
288 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); | 289 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); |
289 | struct ceph_inode_info *ci = ceph_inode(inode); | 290 | struct ceph_inode_info *ci = ceph_inode(inode); |
290 | u64 pos, this_len; | 291 | u64 pos, this_len; |
291 | int io_align, page_align; | 292 | int io_align, page_align; |
292 | int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */ | ||
293 | int left, pages_left; | 293 | int left, pages_left; |
294 | int read; | 294 | int read; |
295 | struct page **page_pos; | 295 | struct page **page_pos; |
@@ -307,7 +307,7 @@ static int striped_read(struct inode *inode, | |||
307 | io_align = off & ~PAGE_MASK; | 307 | io_align = off & ~PAGE_MASK; |
308 | 308 | ||
309 | more: | 309 | more: |
310 | if (align_to_pages) | 310 | if (o_direct) |
311 | page_align = (pos - io_align + buf_align) & ~PAGE_MASK; | 311 | page_align = (pos - io_align + buf_align) & ~PAGE_MASK; |
312 | else | 312 | else |
313 | page_align = pos & ~PAGE_MASK; | 313 | page_align = pos & ~PAGE_MASK; |
@@ -317,20 +317,19 @@ more: | |||
317 | ci->i_truncate_seq, | 317 | ci->i_truncate_seq, |
318 | ci->i_truncate_size, | 318 | ci->i_truncate_size, |
319 | page_pos, pages_left, page_align); | 319 | page_pos, pages_left, page_align); |
320 | hit_stripe = this_len < left; | ||
321 | was_short = ret >= 0 && ret < this_len; | ||
322 | if (ret == -ENOENT) | 320 | if (ret == -ENOENT) |
323 | ret = 0; | 321 | ret = 0; |
322 | hit_stripe = this_len < left; | ||
323 | was_short = ret >= 0 && ret < this_len; | ||
324 | dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read, | 324 | dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read, |
325 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); | 325 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); |
326 | 326 | ||
327 | if (ret > 0) { | 327 | if (ret > 0) { |
328 | int didpages = | 328 | int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; |
329 | ((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT; | ||
330 | 329 | ||
331 | if (read < pos - off) { | 330 | if (read < pos - off) { |
332 | dout(" zero gap %llu to %llu\n", off + read, pos); | 331 | dout(" zero gap %llu to %llu\n", off + read, pos); |
333 | ceph_zero_page_vector_range(page_off + read, | 332 | ceph_zero_page_vector_range(page_align + read, |
334 | pos - off - read, pages); | 333 | pos - off - read, pages); |
335 | } | 334 | } |
336 | pos += ret; | 335 | pos += ret; |
@@ -345,20 +344,22 @@ more: | |||
345 | } | 344 | } |
346 | 345 | ||
347 | if (was_short) { | 346 | if (was_short) { |
348 | /* was original extent fully inside i_size? */ | 347 | /* did we bounce off eof? */ |
349 | if (pos + left <= inode->i_size) { | 348 | if (pos + left > inode->i_size) |
350 | dout("zero tail\n"); | 349 | *checkeof = 1; |
351 | ceph_zero_page_vector_range(page_off + read, len - read, | 350 | |
351 | /* zero trailing bytes (inside i_size) */ | ||
352 | if (left > 0 && pos < inode->i_size) { | ||
353 | if (pos + left > inode->i_size) | ||
354 | left = inode->i_size - pos; | ||
355 | |||
356 | dout("zero tail %d\n", left); | ||
357 | ceph_zero_page_vector_range(page_align + read, left, | ||
352 | pages); | 358 | pages); |
353 | read = len; | 359 | read += left; |
354 | goto out; | ||
355 | } | 360 | } |
356 | |||
357 | /* check i_size */ | ||
358 | *checkeof = 1; | ||
359 | } | 361 | } |
360 | 362 | ||
361 | out: | ||
362 | if (ret >= 0) | 363 | if (ret >= 0) |
363 | ret = read; | 364 | ret = read; |
364 | dout("striped_read returns %d\n", ret); | 365 | dout("striped_read returns %d\n", ret); |
@@ -475,9 +476,6 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
475 | else | 476 | else |
476 | pos = *offset; | 477 | pos = *offset; |
477 | 478 | ||
478 | io_align = pos & ~PAGE_MASK; | ||
479 | buf_align = (unsigned long)data & ~PAGE_MASK; | ||
480 | |||
481 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); | 479 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); |
482 | if (ret < 0) | 480 | if (ret < 0) |
483 | return ret; | 481 | return ret; |
@@ -501,6 +499,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
501 | * boundary. this isn't atomic, unfortunately. :( | 499 | * boundary. this isn't atomic, unfortunately. :( |
502 | */ | 500 | */ |
503 | more: | 501 | more: |
502 | io_align = pos & ~PAGE_MASK; | ||
503 | buf_align = (unsigned long)data & ~PAGE_MASK; | ||
504 | len = left; | 504 | len = left; |
505 | if (file->f_flags & O_DIRECT) { | 505 | if (file->f_flags & O_DIRECT) { |
506 | /* write from beginning of first page, regardless of | 506 | /* write from beginning of first page, regardless of |
@@ -590,6 +590,7 @@ out: | |||
590 | pos += len; | 590 | pos += len; |
591 | written += len; | 591 | written += len; |
592 | left -= len; | 592 | left -= len; |
593 | data += written; | ||
593 | if (left) | 594 | if (left) |
594 | goto more; | 595 | goto more; |
595 | 596 | ||
@@ -658,7 +659,7 @@ out: | |||
658 | 659 | ||
659 | /* hit EOF or hole? */ | 660 | /* hit EOF or hole? */ |
660 | if (statret == 0 && *ppos < inode->i_size) { | 661 | if (statret == 0 && *ppos < inode->i_size) { |
661 | dout("aio_read sync_read hit hole, reading more\n"); | 662 | dout("aio_read sync_read hit hole, ppos %lld < size %lld, reading more\n", *ppos, inode->i_size); |
662 | read += ret; | 663 | read += ret; |
663 | base += ret; | 664 | base += ret; |
664 | len -= ret; | 665 | len -= ret; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 70b6a4839c38..d8858e96ab18 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -1101,10 +1101,10 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1101 | goto done; | 1101 | goto done; |
1102 | } | 1102 | } |
1103 | req->r_dentry = dn; /* may have spliced */ | 1103 | req->r_dentry = dn; /* may have spliced */ |
1104 | igrab(in); | 1104 | ihold(in); |
1105 | } else if (ceph_ino(in) == vino.ino && | 1105 | } else if (ceph_ino(in) == vino.ino && |
1106 | ceph_snap(in) == vino.snap) { | 1106 | ceph_snap(in) == vino.snap) { |
1107 | igrab(in); | 1107 | ihold(in); |
1108 | } else { | 1108 | } else { |
1109 | dout(" %p links to %p %llx.%llx, not %llx.%llx\n", | 1109 | dout(" %p links to %p %llx.%llx, not %llx.%llx\n", |
1110 | dn, in, ceph_ino(in), ceph_snap(in), | 1110 | dn, in, ceph_ino(in), ceph_snap(in), |
@@ -1144,7 +1144,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1144 | goto done; | 1144 | goto done; |
1145 | } | 1145 | } |
1146 | req->r_dentry = dn; /* may have spliced */ | 1146 | req->r_dentry = dn; /* may have spliced */ |
1147 | igrab(in); | 1147 | ihold(in); |
1148 | rinfo->head->is_dentry = 1; /* fool notrace handlers */ | 1148 | rinfo->head->is_dentry = 1; /* fool notrace handlers */ |
1149 | } | 1149 | } |
1150 | 1150 | ||
@@ -1328,7 +1328,7 @@ void ceph_queue_writeback(struct inode *inode) | |||
1328 | if (queue_work(ceph_inode_to_client(inode)->wb_wq, | 1328 | if (queue_work(ceph_inode_to_client(inode)->wb_wq, |
1329 | &ceph_inode(inode)->i_wb_work)) { | 1329 | &ceph_inode(inode)->i_wb_work)) { |
1330 | dout("ceph_queue_writeback %p\n", inode); | 1330 | dout("ceph_queue_writeback %p\n", inode); |
1331 | igrab(inode); | 1331 | ihold(inode); |
1332 | } else { | 1332 | } else { |
1333 | dout("ceph_queue_writeback %p failed\n", inode); | 1333 | dout("ceph_queue_writeback %p failed\n", inode); |
1334 | } | 1334 | } |
@@ -1353,7 +1353,7 @@ void ceph_queue_invalidate(struct inode *inode) | |||
1353 | if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, | 1353 | if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, |
1354 | &ceph_inode(inode)->i_pg_inv_work)) { | 1354 | &ceph_inode(inode)->i_pg_inv_work)) { |
1355 | dout("ceph_queue_invalidate %p\n", inode); | 1355 | dout("ceph_queue_invalidate %p\n", inode); |
1356 | igrab(inode); | 1356 | ihold(inode); |
1357 | } else { | 1357 | } else { |
1358 | dout("ceph_queue_invalidate %p failed\n", inode); | 1358 | dout("ceph_queue_invalidate %p failed\n", inode); |
1359 | } | 1359 | } |
@@ -1477,7 +1477,7 @@ void ceph_queue_vmtruncate(struct inode *inode) | |||
1477 | if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq, | 1477 | if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq, |
1478 | &ci->i_vmtruncate_work)) { | 1478 | &ci->i_vmtruncate_work)) { |
1479 | dout("ceph_queue_vmtruncate %p\n", inode); | 1479 | dout("ceph_queue_vmtruncate %p\n", inode); |
1480 | igrab(inode); | 1480 | ihold(inode); |
1481 | } else { | 1481 | } else { |
1482 | dout("ceph_queue_vmtruncate %p failed, pending=%d\n", | 1482 | dout("ceph_queue_vmtruncate %p failed, pending=%d\n", |
1483 | inode, ci->i_truncate_pending); | 1483 | inode, ci->i_truncate_pending); |
@@ -1738,7 +1738,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) | |||
1738 | __mark_inode_dirty(inode, inode_dirty_flags); | 1738 | __mark_inode_dirty(inode, inode_dirty_flags); |
1739 | 1739 | ||
1740 | if (mask) { | 1740 | if (mask) { |
1741 | req->r_inode = igrab(inode); | 1741 | req->r_inode = inode; |
1742 | ihold(inode); | ||
1742 | req->r_inode_drop = release; | 1743 | req->r_inode_drop = release; |
1743 | req->r_args.setattr.mask = cpu_to_le32(mask); | 1744 | req->r_args.setattr.mask = cpu_to_le32(mask); |
1744 | req->r_num_caps = 1; | 1745 | req->r_num_caps = 1; |
@@ -1779,7 +1780,8 @@ int ceph_do_getattr(struct inode *inode, int mask) | |||
1779 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); | 1780 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); |
1780 | if (IS_ERR(req)) | 1781 | if (IS_ERR(req)) |
1781 | return PTR_ERR(req); | 1782 | return PTR_ERR(req); |
1782 | req->r_inode = igrab(inode); | 1783 | req->r_inode = inode; |
1784 | ihold(inode); | ||
1783 | req->r_num_caps = 1; | 1785 | req->r_num_caps = 1; |
1784 | req->r_args.getattr.mask = cpu_to_le32(mask); | 1786 | req->r_args.getattr.mask = cpu_to_le32(mask); |
1785 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 1787 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 8888c9ba68db..ef0b5f48e13a 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
@@ -73,7 +73,8 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
73 | USE_AUTH_MDS); | 73 | USE_AUTH_MDS); |
74 | if (IS_ERR(req)) | 74 | if (IS_ERR(req)) |
75 | return PTR_ERR(req); | 75 | return PTR_ERR(req); |
76 | req->r_inode = igrab(inode); | 76 | req->r_inode = inode; |
77 | ihold(inode); | ||
77 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; | 78 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; |
78 | 79 | ||
79 | req->r_args.setlayout.layout.fl_stripe_unit = | 80 | req->r_args.setlayout.layout.fl_stripe_unit = |
@@ -135,7 +136,8 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg) | |||
135 | 136 | ||
136 | if (IS_ERR(req)) | 137 | if (IS_ERR(req)) |
137 | return PTR_ERR(req); | 138 | return PTR_ERR(req); |
138 | req->r_inode = igrab(inode); | 139 | req->r_inode = inode; |
140 | ihold(inode); | ||
139 | 141 | ||
140 | req->r_args.setlayout.layout.fl_stripe_unit = | 142 | req->r_args.setlayout.layout.fl_stripe_unit = |
141 | cpu_to_le32(l.stripe_unit); | 143 | cpu_to_le32(l.stripe_unit); |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 476b329867d4..80576d05d687 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -23,7 +23,8 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); | 23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); |
24 | if (IS_ERR(req)) | 24 | if (IS_ERR(req)) |
25 | return PTR_ERR(req); | 25 | return PTR_ERR(req); |
26 | req->r_inode = igrab(inode); | 26 | req->r_inode = inode; |
27 | ihold(inode); | ||
27 | 28 | ||
28 | /* mds requires start and length rather than start and end */ | 29 | /* mds requires start and length rather than start and end */ |
29 | if (LLONG_MAX == fl->fl_end) | 30 | if (LLONG_MAX == fl->fl_end) |
@@ -32,11 +33,10 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
32 | length = fl->fl_end - fl->fl_start + 1; | 33 | length = fl->fl_end - fl->fl_start + 1; |
33 | 34 | ||
34 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 35 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
35 | "length: %llu, wait: %d, type`: %d", (int)lock_type, | 36 | "length: %llu, wait: %d, type: %d", (int)lock_type, |
36 | (int)operation, (u64)fl->fl_pid, fl->fl_start, | 37 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
37 | length, wait, fl->fl_type); | 38 | length, wait, fl->fl_type); |
38 | 39 | ||
39 | |||
40 | req->r_args.filelock_change.rule = lock_type; | 40 | req->r_args.filelock_change.rule = lock_type; |
41 | req->r_args.filelock_change.type = cmd; | 41 | req->r_args.filelock_change.type = cmd; |
42 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); | 42 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); |
@@ -70,7 +70,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
70 | } | 70 | } |
71 | ceph_mdsc_put_request(req); | 71 | ceph_mdsc_put_request(req); |
72 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 72 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
73 | "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type, | 73 | "length: %llu, wait: %d, type: %d, err code %d", (int)lock_type, |
74 | (int)operation, (u64)fl->fl_pid, fl->fl_start, | 74 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
75 | length, wait, fl->fl_type, err); | 75 | length, wait, fl->fl_type, err); |
76 | return err; | 76 | return err; |
@@ -109,16 +109,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
109 | dout("mds locked, locking locally"); | 109 | dout("mds locked, locking locally"); |
110 | err = posix_lock_file(file, fl, NULL); | 110 | err = posix_lock_file(file, fl, NULL); |
111 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { | 111 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { |
112 | /* undo! This should only happen if the kernel detects | 112 | /* undo! This should only happen if |
113 | * local deadlock. */ | 113 | * the kernel detects local |
114 | * deadlock. */ | ||
114 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 115 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
115 | CEPH_LOCK_UNLOCK, 0, fl); | 116 | CEPH_LOCK_UNLOCK, 0, fl); |
116 | dout("got %d on posix_lock_file, undid lock", err); | 117 | dout("got %d on posix_lock_file, undid lock", |
118 | err); | ||
117 | } | 119 | } |
118 | } | 120 | } |
119 | 121 | ||
120 | } else { | 122 | } else if (err == -ERESTARTSYS) { |
121 | dout("mds returned error code %d", err); | 123 | dout("undoing lock\n"); |
124 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | ||
125 | CEPH_LOCK_UNLOCK, 0, fl); | ||
122 | } | 126 | } |
123 | return err; | 127 | return err; |
124 | } | 128 | } |
@@ -155,8 +159,11 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
155 | file, CEPH_LOCK_UNLOCK, 0, fl); | 159 | file, CEPH_LOCK_UNLOCK, 0, fl); |
156 | dout("got %d on flock_lock_file_wait, undid lock", err); | 160 | dout("got %d on flock_lock_file_wait, undid lock", err); |
157 | } | 161 | } |
158 | } else { | 162 | } else if (err == -ERESTARTSYS) { |
159 | dout("mds error code %d", err); | 163 | dout("undoing lock\n"); |
164 | ceph_lock_message(CEPH_LOCK_FLOCK, | ||
165 | CEPH_MDS_OP_SETFILELOCK, | ||
166 | file, CEPH_LOCK_UNLOCK, 0, fl); | ||
160 | } | 167 | } |
161 | return err; | 168 | return err; |
162 | } | 169 | } |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 24067d68a554..54b14de2e729 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -722,7 +722,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc) | |||
722 | ci = list_first_entry(&mdsc->snap_flush_list, | 722 | ci = list_first_entry(&mdsc->snap_flush_list, |
723 | struct ceph_inode_info, i_snap_flush_item); | 723 | struct ceph_inode_info, i_snap_flush_item); |
724 | inode = &ci->vfs_inode; | 724 | inode = &ci->vfs_inode; |
725 | igrab(inode); | 725 | ihold(inode); |
726 | spin_unlock(&mdsc->snap_flush_lock); | 726 | spin_unlock(&mdsc->snap_flush_lock); |
727 | spin_lock(&inode->i_lock); | 727 | spin_lock(&inode->i_lock); |
728 | __ceph_flush_snaps(ci, &session, 0); | 728 | __ceph_flush_snaps(ci, &session, 0); |
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index f2b628696180..f42d730f1b66 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -665,7 +665,8 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name, | |||
665 | err = PTR_ERR(req); | 665 | err = PTR_ERR(req); |
666 | goto out; | 666 | goto out; |
667 | } | 667 | } |
668 | req->r_inode = igrab(inode); | 668 | req->r_inode = inode; |
669 | ihold(inode); | ||
669 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; | 670 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; |
670 | req->r_num_caps = 1; | 671 | req->r_num_caps = 1; |
671 | req->r_args.setxattr.flags = cpu_to_le32(flags); | 672 | req->r_args.setxattr.flags = cpu_to_le32(flags); |
@@ -795,7 +796,8 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name) | |||
795 | USE_AUTH_MDS); | 796 | USE_AUTH_MDS); |
796 | if (IS_ERR(req)) | 797 | if (IS_ERR(req)) |
797 | return PTR_ERR(req); | 798 | return PTR_ERR(req); |
798 | req->r_inode = igrab(inode); | 799 | req->r_inode = inode; |
800 | ihold(inode); | ||
799 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; | 801 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; |
800 | req->r_num_caps = 1; | 802 | req->r_num_caps = 1; |
801 | req->r_path2 = kstrdup(name, GFP_NOFS); | 803 | req->r_path2 = kstrdup(name, GFP_NOFS); |
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 1cd4c3a1862d..f66cc1625150 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -7,6 +7,7 @@ config CIFS | |||
7 | select CRYPTO_MD5 | 7 | select CRYPTO_MD5 |
8 | select CRYPTO_HMAC | 8 | select CRYPTO_HMAC |
9 | select CRYPTO_ARC4 | 9 | select CRYPTO_ARC4 |
10 | select CRYPTO_ECB | ||
10 | select CRYPTO_DES | 11 | select CRYPTO_DES |
11 | help | 12 | help |
12 | This is the client VFS module for the Common Internet File System | 13 | This is the client VFS module for the Common Internet File System |
@@ -148,13 +149,13 @@ config CIFS_FSCACHE | |||
148 | 149 | ||
149 | config CIFS_ACL | 150 | config CIFS_ACL |
150 | bool "Provide CIFS ACL support (EXPERIMENTAL)" | 151 | bool "Provide CIFS ACL support (EXPERIMENTAL)" |
151 | depends on EXPERIMENTAL && CIFS_XATTR | 152 | depends on EXPERIMENTAL && CIFS_XATTR && KEYS |
152 | help | 153 | help |
153 | Allows to fetch CIFS/NTFS ACL from the server. The DACL blob | 154 | Allows to fetch CIFS/NTFS ACL from the server. The DACL blob |
154 | is handed over to the application/caller. | 155 | is handed over to the application/caller. |
155 | 156 | ||
156 | config CIFS_NFSD_EXPORT | 157 | config CIFS_NFSD_EXPORT |
157 | bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)" | 158 | bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)" |
158 | depends on CIFS && EXPERIMENTAL | 159 | depends on CIFS && EXPERIMENTAL && BROKEN |
159 | help | 160 | help |
160 | Allows NFS server to export a CIFS mounted share (nfsd over cifs) | 161 | Allows NFS server to export a CIFS mounted share (nfsd over cifs) |
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c index dd8584d35a14..545509c3313b 100644 --- a/fs/cifs/cache.c +++ b/fs/cifs/cache.c | |||
@@ -92,7 +92,7 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data, | |||
92 | break; | 92 | break; |
93 | 93 | ||
94 | default: | 94 | default: |
95 | cERROR(1, "CIFS: Unknown network family '%d'", sa->sa_family); | 95 | cERROR(1, "Unknown network family '%d'", sa->sa_family); |
96 | key_len = 0; | 96 | key_len = 0; |
97 | break; | 97 | break; |
98 | } | 98 | } |
@@ -152,7 +152,7 @@ static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer, | |||
152 | 152 | ||
153 | sharename = extract_sharename(tcon->treeName); | 153 | sharename = extract_sharename(tcon->treeName); |
154 | if (IS_ERR(sharename)) { | 154 | if (IS_ERR(sharename)) { |
155 | cFYI(1, "CIFS: couldn't extract sharename\n"); | 155 | cFYI(1, "%s: couldn't extract sharename\n", __func__); |
156 | sharename = NULL; | 156 | sharename = NULL; |
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
@@ -302,7 +302,7 @@ static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data) | |||
302 | pagevec_init(&pvec, 0); | 302 | pagevec_init(&pvec, 0); |
303 | first = 0; | 303 | first = 0; |
304 | 304 | ||
305 | cFYI(1, "cifs inode 0x%p now uncached", cifsi); | 305 | cFYI(1, "%s: cifs inode 0x%p now uncached", __func__, cifsi); |
306 | 306 | ||
307 | for (;;) { | 307 | for (;;) { |
308 | nr_pages = pagevec_lookup(&pvec, | 308 | nr_pages = pagevec_lookup(&pvec, |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index ffb1459dc6ec..7260e11e21f8 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ | 42 | #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ |
43 | #define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ | 43 | #define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ |
44 | #define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */ | 44 | #define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */ |
45 | #define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */ | ||
45 | 46 | ||
46 | struct cifs_sb_info { | 47 | struct cifs_sb_info { |
47 | struct rb_root tlink_tree; | 48 | struct rb_root tlink_tree; |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index dfbd9f1f373d..5a0ee7f2af06 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -184,7 +184,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, | |||
184 | if (cifs_pdu == NULL || server == NULL) | 184 | if (cifs_pdu == NULL || server == NULL) |
185 | return -EINVAL; | 185 | return -EINVAL; |
186 | 186 | ||
187 | if (cifs_pdu->Command == SMB_COM_NEGOTIATE) | 187 | if (!server->session_estab) |
188 | return 0; | 188 | return 0; |
189 | 189 | ||
190 | if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { | 190 | if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 989442dcfb45..35f9154615fa 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -104,8 +104,7 @@ cifs_sb_deactive(struct super_block *sb) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | static int | 106 | static int |
107 | cifs_read_super(struct super_block *sb, struct smb_vol *volume_info, | 107 | cifs_read_super(struct super_block *sb) |
108 | const char *devname, int silent) | ||
109 | { | 108 | { |
110 | struct inode *inode; | 109 | struct inode *inode; |
111 | struct cifs_sb_info *cifs_sb; | 110 | struct cifs_sb_info *cifs_sb; |
@@ -113,22 +112,16 @@ cifs_read_super(struct super_block *sb, struct smb_vol *volume_info, | |||
113 | 112 | ||
114 | cifs_sb = CIFS_SB(sb); | 113 | cifs_sb = CIFS_SB(sb); |
115 | 114 | ||
116 | spin_lock_init(&cifs_sb->tlink_tree_lock); | 115 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL) |
117 | cifs_sb->tlink_tree = RB_ROOT; | 116 | sb->s_flags |= MS_POSIXACL; |
118 | 117 | ||
119 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | 118 | if (cifs_sb_master_tcon(cifs_sb)->ses->capabilities & CAP_LARGE_FILES) |
120 | if (rc) | 119 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
121 | return rc; | 120 | else |
122 | 121 | sb->s_maxbytes = MAX_NON_LFS; | |
123 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; | ||
124 | 122 | ||
125 | rc = cifs_mount(sb, cifs_sb, volume_info, devname); | 123 | /* BB FIXME fix time_gran to be larger for LANMAN sessions */ |
126 | 124 | sb->s_time_gran = 100; | |
127 | if (rc) { | ||
128 | if (!silent) | ||
129 | cERROR(1, "cifs_mount failed w/return code = %d", rc); | ||
130 | goto out_mount_failed; | ||
131 | } | ||
132 | 125 | ||
133 | sb->s_magic = CIFS_MAGIC_NUMBER; | 126 | sb->s_magic = CIFS_MAGIC_NUMBER; |
134 | sb->s_op = &cifs_super_ops; | 127 | sb->s_op = &cifs_super_ops; |
@@ -170,37 +163,14 @@ out_no_root: | |||
170 | if (inode) | 163 | if (inode) |
171 | iput(inode); | 164 | iput(inode); |
172 | 165 | ||
173 | cifs_umount(sb, cifs_sb); | ||
174 | |||
175 | out_mount_failed: | ||
176 | bdi_destroy(&cifs_sb->bdi); | ||
177 | return rc; | 166 | return rc; |
178 | } | 167 | } |
179 | 168 | ||
180 | static void | 169 | static void cifs_kill_sb(struct super_block *sb) |
181 | cifs_put_super(struct super_block *sb) | ||
182 | { | 170 | { |
183 | int rc = 0; | 171 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
184 | struct cifs_sb_info *cifs_sb; | 172 | kill_anon_super(sb); |
185 | 173 | cifs_umount(cifs_sb); | |
186 | cFYI(1, "In cifs_put_super"); | ||
187 | cifs_sb = CIFS_SB(sb); | ||
188 | if (cifs_sb == NULL) { | ||
189 | cFYI(1, "Empty cifs superblock info passed to unmount"); | ||
190 | return; | ||
191 | } | ||
192 | |||
193 | rc = cifs_umount(sb, cifs_sb); | ||
194 | if (rc) | ||
195 | cERROR(1, "cifs_umount failed with return code %d", rc); | ||
196 | if (cifs_sb->mountdata) { | ||
197 | kfree(cifs_sb->mountdata); | ||
198 | cifs_sb->mountdata = NULL; | ||
199 | } | ||
200 | |||
201 | unload_nls(cifs_sb->local_nls); | ||
202 | bdi_destroy(&cifs_sb->bdi); | ||
203 | kfree(cifs_sb); | ||
204 | } | 174 | } |
205 | 175 | ||
206 | static int | 176 | static int |
@@ -257,9 +227,6 @@ static int cifs_permission(struct inode *inode, int mask, unsigned int flags) | |||
257 | { | 227 | { |
258 | struct cifs_sb_info *cifs_sb; | 228 | struct cifs_sb_info *cifs_sb; |
259 | 229 | ||
260 | if (flags & IPERM_FLAG_RCU) | ||
261 | return -ECHILD; | ||
262 | |||
263 | cifs_sb = CIFS_SB(inode->i_sb); | 230 | cifs_sb = CIFS_SB(inode->i_sb); |
264 | 231 | ||
265 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { | 232 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { |
@@ -352,6 +319,37 @@ cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) | |||
352 | } | 319 | } |
353 | } | 320 | } |
354 | 321 | ||
322 | static void | ||
323 | cifs_show_security(struct seq_file *s, struct TCP_Server_Info *server) | ||
324 | { | ||
325 | seq_printf(s, ",sec="); | ||
326 | |||
327 | switch (server->secType) { | ||
328 | case LANMAN: | ||
329 | seq_printf(s, "lanman"); | ||
330 | break; | ||
331 | case NTLMv2: | ||
332 | seq_printf(s, "ntlmv2"); | ||
333 | break; | ||
334 | case NTLM: | ||
335 | seq_printf(s, "ntlm"); | ||
336 | break; | ||
337 | case Kerberos: | ||
338 | seq_printf(s, "krb5"); | ||
339 | break; | ||
340 | case RawNTLMSSP: | ||
341 | seq_printf(s, "ntlmssp"); | ||
342 | break; | ||
343 | default: | ||
344 | /* shouldn't ever happen */ | ||
345 | seq_printf(s, "unknown"); | ||
346 | break; | ||
347 | } | ||
348 | |||
349 | if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | ||
350 | seq_printf(s, "i"); | ||
351 | } | ||
352 | |||
355 | /* | 353 | /* |
356 | * cifs_show_options() is for displaying mount options in /proc/mounts. | 354 | * cifs_show_options() is for displaying mount options in /proc/mounts. |
357 | * Not all settable options are displayed but most of the important | 355 | * Not all settable options are displayed but most of the important |
@@ -365,6 +363,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
365 | struct sockaddr *srcaddr; | 363 | struct sockaddr *srcaddr; |
366 | srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; | 364 | srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; |
367 | 365 | ||
366 | cifs_show_security(s, tcon->ses->server); | ||
367 | |||
368 | seq_printf(s, ",unc=%s", tcon->treeName); | 368 | seq_printf(s, ",unc=%s", tcon->treeName); |
369 | 369 | ||
370 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) | 370 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) |
@@ -518,7 +518,6 @@ static int cifs_drop_inode(struct inode *inode) | |||
518 | } | 518 | } |
519 | 519 | ||
520 | static const struct super_operations cifs_super_ops = { | 520 | static const struct super_operations cifs_super_ops = { |
521 | .put_super = cifs_put_super, | ||
522 | .statfs = cifs_statfs, | 521 | .statfs = cifs_statfs, |
523 | .alloc_inode = cifs_alloc_inode, | 522 | .alloc_inode = cifs_alloc_inode, |
524 | .destroy_inode = cifs_destroy_inode, | 523 | .destroy_inode = cifs_destroy_inode, |
@@ -555,7 +554,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
555 | full_path = cifs_build_path_to_root(vol, cifs_sb, | 554 | full_path = cifs_build_path_to_root(vol, cifs_sb, |
556 | cifs_sb_master_tcon(cifs_sb)); | 555 | cifs_sb_master_tcon(cifs_sb)); |
557 | if (full_path == NULL) | 556 | if (full_path == NULL) |
558 | return NULL; | 557 | return ERR_PTR(-ENOMEM); |
559 | 558 | ||
560 | cFYI(1, "Get root dentry for %s", full_path); | 559 | cFYI(1, "Get root dentry for %s", full_path); |
561 | 560 | ||
@@ -584,7 +583,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
584 | dchild = d_alloc(dparent, &name); | 583 | dchild = d_alloc(dparent, &name); |
585 | if (dchild == NULL) { | 584 | if (dchild == NULL) { |
586 | dput(dparent); | 585 | dput(dparent); |
587 | dparent = NULL; | 586 | dparent = ERR_PTR(-ENOMEM); |
588 | goto out; | 587 | goto out; |
589 | } | 588 | } |
590 | } | 589 | } |
@@ -602,7 +601,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
602 | if (rc) { | 601 | if (rc) { |
603 | dput(dchild); | 602 | dput(dchild); |
604 | dput(dparent); | 603 | dput(dparent); |
605 | dparent = NULL; | 604 | dparent = ERR_PTR(rc); |
606 | goto out; | 605 | goto out; |
607 | } | 606 | } |
608 | alias = d_materialise_unique(dchild, inode); | 607 | alias = d_materialise_unique(dchild, inode); |
@@ -610,7 +609,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
610 | dput(dchild); | 609 | dput(dchild); |
611 | if (IS_ERR(alias)) { | 610 | if (IS_ERR(alias)) { |
612 | dput(dparent); | 611 | dput(dparent); |
613 | dparent = NULL; | 612 | dparent = ERR_PTR(-EINVAL); /* XXX */ |
614 | goto out; | 613 | goto out; |
615 | } | 614 | } |
616 | dchild = alias; | 615 | dchild = alias; |
@@ -630,6 +629,13 @@ out: | |||
630 | return dparent; | 629 | return dparent; |
631 | } | 630 | } |
632 | 631 | ||
632 | static int cifs_set_super(struct super_block *sb, void *data) | ||
633 | { | ||
634 | struct cifs_mnt_data *mnt_data = data; | ||
635 | sb->s_fs_info = mnt_data->cifs_sb; | ||
636 | return set_anon_super(sb, NULL); | ||
637 | } | ||
638 | |||
633 | static struct dentry * | 639 | static struct dentry * |
634 | cifs_do_mount(struct file_system_type *fs_type, | 640 | cifs_do_mount(struct file_system_type *fs_type, |
635 | int flags, const char *dev_name, void *data) | 641 | int flags, const char *dev_name, void *data) |
@@ -650,75 +656,73 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
650 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); | 656 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); |
651 | if (cifs_sb == NULL) { | 657 | if (cifs_sb == NULL) { |
652 | root = ERR_PTR(-ENOMEM); | 658 | root = ERR_PTR(-ENOMEM); |
653 | goto out; | 659 | goto out_nls; |
660 | } | ||
661 | |||
662 | cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); | ||
663 | if (cifs_sb->mountdata == NULL) { | ||
664 | root = ERR_PTR(-ENOMEM); | ||
665 | goto out_cifs_sb; | ||
654 | } | 666 | } |
655 | 667 | ||
656 | cifs_setup_cifs_sb(volume_info, cifs_sb); | 668 | cifs_setup_cifs_sb(volume_info, cifs_sb); |
657 | 669 | ||
670 | rc = cifs_mount(cifs_sb, volume_info); | ||
671 | if (rc) { | ||
672 | if (!(flags & MS_SILENT)) | ||
673 | cERROR(1, "cifs_mount failed w/return code = %d", rc); | ||
674 | root = ERR_PTR(rc); | ||
675 | goto out_mountdata; | ||
676 | } | ||
677 | |||
658 | mnt_data.vol = volume_info; | 678 | mnt_data.vol = volume_info; |
659 | mnt_data.cifs_sb = cifs_sb; | 679 | mnt_data.cifs_sb = cifs_sb; |
660 | mnt_data.flags = flags; | 680 | mnt_data.flags = flags; |
661 | 681 | ||
662 | sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data); | 682 | sb = sget(fs_type, cifs_match_super, cifs_set_super, &mnt_data); |
663 | if (IS_ERR(sb)) { | 683 | if (IS_ERR(sb)) { |
664 | root = ERR_CAST(sb); | 684 | root = ERR_CAST(sb); |
665 | goto out_cifs_sb; | 685 | cifs_umount(cifs_sb); |
686 | goto out; | ||
666 | } | 687 | } |
667 | 688 | ||
668 | if (sb->s_fs_info) { | 689 | if (sb->s_root) { |
669 | cFYI(1, "Use existing superblock"); | 690 | cFYI(1, "Use existing superblock"); |
670 | goto out_shared; | 691 | cifs_umount(cifs_sb); |
671 | } | 692 | } else { |
672 | 693 | sb->s_flags = flags; | |
673 | /* | 694 | /* BB should we make this contingent on mount parm? */ |
674 | * Copy mount params for use in submounts. Better to do | 695 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; |
675 | * the copy here and deal with the error before cleanup gets | 696 | |
676 | * complicated post-mount. | 697 | rc = cifs_read_super(sb); |
677 | */ | 698 | if (rc) { |
678 | cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); | 699 | root = ERR_PTR(rc); |
679 | if (cifs_sb->mountdata == NULL) { | 700 | goto out_super; |
680 | root = ERR_PTR(-ENOMEM); | 701 | } |
681 | goto out_super; | ||
682 | } | ||
683 | |||
684 | sb->s_flags = flags; | ||
685 | /* BB should we make this contingent on mount parm? */ | ||
686 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; | ||
687 | sb->s_fs_info = cifs_sb; | ||
688 | 702 | ||
689 | rc = cifs_read_super(sb, volume_info, dev_name, | 703 | sb->s_flags |= MS_ACTIVE; |
690 | flags & MS_SILENT ? 1 : 0); | ||
691 | if (rc) { | ||
692 | root = ERR_PTR(rc); | ||
693 | goto out_super; | ||
694 | } | 704 | } |
695 | 705 | ||
696 | sb->s_flags |= MS_ACTIVE; | ||
697 | |||
698 | root = cifs_get_root(volume_info, sb); | 706 | root = cifs_get_root(volume_info, sb); |
699 | if (root == NULL) | 707 | if (IS_ERR(root)) |
700 | goto out_super; | 708 | goto out_super; |
701 | 709 | ||
702 | cFYI(1, "dentry root is: %p", root); | 710 | cFYI(1, "dentry root is: %p", root); |
703 | goto out; | 711 | goto out; |
704 | 712 | ||
705 | out_shared: | ||
706 | root = cifs_get_root(volume_info, sb); | ||
707 | if (root) | ||
708 | cFYI(1, "dentry root is: %p", root); | ||
709 | goto out; | ||
710 | |||
711 | out_super: | 713 | out_super: |
712 | kfree(cifs_sb->mountdata); | ||
713 | deactivate_locked_super(sb); | 714 | deactivate_locked_super(sb); |
714 | |||
715 | out_cifs_sb: | ||
716 | unload_nls(cifs_sb->local_nls); | ||
717 | kfree(cifs_sb); | ||
718 | |||
719 | out: | 715 | out: |
720 | cifs_cleanup_volume_info(&volume_info); | 716 | cifs_cleanup_volume_info(&volume_info); |
721 | return root; | 717 | return root; |
718 | |||
719 | out_mountdata: | ||
720 | kfree(cifs_sb->mountdata); | ||
721 | out_cifs_sb: | ||
722 | kfree(cifs_sb); | ||
723 | out_nls: | ||
724 | unload_nls(volume_info->local_nls); | ||
725 | goto out; | ||
722 | } | 726 | } |
723 | 727 | ||
724 | static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 728 | static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
@@ -807,7 +811,7 @@ struct file_system_type cifs_fs_type = { | |||
807 | .owner = THIS_MODULE, | 811 | .owner = THIS_MODULE, |
808 | .name = "cifs", | 812 | .name = "cifs", |
809 | .mount = cifs_do_mount, | 813 | .mount = cifs_do_mount, |
810 | .kill_sb = kill_anon_super, | 814 | .kill_sb = cifs_kill_sb, |
811 | /* .fs_flags */ | 815 | /* .fs_flags */ |
812 | }; | 816 | }; |
813 | const struct inode_operations cifs_dir_inode_ops = { | 817 | const struct inode_operations cifs_dir_inode_ops = { |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 64313f778ebf..0900e1658c96 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -129,5 +129,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
129 | extern const struct export_operations cifs_export_ops; | 129 | extern const struct export_operations cifs_export_ops; |
130 | #endif /* CIFS_NFSD_EXPORT */ | 130 | #endif /* CIFS_NFSD_EXPORT */ |
131 | 131 | ||
132 | #define CIFS_VERSION "1.72" | 132 | #define CIFS_VERSION "1.73" |
133 | #endif /* _CIFSFS_H */ | 133 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 953f84413c77..257f312ede42 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -157,9 +157,8 @@ extern int cifs_match_super(struct super_block *, void *); | |||
157 | extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); | 157 | extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); |
158 | extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, | 158 | extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, |
159 | char *mount_data, const char *devname); | 159 | char *mount_data, const char *devname); |
160 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, | 160 | extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); |
161 | struct smb_vol *, const char *); | 161 | extern void cifs_umount(struct cifs_sb_info *); |
162 | extern int cifs_umount(struct super_block *, struct cifs_sb_info *); | ||
163 | extern void cifs_dfs_release_automount_timer(void); | 162 | extern void cifs_dfs_release_automount_timer(void); |
164 | void cifs_proc_init(void); | 163 | void cifs_proc_init(void); |
165 | void cifs_proc_clean(void); | 164 | void cifs_proc_clean(void); |
@@ -218,7 +217,8 @@ extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo, | |||
218 | struct dfs_info3_param **preferrals, | 217 | struct dfs_info3_param **preferrals, |
219 | int remap); | 218 | int remap); |
220 | extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, | 219 | extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, |
221 | struct super_block *sb, struct smb_vol *vol); | 220 | struct cifs_sb_info *cifs_sb, |
221 | struct smb_vol *vol); | ||
222 | extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, | 222 | extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, |
223 | struct kstatfs *FSData); | 223 | struct kstatfs *FSData); |
224 | extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, | 224 | extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 6d88b82537c3..c8cb83ef6f6f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -152,7 +152,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
152 | mid_entry->callback(mid_entry); | 152 | mid_entry->callback(mid_entry); |
153 | } | 153 | } |
154 | 154 | ||
155 | while (server->tcpStatus == CifsNeedReconnect) { | 155 | do { |
156 | try_to_freeze(); | 156 | try_to_freeze(); |
157 | 157 | ||
158 | /* we should try only the port we connected to before */ | 158 | /* we should try only the port we connected to before */ |
@@ -167,7 +167,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
167 | server->tcpStatus = CifsNeedNegotiate; | 167 | server->tcpStatus = CifsNeedNegotiate; |
168 | spin_unlock(&GlobalMid_Lock); | 168 | spin_unlock(&GlobalMid_Lock); |
169 | } | 169 | } |
170 | } | 170 | } while (server->tcpStatus == CifsNeedReconnect); |
171 | 171 | ||
172 | return rc; | 172 | return rc; |
173 | } | 173 | } |
@@ -784,7 +784,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
784 | struct smb_vol *vol) | 784 | struct smb_vol *vol) |
785 | { | 785 | { |
786 | char *value, *data, *end; | 786 | char *value, *data, *end; |
787 | char *mountdata_copy, *options; | 787 | char *mountdata_copy = NULL, *options; |
788 | unsigned int temp_len, i, j; | 788 | unsigned int temp_len, i, j; |
789 | char separator[2]; | 789 | char separator[2]; |
790 | short int override_uid = -1; | 790 | short int override_uid = -1; |
@@ -1391,7 +1391,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1391 | "/proc/fs/cifs/LookupCacheEnabled to 0\n"); | 1391 | "/proc/fs/cifs/LookupCacheEnabled to 0\n"); |
1392 | } else if (strnicmp(data, "fsc", 3) == 0) { | 1392 | } else if (strnicmp(data, "fsc", 3) == 0) { |
1393 | #ifndef CONFIG_CIFS_FSCACHE | 1393 | #ifndef CONFIG_CIFS_FSCACHE |
1394 | cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE" | 1394 | cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE " |
1395 | "kernel config option set"); | 1395 | "kernel config option set"); |
1396 | goto cifs_parse_mount_err; | 1396 | goto cifs_parse_mount_err; |
1397 | #endif | 1397 | #endif |
@@ -1976,7 +1976,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1976 | warned_on_ntlm = true; | 1976 | warned_on_ntlm = true; |
1977 | cERROR(1, "default security mechanism requested. The default " | 1977 | cERROR(1, "default security mechanism requested. The default " |
1978 | "security mechanism will be upgraded from ntlm to " | 1978 | "security mechanism will be upgraded from ntlm to " |
1979 | "ntlmv2 in kernel release 2.6.41"); | 1979 | "ntlmv2 in kernel release 3.1"); |
1980 | } | 1980 | } |
1981 | ses->overrideSecFlg = volume_info->secFlg; | 1981 | ses->overrideSecFlg = volume_info->secFlg; |
1982 | 1982 | ||
@@ -2149,7 +2149,10 @@ cifs_put_tlink(struct tcon_link *tlink) | |||
2149 | } | 2149 | } |
2150 | 2150 | ||
2151 | static inline struct tcon_link * | 2151 | static inline struct tcon_link * |
2152 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb); | 2152 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) |
2153 | { | ||
2154 | return cifs_sb->master_tlink; | ||
2155 | } | ||
2153 | 2156 | ||
2154 | static int | 2157 | static int |
2155 | compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) | 2158 | compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) |
@@ -2471,14 +2474,6 @@ generic_ip_connect(struct TCP_Server_Info *server) | |||
2471 | if (rc < 0) | 2474 | if (rc < 0) |
2472 | return rc; | 2475 | return rc; |
2473 | 2476 | ||
2474 | rc = socket->ops->connect(socket, saddr, slen, 0); | ||
2475 | if (rc < 0) { | ||
2476 | cFYI(1, "Error %d connecting to server", rc); | ||
2477 | sock_release(socket); | ||
2478 | server->ssocket = NULL; | ||
2479 | return rc; | ||
2480 | } | ||
2481 | |||
2482 | /* | 2477 | /* |
2483 | * Eventually check for other socket options to change from | 2478 | * Eventually check for other socket options to change from |
2484 | * the default. sock_setsockopt not used because it expects | 2479 | * the default. sock_setsockopt not used because it expects |
@@ -2507,6 +2502,14 @@ generic_ip_connect(struct TCP_Server_Info *server) | |||
2507 | socket->sk->sk_sndbuf, | 2502 | socket->sk->sk_sndbuf, |
2508 | socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); | 2503 | socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); |
2509 | 2504 | ||
2505 | rc = socket->ops->connect(socket, saddr, slen, 0); | ||
2506 | if (rc < 0) { | ||
2507 | cFYI(1, "Error %d connecting to server", rc); | ||
2508 | sock_release(socket); | ||
2509 | server->ssocket = NULL; | ||
2510 | return rc; | ||
2511 | } | ||
2512 | |||
2510 | if (sport == htons(RFC1001_PORT)) | 2513 | if (sport == htons(RFC1001_PORT)) |
2511 | rc = ip_rfc1001_connect(server); | 2514 | rc = ip_rfc1001_connect(server); |
2512 | 2515 | ||
@@ -2543,7 +2546,7 @@ ip_connect(struct TCP_Server_Info *server) | |||
2543 | } | 2546 | } |
2544 | 2547 | ||
2545 | void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, | 2548 | void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, |
2546 | struct super_block *sb, struct smb_vol *vol_info) | 2549 | struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info) |
2547 | { | 2550 | { |
2548 | /* if we are reconnecting then should we check to see if | 2551 | /* if we are reconnecting then should we check to see if |
2549 | * any requested capabilities changed locally e.g. via | 2552 | * any requested capabilities changed locally e.g. via |
@@ -2597,22 +2600,23 @@ void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, | |||
2597 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; | 2600 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
2598 | else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { | 2601 | else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { |
2599 | cFYI(1, "negotiated posix acl support"); | 2602 | cFYI(1, "negotiated posix acl support"); |
2600 | if (sb) | 2603 | if (cifs_sb) |
2601 | sb->s_flags |= MS_POSIXACL; | 2604 | cifs_sb->mnt_cifs_flags |= |
2605 | CIFS_MOUNT_POSIXACL; | ||
2602 | } | 2606 | } |
2603 | 2607 | ||
2604 | if (vol_info && vol_info->posix_paths == 0) | 2608 | if (vol_info && vol_info->posix_paths == 0) |
2605 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; | 2609 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; |
2606 | else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { | 2610 | else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { |
2607 | cFYI(1, "negotiate posix pathnames"); | 2611 | cFYI(1, "negotiate posix pathnames"); |
2608 | if (sb) | 2612 | if (cifs_sb) |
2609 | CIFS_SB(sb)->mnt_cifs_flags |= | 2613 | cifs_sb->mnt_cifs_flags |= |
2610 | CIFS_MOUNT_POSIX_PATHS; | 2614 | CIFS_MOUNT_POSIX_PATHS; |
2611 | } | 2615 | } |
2612 | 2616 | ||
2613 | if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { | 2617 | if (cifs_sb && (cifs_sb->rsize > 127 * 1024)) { |
2614 | if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { | 2618 | if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { |
2615 | CIFS_SB(sb)->rsize = 127 * 1024; | 2619 | cifs_sb->rsize = 127 * 1024; |
2616 | cFYI(DBG2, "larger reads not supported by srv"); | 2620 | cFYI(DBG2, "larger reads not supported by srv"); |
2617 | } | 2621 | } |
2618 | } | 2622 | } |
@@ -2659,6 +2663,9 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
2659 | { | 2663 | { |
2660 | INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); | 2664 | INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); |
2661 | 2665 | ||
2666 | spin_lock_init(&cifs_sb->tlink_tree_lock); | ||
2667 | cifs_sb->tlink_tree = RB_ROOT; | ||
2668 | |||
2662 | if (pvolume_info->rsize > CIFSMaxBufSize) { | 2669 | if (pvolume_info->rsize > CIFSMaxBufSize) { |
2663 | cERROR(1, "rsize %d too large, using MaxBufSize", | 2670 | cERROR(1, "rsize %d too large, using MaxBufSize", |
2664 | pvolume_info->rsize); | 2671 | pvolume_info->rsize); |
@@ -2747,21 +2754,21 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
2747 | 2754 | ||
2748 | /* | 2755 | /* |
2749 | * When the server supports very large writes via POSIX extensions, we can | 2756 | * When the server supports very large writes via POSIX extensions, we can |
2750 | * allow up to 2^24 - PAGE_CACHE_SIZE. | 2757 | * allow up to 2^24-1, minus the size of a WRITE_AND_X header, not including |
2758 | * the RFC1001 length. | ||
2751 | * | 2759 | * |
2752 | * Note that this might make for "interesting" allocation problems during | 2760 | * Note that this might make for "interesting" allocation problems during |
2753 | * writeback however (as we have to allocate an array of pointers for the | 2761 | * writeback however as we have to allocate an array of pointers for the |
2754 | * pages). A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. | 2762 | * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. |
2755 | */ | 2763 | */ |
2756 | #define CIFS_MAX_WSIZE ((1<<24) - PAGE_CACHE_SIZE) | 2764 | #define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4) |
2757 | 2765 | ||
2758 | /* | 2766 | /* |
2759 | * When the server doesn't allow large posix writes, default to a wsize of | 2767 | * When the server doesn't allow large posix writes, only allow a wsize of |
2760 | * 128k - PAGE_CACHE_SIZE -- one page less than the largest frame size | 2768 | * 128k minus the size of the WRITE_AND_X header. That allows for a write up |
2761 | * described in RFC1001. This allows space for the header without going over | 2769 | * to the maximum size described by RFC1002. |
2762 | * that by default. | ||
2763 | */ | 2770 | */ |
2764 | #define CIFS_MAX_RFC1001_WSIZE (128 * 1024 - PAGE_CACHE_SIZE) | 2771 | #define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4) |
2765 | 2772 | ||
2766 | /* | 2773 | /* |
2767 | * The default wsize is 1M. find_get_pages seems to return a maximum of 256 | 2774 | * The default wsize is 1M. find_get_pages seems to return a maximum of 256 |
@@ -2780,11 +2787,18 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
2780 | 2787 | ||
2781 | /* can server support 24-bit write sizes? (via UNIX extensions) */ | 2788 | /* can server support 24-bit write sizes? (via UNIX extensions) */ |
2782 | if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) | 2789 | if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) |
2783 | wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1001_WSIZE); | 2790 | wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE); |
2784 | 2791 | ||
2785 | /* no CAP_LARGE_WRITE_X? Limit it to 16 bits */ | 2792 | /* |
2786 | if (!(server->capabilities & CAP_LARGE_WRITE_X)) | 2793 | * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set? |
2787 | wsize = min_t(unsigned int, wsize, USHRT_MAX); | 2794 | * Limit it to max buffer offered by the server, minus the size of the |
2795 | * WRITEX header, not including the 4 byte RFC1001 length. | ||
2796 | */ | ||
2797 | if (!(server->capabilities & CAP_LARGE_WRITE_X) || | ||
2798 | (!(server->capabilities & CAP_UNIX) && | ||
2799 | (server->sec_mode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)))) | ||
2800 | wsize = min_t(unsigned int, wsize, | ||
2801 | server->maxBuf - sizeof(WRITE_REQ) + 4); | ||
2788 | 2802 | ||
2789 | /* hard limit of CIFS_MAX_WSIZE */ | 2803 | /* hard limit of CIFS_MAX_WSIZE */ |
2790 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); | 2804 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); |
@@ -2934,7 +2948,11 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
2934 | 2948 | ||
2935 | if (volume_info->nullauth) { | 2949 | if (volume_info->nullauth) { |
2936 | cFYI(1, "null user"); | 2950 | cFYI(1, "null user"); |
2937 | volume_info->username = ""; | 2951 | volume_info->username = kzalloc(1, GFP_KERNEL); |
2952 | if (volume_info->username == NULL) { | ||
2953 | rc = -ENOMEM; | ||
2954 | goto out; | ||
2955 | } | ||
2938 | } else if (volume_info->username) { | 2956 | } else if (volume_info->username) { |
2939 | /* BB fixme parse for domain name here */ | 2957 | /* BB fixme parse for domain name here */ |
2940 | cFYI(1, "Username: %s", volume_info->username); | 2958 | cFYI(1, "Username: %s", volume_info->username); |
@@ -2968,8 +2986,7 @@ out: | |||
2968 | } | 2986 | } |
2969 | 2987 | ||
2970 | int | 2988 | int |
2971 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | 2989 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) |
2972 | struct smb_vol *volume_info, const char *devname) | ||
2973 | { | 2990 | { |
2974 | int rc = 0; | 2991 | int rc = 0; |
2975 | int xid; | 2992 | int xid; |
@@ -2980,6 +2997,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2980 | struct tcon_link *tlink; | 2997 | struct tcon_link *tlink; |
2981 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2998 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2982 | int referral_walks_count = 0; | 2999 | int referral_walks_count = 0; |
3000 | |||
3001 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | ||
3002 | if (rc) | ||
3003 | return rc; | ||
3004 | |||
3005 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; | ||
3006 | |||
2983 | try_mount_again: | 3007 | try_mount_again: |
2984 | /* cleanup activities if we're chasing a referral */ | 3008 | /* cleanup activities if we're chasing a referral */ |
2985 | if (referral_walks_count) { | 3009 | if (referral_walks_count) { |
@@ -3004,6 +3028,7 @@ try_mount_again: | |||
3004 | srvTcp = cifs_get_tcp_session(volume_info); | 3028 | srvTcp = cifs_get_tcp_session(volume_info); |
3005 | if (IS_ERR(srvTcp)) { | 3029 | if (IS_ERR(srvTcp)) { |
3006 | rc = PTR_ERR(srvTcp); | 3030 | rc = PTR_ERR(srvTcp); |
3031 | bdi_destroy(&cifs_sb->bdi); | ||
3007 | goto out; | 3032 | goto out; |
3008 | } | 3033 | } |
3009 | 3034 | ||
@@ -3015,14 +3040,6 @@ try_mount_again: | |||
3015 | goto mount_fail_check; | 3040 | goto mount_fail_check; |
3016 | } | 3041 | } |
3017 | 3042 | ||
3018 | if (pSesInfo->capabilities & CAP_LARGE_FILES) | ||
3019 | sb->s_maxbytes = MAX_LFS_FILESIZE; | ||
3020 | else | ||
3021 | sb->s_maxbytes = MAX_NON_LFS; | ||
3022 | |||
3023 | /* BB FIXME fix time_gran to be larger for LANMAN sessions */ | ||
3024 | sb->s_time_gran = 100; | ||
3025 | |||
3026 | /* search for existing tcon to this server share */ | 3043 | /* search for existing tcon to this server share */ |
3027 | tcon = cifs_get_tcon(pSesInfo, volume_info); | 3044 | tcon = cifs_get_tcon(pSesInfo, volume_info); |
3028 | if (IS_ERR(tcon)) { | 3045 | if (IS_ERR(tcon)) { |
@@ -3035,7 +3052,7 @@ try_mount_again: | |||
3035 | if (tcon->ses->capabilities & CAP_UNIX) { | 3052 | if (tcon->ses->capabilities & CAP_UNIX) { |
3036 | /* reset of caps checks mount to see if unix extensions | 3053 | /* reset of caps checks mount to see if unix extensions |
3037 | disabled for just this mount */ | 3054 | disabled for just this mount */ |
3038 | reset_cifs_unix_caps(xid, tcon, sb, volume_info); | 3055 | reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info); |
3039 | if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && | 3056 | if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && |
3040 | (le64_to_cpu(tcon->fsUnixInfo.Capability) & | 3057 | (le64_to_cpu(tcon->fsUnixInfo.Capability) & |
3041 | CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { | 3058 | CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { |
@@ -3158,6 +3175,7 @@ mount_fail_check: | |||
3158 | cifs_put_smb_ses(pSesInfo); | 3175 | cifs_put_smb_ses(pSesInfo); |
3159 | else | 3176 | else |
3160 | cifs_put_tcp_session(srvTcp); | 3177 | cifs_put_tcp_session(srvTcp); |
3178 | bdi_destroy(&cifs_sb->bdi); | ||
3161 | goto out; | 3179 | goto out; |
3162 | } | 3180 | } |
3163 | 3181 | ||
@@ -3171,6 +3189,10 @@ out: | |||
3171 | return rc; | 3189 | return rc; |
3172 | } | 3190 | } |
3173 | 3191 | ||
3192 | /* | ||
3193 | * Issue a TREE_CONNECT request. Note that for IPC$ shares, that the tcon | ||
3194 | * pointer may be NULL. | ||
3195 | */ | ||
3174 | int | 3196 | int |
3175 | CIFSTCon(unsigned int xid, struct cifs_ses *ses, | 3197 | CIFSTCon(unsigned int xid, struct cifs_ses *ses, |
3176 | const char *tree, struct cifs_tcon *tcon, | 3198 | const char *tree, struct cifs_tcon *tcon, |
@@ -3205,7 +3227,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
3205 | pSMB->AndXCommand = 0xFF; | 3227 | pSMB->AndXCommand = 0xFF; |
3206 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); | 3228 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); |
3207 | bcc_ptr = &pSMB->Password[0]; | 3229 | bcc_ptr = &pSMB->Password[0]; |
3208 | if ((ses->server->sec_mode) & SECMODE_USER) { | 3230 | if (!tcon || (ses->server->sec_mode & SECMODE_USER)) { |
3209 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ | 3231 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ |
3210 | *bcc_ptr = 0; /* password is null byte */ | 3232 | *bcc_ptr = 0; /* password is null byte */ |
3211 | bcc_ptr++; /* skip password */ | 3233 | bcc_ptr++; /* skip password */ |
@@ -3328,8 +3350,8 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
3328 | return rc; | 3350 | return rc; |
3329 | } | 3351 | } |
3330 | 3352 | ||
3331 | int | 3353 | void |
3332 | cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | 3354 | cifs_umount(struct cifs_sb_info *cifs_sb) |
3333 | { | 3355 | { |
3334 | struct rb_root *root = &cifs_sb->tlink_tree; | 3356 | struct rb_root *root = &cifs_sb->tlink_tree; |
3335 | struct rb_node *node; | 3357 | struct rb_node *node; |
@@ -3350,7 +3372,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | |||
3350 | } | 3372 | } |
3351 | spin_unlock(&cifs_sb->tlink_tree_lock); | 3373 | spin_unlock(&cifs_sb->tlink_tree_lock); |
3352 | 3374 | ||
3353 | return 0; | 3375 | bdi_destroy(&cifs_sb->bdi); |
3376 | kfree(cifs_sb->mountdata); | ||
3377 | unload_nls(cifs_sb->local_nls); | ||
3378 | kfree(cifs_sb); | ||
3354 | } | 3379 | } |
3355 | 3380 | ||
3356 | int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) | 3381 | int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) |
@@ -3371,7 +3396,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) | |||
3371 | } | 3396 | } |
3372 | if (rc == 0) { | 3397 | if (rc == 0) { |
3373 | spin_lock(&GlobalMid_Lock); | 3398 | spin_lock(&GlobalMid_Lock); |
3374 | if (server->tcpStatus != CifsExiting) | 3399 | if (server->tcpStatus == CifsNeedNegotiate) |
3375 | server->tcpStatus = CifsGood; | 3400 | server->tcpStatus = CifsGood; |
3376 | else | 3401 | else |
3377 | rc = -EHOSTDOWN; | 3402 | rc = -EHOSTDOWN; |
@@ -3484,12 +3509,6 @@ out: | |||
3484 | return tcon; | 3509 | return tcon; |
3485 | } | 3510 | } |
3486 | 3511 | ||
3487 | static inline struct tcon_link * | ||
3488 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) | ||
3489 | { | ||
3490 | return cifs_sb->master_tlink; | ||
3491 | } | ||
3492 | |||
3493 | struct cifs_tcon * | 3512 | struct cifs_tcon * |
3494 | cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) | 3513 | cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) |
3495 | { | 3514 | { |
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index d368a47ba5eb..42e5363b4102 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c | |||
@@ -28,14 +28,14 @@ void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) | |||
28 | server->fscache = | 28 | server->fscache = |
29 | fscache_acquire_cookie(cifs_fscache_netfs.primary_index, | 29 | fscache_acquire_cookie(cifs_fscache_netfs.primary_index, |
30 | &cifs_fscache_server_index_def, server); | 30 | &cifs_fscache_server_index_def, server); |
31 | cFYI(1, "CIFS: get client cookie (0x%p/0x%p)", server, | 31 | cFYI(1, "%s: (0x%p/0x%p)", __func__, server, |
32 | server->fscache); | 32 | server->fscache); |
33 | } | 33 | } |
34 | 34 | ||
35 | void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) | 35 | void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) |
36 | { | 36 | { |
37 | cFYI(1, "CIFS: release client cookie (0x%p/0x%p)", server, | 37 | cFYI(1, "%s: (0x%p/0x%p)", __func__, server, |
38 | server->fscache); | 38 | server->fscache); |
39 | fscache_relinquish_cookie(server->fscache, 0); | 39 | fscache_relinquish_cookie(server->fscache, 0); |
40 | server->fscache = NULL; | 40 | server->fscache = NULL; |
41 | } | 41 | } |
@@ -47,13 +47,13 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) | |||
47 | tcon->fscache = | 47 | tcon->fscache = |
48 | fscache_acquire_cookie(server->fscache, | 48 | fscache_acquire_cookie(server->fscache, |
49 | &cifs_fscache_super_index_def, tcon); | 49 | &cifs_fscache_super_index_def, tcon); |
50 | cFYI(1, "CIFS: get superblock cookie (0x%p/0x%p)", | 50 | cFYI(1, "%s: (0x%p/0x%p)", __func__, server->fscache, |
51 | server->fscache, tcon->fscache); | 51 | tcon->fscache); |
52 | } | 52 | } |
53 | 53 | ||
54 | void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) | 54 | void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) |
55 | { | 55 | { |
56 | cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache); | 56 | cFYI(1, "%s: (0x%p)", __func__, tcon->fscache); |
57 | fscache_relinquish_cookie(tcon->fscache, 0); | 57 | fscache_relinquish_cookie(tcon->fscache, 0); |
58 | tcon->fscache = NULL; | 58 | tcon->fscache = NULL; |
59 | } | 59 | } |
@@ -70,8 +70,8 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode) | |||
70 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) { | 70 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) { |
71 | cifsi->fscache = fscache_acquire_cookie(tcon->fscache, | 71 | cifsi->fscache = fscache_acquire_cookie(tcon->fscache, |
72 | &cifs_fscache_inode_object_def, cifsi); | 72 | &cifs_fscache_inode_object_def, cifsi); |
73 | cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache, | 73 | cFYI(1, "%s: got FH cookie (0x%p/0x%p)", __func__, |
74 | cifsi->fscache); | 74 | tcon->fscache, cifsi->fscache); |
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
@@ -80,8 +80,7 @@ void cifs_fscache_release_inode_cookie(struct inode *inode) | |||
80 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 80 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
81 | 81 | ||
82 | if (cifsi->fscache) { | 82 | if (cifsi->fscache) { |
83 | cFYI(1, "CIFS releasing inode cookie (0x%p)", | 83 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); |
84 | cifsi->fscache); | ||
85 | fscache_relinquish_cookie(cifsi->fscache, 0); | 84 | fscache_relinquish_cookie(cifsi->fscache, 0); |
86 | cifsi->fscache = NULL; | 85 | cifsi->fscache = NULL; |
87 | } | 86 | } |
@@ -92,8 +91,8 @@ static void cifs_fscache_disable_inode_cookie(struct inode *inode) | |||
92 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 91 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
93 | 92 | ||
94 | if (cifsi->fscache) { | 93 | if (cifsi->fscache) { |
95 | cFYI(1, "CIFS disabling inode cookie (0x%p)", | 94 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); |
96 | cifsi->fscache); | 95 | fscache_uncache_all_inode_pages(cifsi->fscache, inode); |
97 | fscache_relinquish_cookie(cifsi->fscache, 1); | 96 | fscache_relinquish_cookie(cifsi->fscache, 1); |
98 | cifsi->fscache = NULL; | 97 | cifsi->fscache = NULL; |
99 | } | 98 | } |
@@ -121,8 +120,8 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode) | |||
121 | cifs_sb_master_tcon(cifs_sb)->fscache, | 120 | cifs_sb_master_tcon(cifs_sb)->fscache, |
122 | &cifs_fscache_inode_object_def, | 121 | &cifs_fscache_inode_object_def, |
123 | cifsi); | 122 | cifsi); |
124 | cFYI(1, "CIFS: new cookie 0x%p oldcookie 0x%p", | 123 | cFYI(1, "%s: new cookie 0x%p oldcookie 0x%p", |
125 | cifsi->fscache, old); | 124 | __func__, cifsi->fscache, old); |
126 | } | 125 | } |
127 | } | 126 | } |
128 | 127 | ||
@@ -132,8 +131,8 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp) | |||
132 | struct inode *inode = page->mapping->host; | 131 | struct inode *inode = page->mapping->host; |
133 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 132 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
134 | 133 | ||
135 | cFYI(1, "CIFS: fscache release page (0x%p/0x%p)", | 134 | cFYI(1, "%s: (0x%p/0x%p)", __func__, page, |
136 | page, cifsi->fscache); | 135 | cifsi->fscache); |
137 | if (!fscache_maybe_release_page(cifsi->fscache, page, gfp)) | 136 | if (!fscache_maybe_release_page(cifsi->fscache, page, gfp)) |
138 | return 0; | 137 | return 0; |
139 | } | 138 | } |
@@ -144,8 +143,7 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp) | |||
144 | static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx, | 143 | static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx, |
145 | int error) | 144 | int error) |
146 | { | 145 | { |
147 | cFYI(1, "CFS: readpage_from_fscache_complete (0x%p/%d)", | 146 | cFYI(1, "%s: (0x%p/%d)", __func__, page, error); |
148 | page, error); | ||
149 | if (!error) | 147 | if (!error) |
150 | SetPageUptodate(page); | 148 | SetPageUptodate(page); |
151 | unlock_page(page); | 149 | unlock_page(page); |
@@ -158,7 +156,7 @@ int __cifs_readpage_from_fscache(struct inode *inode, struct page *page) | |||
158 | { | 156 | { |
159 | int ret; | 157 | int ret; |
160 | 158 | ||
161 | cFYI(1, "CIFS: readpage_from_fscache(fsc:%p, p:%p, i:0x%p", | 159 | cFYI(1, "%s: (fsc:%p, p:%p, i:0x%p", __func__, |
162 | CIFS_I(inode)->fscache, page, inode); | 160 | CIFS_I(inode)->fscache, page, inode); |
163 | ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page, | 161 | ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page, |
164 | cifs_readpage_from_fscache_complete, | 162 | cifs_readpage_from_fscache_complete, |
@@ -167,11 +165,11 @@ int __cifs_readpage_from_fscache(struct inode *inode, struct page *page) | |||
167 | switch (ret) { | 165 | switch (ret) { |
168 | 166 | ||
169 | case 0: /* page found in fscache, read submitted */ | 167 | case 0: /* page found in fscache, read submitted */ |
170 | cFYI(1, "CIFS: readpage_from_fscache: submitted"); | 168 | cFYI(1, "%s: submitted", __func__); |
171 | return ret; | 169 | return ret; |
172 | case -ENOBUFS: /* page won't be cached */ | 170 | case -ENOBUFS: /* page won't be cached */ |
173 | case -ENODATA: /* page not in cache */ | 171 | case -ENODATA: /* page not in cache */ |
174 | cFYI(1, "CIFS: readpage_from_fscache %d", ret); | 172 | cFYI(1, "%s: %d", __func__, ret); |
175 | return 1; | 173 | return 1; |
176 | 174 | ||
177 | default: | 175 | default: |
@@ -190,7 +188,7 @@ int __cifs_readpages_from_fscache(struct inode *inode, | |||
190 | { | 188 | { |
191 | int ret; | 189 | int ret; |
192 | 190 | ||
193 | cFYI(1, "CIFS: __cifs_readpages_from_fscache (0x%p/%u/0x%p)", | 191 | cFYI(1, "%s: (0x%p/%u/0x%p)", __func__, |
194 | CIFS_I(inode)->fscache, *nr_pages, inode); | 192 | CIFS_I(inode)->fscache, *nr_pages, inode); |
195 | ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping, | 193 | ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping, |
196 | pages, nr_pages, | 194 | pages, nr_pages, |
@@ -199,12 +197,12 @@ int __cifs_readpages_from_fscache(struct inode *inode, | |||
199 | mapping_gfp_mask(mapping)); | 197 | mapping_gfp_mask(mapping)); |
200 | switch (ret) { | 198 | switch (ret) { |
201 | case 0: /* read submitted to the cache for all pages */ | 199 | case 0: /* read submitted to the cache for all pages */ |
202 | cFYI(1, "CIFS: readpages_from_fscache: submitted"); | 200 | cFYI(1, "%s: submitted", __func__); |
203 | return ret; | 201 | return ret; |
204 | 202 | ||
205 | case -ENOBUFS: /* some pages are not cached and can't be */ | 203 | case -ENOBUFS: /* some pages are not cached and can't be */ |
206 | case -ENODATA: /* some pages are not cached */ | 204 | case -ENODATA: /* some pages are not cached */ |
207 | cFYI(1, "CIFS: readpages_from_fscache: no page"); | 205 | cFYI(1, "%s: no page", __func__); |
208 | return 1; | 206 | return 1; |
209 | 207 | ||
210 | default: | 208 | default: |
@@ -218,7 +216,7 @@ void __cifs_readpage_to_fscache(struct inode *inode, struct page *page) | |||
218 | { | 216 | { |
219 | int ret; | 217 | int ret; |
220 | 218 | ||
221 | cFYI(1, "CIFS: readpage_to_fscache(fsc: %p, p: %p, i: %p", | 219 | cFYI(1, "%s: (fsc: %p, p: %p, i: %p)", __func__, |
222 | CIFS_I(inode)->fscache, page, inode); | 220 | CIFS_I(inode)->fscache, page, inode); |
223 | ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL); | 221 | ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL); |
224 | if (ret != 0) | 222 | if (ret != 0) |
@@ -230,7 +228,7 @@ void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode) | |||
230 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 228 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
231 | struct fscache_cookie *cookie = cifsi->fscache; | 229 | struct fscache_cookie *cookie = cifsi->fscache; |
232 | 230 | ||
233 | cFYI(1, "CIFS: fscache invalidatepage (0x%p/0x%p)", page, cookie); | 231 | cFYI(1, "%s: (0x%p/0x%p)", __func__, page, cookie); |
234 | fscache_wait_on_page_write(cookie, page); | 232 | fscache_wait_on_page_write(cookie, page); |
235 | fscache_uncache_page(cookie, page); | 233 | fscache_uncache_page(cookie, page); |
236 | } | 234 | } |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 1525d5e662b6..1c5b770c3141 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -90,12 +90,10 @@ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key) | |||
90 | sg_init_one(&sgout, out, 8); | 90 | sg_init_one(&sgout, out, 8); |
91 | 91 | ||
92 | rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8); | 92 | rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8); |
93 | if (rc) { | 93 | if (rc) |
94 | cERROR(1, "could not encrypt crypt key rc: %d\n", rc); | 94 | cERROR(1, "could not encrypt crypt key rc: %d\n", rc); |
95 | crypto_free_blkcipher(tfm_des); | ||
96 | goto smbhash_err; | ||
97 | } | ||
98 | 95 | ||
96 | crypto_free_blkcipher(tfm_des); | ||
99 | smbhash_err: | 97 | smbhash_err: |
100 | return rc; | 98 | return rc; |
101 | } | 99 | } |
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index 6cbb3afb36dc..cb140ef293e4 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c | |||
@@ -43,8 +43,6 @@ const struct file_operations coda_ioctl_operations = { | |||
43 | /* the coda pioctl inode ops */ | 43 | /* the coda pioctl inode ops */ |
44 | static int coda_ioctl_permission(struct inode *inode, int mask, unsigned int flags) | 44 | static int coda_ioctl_permission(struct inode *inode, int mask, unsigned int flags) |
45 | { | 45 | { |
46 | if (flags & IPERM_FLAG_RCU) | ||
47 | return -ECHILD; | ||
48 | return (mask & MAY_EXEC) ? -EACCES : 0; | 46 | return (mask & MAY_EXEC) ? -EACCES : 0; |
49 | } | 47 | } |
50 | 48 | ||
diff --git a/fs/dcookies.c b/fs/dcookies.c index a21cabdbd87b..dda0dc702d1b 100644 --- a/fs/dcookies.c +++ b/fs/dcookies.c | |||
@@ -178,6 +178,8 @@ SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) | |||
178 | /* FIXME: (deleted) ? */ | 178 | /* FIXME: (deleted) ? */ |
179 | path = d_path(&dcs->path, kbuf, PAGE_SIZE); | 179 | path = d_path(&dcs->path, kbuf, PAGE_SIZE); |
180 | 180 | ||
181 | mutex_unlock(&dcookie_mutex); | ||
182 | |||
181 | if (IS_ERR(path)) { | 183 | if (IS_ERR(path)) { |
182 | err = PTR_ERR(path); | 184 | err = PTR_ERR(path); |
183 | goto out_free; | 185 | goto out_free; |
@@ -194,6 +196,7 @@ SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) | |||
194 | 196 | ||
195 | out_free: | 197 | out_free: |
196 | kfree(kbuf); | 198 | kfree(kbuf); |
199 | return err; | ||
197 | out: | 200 | out: |
198 | mutex_unlock(&dcookie_mutex); | 201 | mutex_unlock(&dcookie_mutex); |
199 | return err; | 202 | return err; |
@@ -1093,6 +1093,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1093 | 1093 | ||
1094 | bprm->mm = NULL; /* We're using it now */ | 1094 | bprm->mm = NULL; /* We're using it now */ |
1095 | 1095 | ||
1096 | set_fs(USER_DS); | ||
1096 | current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); | 1097 | current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); |
1097 | flush_thread(); | 1098 | flush_thread(); |
1098 | current->personality &= ~bprm->per_clear; | 1099 | current->personality &= ~bprm->per_clear; |
@@ -1357,10 +1358,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | |||
1357 | if (retval) | 1358 | if (retval) |
1358 | return retval; | 1359 | return retval; |
1359 | 1360 | ||
1360 | /* kernel module loader fixup */ | ||
1361 | /* so we don't try to load run modprobe in kernel space. */ | ||
1362 | set_fs(USER_DS); | ||
1363 | |||
1364 | retval = audit_bprm(bprm); | 1361 | retval = audit_bprm(bprm); |
1365 | if (retval) | 1362 | if (retval) |
1366 | return retval; | 1363 | return retval; |
@@ -1999,7 +1996,7 @@ static void wait_for_dump_helpers(struct file *file) | |||
1999 | * is a special value that we use to trap recursive | 1996 | * is a special value that we use to trap recursive |
2000 | * core dumps | 1997 | * core dumps |
2001 | */ | 1998 | */ |
2002 | static int umh_pipe_setup(struct subprocess_info *info) | 1999 | static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) |
2003 | { | 2000 | { |
2004 | struct file *rp, *wp; | 2001 | struct file *rp, *wp; |
2005 | struct fdtable *fdt; | 2002 | struct fdtable *fdt; |
diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h index 2e29abb30f76..095c36f3b612 100644 --- a/fs/ext4/ext4_extents.h +++ b/fs/ext4/ext4_extents.h | |||
@@ -125,7 +125,7 @@ struct ext4_ext_path { | |||
125 | * positive retcode - signal for ext4_ext_walk_space(), see below | 125 | * positive retcode - signal for ext4_ext_walk_space(), see below |
126 | * callback must return valid extent (passed or newly created) | 126 | * callback must return valid extent (passed or newly created) |
127 | */ | 127 | */ |
128 | typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *, | 128 | typedef int (*ext_prepare_callback)(struct inode *, ext4_lblk_t, |
129 | struct ext4_ext_cache *, | 129 | struct ext4_ext_cache *, |
130 | struct ext4_extent *, void *); | 130 | struct ext4_extent *, void *); |
131 | 131 | ||
@@ -133,8 +133,11 @@ typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *, | |||
133 | #define EXT_BREAK 1 | 133 | #define EXT_BREAK 1 |
134 | #define EXT_REPEAT 2 | 134 | #define EXT_REPEAT 2 |
135 | 135 | ||
136 | /* Maximum logical block in a file; ext4_extent's ee_block is __le32 */ | 136 | /* |
137 | #define EXT_MAX_BLOCK 0xffffffff | 137 | * Maximum number of logical blocks in a file; ext4_extent's ee_block is |
138 | * __le32. | ||
139 | */ | ||
140 | #define EXT_MAX_BLOCKS 0xffffffff | ||
138 | 141 | ||
139 | /* | 142 | /* |
140 | * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an | 143 | * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 5199bac7fc62..f815cc81e7a2 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -1408,7 +1408,7 @@ got_index: | |||
1408 | 1408 | ||
1409 | /* | 1409 | /* |
1410 | * ext4_ext_next_allocated_block: | 1410 | * ext4_ext_next_allocated_block: |
1411 | * returns allocated block in subsequent extent or EXT_MAX_BLOCK. | 1411 | * returns allocated block in subsequent extent or EXT_MAX_BLOCKS. |
1412 | * NOTE: it considers block number from index entry as | 1412 | * NOTE: it considers block number from index entry as |
1413 | * allocated block. Thus, index entries have to be consistent | 1413 | * allocated block. Thus, index entries have to be consistent |
1414 | * with leaves. | 1414 | * with leaves. |
@@ -1422,7 +1422,7 @@ ext4_ext_next_allocated_block(struct ext4_ext_path *path) | |||
1422 | depth = path->p_depth; | 1422 | depth = path->p_depth; |
1423 | 1423 | ||
1424 | if (depth == 0 && path->p_ext == NULL) | 1424 | if (depth == 0 && path->p_ext == NULL) |
1425 | return EXT_MAX_BLOCK; | 1425 | return EXT_MAX_BLOCKS; |
1426 | 1426 | ||
1427 | while (depth >= 0) { | 1427 | while (depth >= 0) { |
1428 | if (depth == path->p_depth) { | 1428 | if (depth == path->p_depth) { |
@@ -1439,12 +1439,12 @@ ext4_ext_next_allocated_block(struct ext4_ext_path *path) | |||
1439 | depth--; | 1439 | depth--; |
1440 | } | 1440 | } |
1441 | 1441 | ||
1442 | return EXT_MAX_BLOCK; | 1442 | return EXT_MAX_BLOCKS; |
1443 | } | 1443 | } |
1444 | 1444 | ||
1445 | /* | 1445 | /* |
1446 | * ext4_ext_next_leaf_block: | 1446 | * ext4_ext_next_leaf_block: |
1447 | * returns first allocated block from next leaf or EXT_MAX_BLOCK | 1447 | * returns first allocated block from next leaf or EXT_MAX_BLOCKS |
1448 | */ | 1448 | */ |
1449 | static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, | 1449 | static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, |
1450 | struct ext4_ext_path *path) | 1450 | struct ext4_ext_path *path) |
@@ -1456,7 +1456,7 @@ static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, | |||
1456 | 1456 | ||
1457 | /* zero-tree has no leaf blocks at all */ | 1457 | /* zero-tree has no leaf blocks at all */ |
1458 | if (depth == 0) | 1458 | if (depth == 0) |
1459 | return EXT_MAX_BLOCK; | 1459 | return EXT_MAX_BLOCKS; |
1460 | 1460 | ||
1461 | /* go to index block */ | 1461 | /* go to index block */ |
1462 | depth--; | 1462 | depth--; |
@@ -1469,7 +1469,7 @@ static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, | |||
1469 | depth--; | 1469 | depth--; |
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | return EXT_MAX_BLOCK; | 1472 | return EXT_MAX_BLOCKS; |
1473 | } | 1473 | } |
1474 | 1474 | ||
1475 | /* | 1475 | /* |
@@ -1677,13 +1677,13 @@ static unsigned int ext4_ext_check_overlap(struct inode *inode, | |||
1677 | */ | 1677 | */ |
1678 | if (b2 < b1) { | 1678 | if (b2 < b1) { |
1679 | b2 = ext4_ext_next_allocated_block(path); | 1679 | b2 = ext4_ext_next_allocated_block(path); |
1680 | if (b2 == EXT_MAX_BLOCK) | 1680 | if (b2 == EXT_MAX_BLOCKS) |
1681 | goto out; | 1681 | goto out; |
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | /* check for wrap through zero on extent logical start block*/ | 1684 | /* check for wrap through zero on extent logical start block*/ |
1685 | if (b1 + len1 < b1) { | 1685 | if (b1 + len1 < b1) { |
1686 | len1 = EXT_MAX_BLOCK - b1; | 1686 | len1 = EXT_MAX_BLOCKS - b1; |
1687 | newext->ee_len = cpu_to_le16(len1); | 1687 | newext->ee_len = cpu_to_le16(len1); |
1688 | ret = 1; | 1688 | ret = 1; |
1689 | } | 1689 | } |
@@ -1767,7 +1767,7 @@ repeat: | |||
1767 | fex = EXT_LAST_EXTENT(eh); | 1767 | fex = EXT_LAST_EXTENT(eh); |
1768 | next = ext4_ext_next_leaf_block(inode, path); | 1768 | next = ext4_ext_next_leaf_block(inode, path); |
1769 | if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block) | 1769 | if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block) |
1770 | && next != EXT_MAX_BLOCK) { | 1770 | && next != EXT_MAX_BLOCKS) { |
1771 | ext_debug("next leaf block - %d\n", next); | 1771 | ext_debug("next leaf block - %d\n", next); |
1772 | BUG_ON(npath != NULL); | 1772 | BUG_ON(npath != NULL); |
1773 | npath = ext4_ext_find_extent(inode, next, NULL); | 1773 | npath = ext4_ext_find_extent(inode, next, NULL); |
@@ -1887,7 +1887,7 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block, | |||
1887 | BUG_ON(func == NULL); | 1887 | BUG_ON(func == NULL); |
1888 | BUG_ON(inode == NULL); | 1888 | BUG_ON(inode == NULL); |
1889 | 1889 | ||
1890 | while (block < last && block != EXT_MAX_BLOCK) { | 1890 | while (block < last && block != EXT_MAX_BLOCKS) { |
1891 | num = last - block; | 1891 | num = last - block; |
1892 | /* find extent for this block */ | 1892 | /* find extent for this block */ |
1893 | down_read(&EXT4_I(inode)->i_data_sem); | 1893 | down_read(&EXT4_I(inode)->i_data_sem); |
@@ -1958,7 +1958,7 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block, | |||
1958 | err = -EIO; | 1958 | err = -EIO; |
1959 | break; | 1959 | break; |
1960 | } | 1960 | } |
1961 | err = func(inode, path, &cbex, ex, cbdata); | 1961 | err = func(inode, next, &cbex, ex, cbdata); |
1962 | ext4_ext_drop_refs(path); | 1962 | ext4_ext_drop_refs(path); |
1963 | 1963 | ||
1964 | if (err < 0) | 1964 | if (err < 0) |
@@ -2020,7 +2020,7 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | |||
2020 | if (ex == NULL) { | 2020 | if (ex == NULL) { |
2021 | /* there is no extent yet, so gap is [0;-] */ | 2021 | /* there is no extent yet, so gap is [0;-] */ |
2022 | lblock = 0; | 2022 | lblock = 0; |
2023 | len = EXT_MAX_BLOCK; | 2023 | len = EXT_MAX_BLOCKS; |
2024 | ext_debug("cache gap(whole file):"); | 2024 | ext_debug("cache gap(whole file):"); |
2025 | } else if (block < le32_to_cpu(ex->ee_block)) { | 2025 | } else if (block < le32_to_cpu(ex->ee_block)) { |
2026 | lblock = block; | 2026 | lblock = block; |
@@ -2350,7 +2350,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2350 | * never happen because at least one of the end points | 2350 | * never happen because at least one of the end points |
2351 | * needs to be on the edge of the extent. | 2351 | * needs to be on the edge of the extent. |
2352 | */ | 2352 | */ |
2353 | if (end == EXT_MAX_BLOCK) { | 2353 | if (end == EXT_MAX_BLOCKS - 1) { |
2354 | ext_debug(" bad truncate %u:%u\n", | 2354 | ext_debug(" bad truncate %u:%u\n", |
2355 | start, end); | 2355 | start, end); |
2356 | block = 0; | 2356 | block = 0; |
@@ -2398,7 +2398,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2398 | * If this is a truncate, this condition | 2398 | * If this is a truncate, this condition |
2399 | * should never happen | 2399 | * should never happen |
2400 | */ | 2400 | */ |
2401 | if (end == EXT_MAX_BLOCK) { | 2401 | if (end == EXT_MAX_BLOCKS - 1) { |
2402 | ext_debug(" bad truncate %u:%u\n", | 2402 | ext_debug(" bad truncate %u:%u\n", |
2403 | start, end); | 2403 | start, end); |
2404 | err = -EIO; | 2404 | err = -EIO; |
@@ -2478,7 +2478,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2478 | * we need to remove it from the leaf | 2478 | * we need to remove it from the leaf |
2479 | */ | 2479 | */ |
2480 | if (num == 0) { | 2480 | if (num == 0) { |
2481 | if (end != EXT_MAX_BLOCK) { | 2481 | if (end != EXT_MAX_BLOCKS - 1) { |
2482 | /* | 2482 | /* |
2483 | * For hole punching, we need to scoot all the | 2483 | * For hole punching, we need to scoot all the |
2484 | * extents up when an extent is removed so that | 2484 | * extents up when an extent is removed so that |
@@ -3699,7 +3699,7 @@ void ext4_ext_truncate(struct inode *inode) | |||
3699 | 3699 | ||
3700 | last_block = (inode->i_size + sb->s_blocksize - 1) | 3700 | last_block = (inode->i_size + sb->s_blocksize - 1) |
3701 | >> EXT4_BLOCK_SIZE_BITS(sb); | 3701 | >> EXT4_BLOCK_SIZE_BITS(sb); |
3702 | err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCK); | 3702 | err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); |
3703 | 3703 | ||
3704 | /* In a multi-transaction truncate, we only make the final | 3704 | /* In a multi-transaction truncate, we only make the final |
3705 | * transaction synchronous. | 3705 | * transaction synchronous. |
@@ -3914,14 +3914,13 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset, | |||
3914 | /* | 3914 | /* |
3915 | * Callback function called for each extent to gather FIEMAP information. | 3915 | * Callback function called for each extent to gather FIEMAP information. |
3916 | */ | 3916 | */ |
3917 | static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, | 3917 | static int ext4_ext_fiemap_cb(struct inode *inode, ext4_lblk_t next, |
3918 | struct ext4_ext_cache *newex, struct ext4_extent *ex, | 3918 | struct ext4_ext_cache *newex, struct ext4_extent *ex, |
3919 | void *data) | 3919 | void *data) |
3920 | { | 3920 | { |
3921 | __u64 logical; | 3921 | __u64 logical; |
3922 | __u64 physical; | 3922 | __u64 physical; |
3923 | __u64 length; | 3923 | __u64 length; |
3924 | loff_t size; | ||
3925 | __u32 flags = 0; | 3924 | __u32 flags = 0; |
3926 | int ret = 0; | 3925 | int ret = 0; |
3927 | struct fiemap_extent_info *fieinfo = data; | 3926 | struct fiemap_extent_info *fieinfo = data; |
@@ -4103,8 +4102,7 @@ found_delayed_extent: | |||
4103 | if (ex && ext4_ext_is_uninitialized(ex)) | 4102 | if (ex && ext4_ext_is_uninitialized(ex)) |
4104 | flags |= FIEMAP_EXTENT_UNWRITTEN; | 4103 | flags |= FIEMAP_EXTENT_UNWRITTEN; |
4105 | 4104 | ||
4106 | size = i_size_read(inode); | 4105 | if (next == EXT_MAX_BLOCKS) |
4107 | if (logical + length >= size) | ||
4108 | flags |= FIEMAP_EXTENT_LAST; | 4106 | flags |= FIEMAP_EXTENT_LAST; |
4109 | 4107 | ||
4110 | ret = fiemap_fill_next_extent(fieinfo, logical, physical, | 4108 | ret = fiemap_fill_next_extent(fieinfo, logical, physical, |
@@ -4347,8 +4345,8 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4347 | 4345 | ||
4348 | start_blk = start >> inode->i_sb->s_blocksize_bits; | 4346 | start_blk = start >> inode->i_sb->s_blocksize_bits; |
4349 | last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits; | 4347 | last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits; |
4350 | if (last_blk >= EXT_MAX_BLOCK) | 4348 | if (last_blk >= EXT_MAX_BLOCKS) |
4351 | last_blk = EXT_MAX_BLOCK-1; | 4349 | last_blk = EXT_MAX_BLOCKS-1; |
4352 | len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1; | 4350 | len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1; |
4353 | 4351 | ||
4354 | /* | 4352 | /* |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a5763e3505ba..e3126c051006 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2634,7 +2634,7 @@ static int ext4_writepage(struct page *page, | |||
2634 | struct buffer_head *page_bufs = NULL; | 2634 | struct buffer_head *page_bufs = NULL; |
2635 | struct inode *inode = page->mapping->host; | 2635 | struct inode *inode = page->mapping->host; |
2636 | 2636 | ||
2637 | trace_ext4_writepage(inode, page); | 2637 | trace_ext4_writepage(page); |
2638 | size = i_size_read(inode); | 2638 | size = i_size_read(inode); |
2639 | if (page->index == size >> PAGE_CACHE_SHIFT) | 2639 | if (page->index == size >> PAGE_CACHE_SHIFT) |
2640 | len = size & ~PAGE_CACHE_MASK; | 2640 | len = size & ~PAGE_CACHE_MASK; |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 859f2ae8864e..6ed859d56850 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -3578,8 +3578,8 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | |||
3578 | free += next - bit; | 3578 | free += next - bit; |
3579 | 3579 | ||
3580 | trace_ext4_mballoc_discard(sb, NULL, group, bit, next - bit); | 3580 | trace_ext4_mballoc_discard(sb, NULL, group, bit, next - bit); |
3581 | trace_ext4_mb_release_inode_pa(sb, pa->pa_inode, pa, | 3581 | trace_ext4_mb_release_inode_pa(pa, grp_blk_start + bit, |
3582 | grp_blk_start + bit, next - bit); | 3582 | next - bit); |
3583 | mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); | 3583 | mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); |
3584 | bit = next + 1; | 3584 | bit = next + 1; |
3585 | } | 3585 | } |
@@ -3608,7 +3608,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, | |||
3608 | ext4_group_t group; | 3608 | ext4_group_t group; |
3609 | ext4_grpblk_t bit; | 3609 | ext4_grpblk_t bit; |
3610 | 3610 | ||
3611 | trace_ext4_mb_release_group_pa(sb, pa); | 3611 | trace_ext4_mb_release_group_pa(pa); |
3612 | BUG_ON(pa->pa_deleted == 0); | 3612 | BUG_ON(pa->pa_deleted == 0); |
3613 | ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); | 3613 | ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); |
3614 | BUG_ON(group != e4b->bd_group && pa->pa_len != 0); | 3614 | BUG_ON(group != e4b->bd_group && pa->pa_len != 0); |
@@ -4448,7 +4448,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, | |||
4448 | * @inode: inode | 4448 | * @inode: inode |
4449 | * @block: start physical block to free | 4449 | * @block: start physical block to free |
4450 | * @count: number of blocks to count | 4450 | * @count: number of blocks to count |
4451 | * @metadata: Are these metadata blocks | 4451 | * @flags: flags used by ext4_free_blocks |
4452 | */ | 4452 | */ |
4453 | void ext4_free_blocks(handle_t *handle, struct inode *inode, | 4453 | void ext4_free_blocks(handle_t *handle, struct inode *inode, |
4454 | struct buffer_head *bh, ext4_fsblk_t block, | 4454 | struct buffer_head *bh, ext4_fsblk_t block, |
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 2b8304bf3c50..f57455a1b1b2 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c | |||
@@ -1002,12 +1002,12 @@ mext_check_arguments(struct inode *orig_inode, | |||
1002 | return -EINVAL; | 1002 | return -EINVAL; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | if ((orig_start > EXT_MAX_BLOCK) || | 1005 | if ((orig_start >= EXT_MAX_BLOCKS) || |
1006 | (donor_start > EXT_MAX_BLOCK) || | 1006 | (donor_start >= EXT_MAX_BLOCKS) || |
1007 | (*len > EXT_MAX_BLOCK) || | 1007 | (*len > EXT_MAX_BLOCKS) || |
1008 | (orig_start + *len > EXT_MAX_BLOCK)) { | 1008 | (orig_start + *len >= EXT_MAX_BLOCKS)) { |
1009 | ext4_debug("ext4 move extent: Can't handle over [%u] blocks " | 1009 | ext4_debug("ext4 move extent: Can't handle over [%u] blocks " |
1010 | "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCK, | 1010 | "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCKS, |
1011 | orig_inode->i_ino, donor_inode->i_ino); | 1011 | orig_inode->i_ino, donor_inode->i_ino); |
1012 | return -EINVAL; | 1012 | return -EINVAL; |
1013 | } | 1013 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index cc5c157aa11d..9ea71aa864b3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2243,6 +2243,12 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
2243 | * in the vfs. ext4 inode has 48 bits of i_block in fsblock units, | 2243 | * in the vfs. ext4 inode has 48 bits of i_block in fsblock units, |
2244 | * so that won't be a limiting factor. | 2244 | * so that won't be a limiting factor. |
2245 | * | 2245 | * |
2246 | * However there is other limiting factor. We do store extents in the form | ||
2247 | * of starting block and length, hence the resulting length of the extent | ||
2248 | * covering maximum file size must fit into on-disk format containers as | ||
2249 | * well. Given that length is always by 1 unit bigger than max unit (because | ||
2250 | * we count 0 as well) we have to lower the s_maxbytes by one fs block. | ||
2251 | * | ||
2246 | * Note, this does *not* consider any metadata overhead for vfs i_blocks. | 2252 | * Note, this does *not* consider any metadata overhead for vfs i_blocks. |
2247 | */ | 2253 | */ |
2248 | static loff_t ext4_max_size(int blkbits, int has_huge_files) | 2254 | static loff_t ext4_max_size(int blkbits, int has_huge_files) |
@@ -2264,10 +2270,13 @@ static loff_t ext4_max_size(int blkbits, int has_huge_files) | |||
2264 | upper_limit <<= blkbits; | 2270 | upper_limit <<= blkbits; |
2265 | } | 2271 | } |
2266 | 2272 | ||
2267 | /* 32-bit extent-start container, ee_block */ | 2273 | /* |
2268 | res = 1LL << 32; | 2274 | * 32-bit extent-start container, ee_block. We lower the maxbytes |
2275 | * by one fs block, so ee_len can cover the extent of maximum file | ||
2276 | * size | ||
2277 | */ | ||
2278 | res = (1LL << 32) - 1; | ||
2269 | res <<= blkbits; | 2279 | res <<= blkbits; |
2270 | res -= 1; | ||
2271 | 2280 | ||
2272 | /* Sanity check against vm- & vfs- imposed limits */ | 2281 | /* Sanity check against vm- & vfs- imposed limits */ |
2273 | if (res > upper_limit) | 2282 | if (res > upper_limit) |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 7257752b6d5d..7018e1d8902d 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -102,7 +102,7 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) | |||
102 | if (attr & ATTR_SYS) | 102 | if (attr & ATTR_SYS) |
103 | inode->i_flags |= S_IMMUTABLE; | 103 | inode->i_flags |= S_IMMUTABLE; |
104 | else | 104 | else |
105 | inode->i_flags &= S_IMMUTABLE; | 105 | inode->i_flags &= ~S_IMMUTABLE; |
106 | } | 106 | } |
107 | 107 | ||
108 | fat_save_attrs(inode, attr); | 108 | fat_save_attrs(inode, attr); |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index a2a5d19ece6a..2f343b4d7a7d 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -954,3 +954,47 @@ void fscache_mark_pages_cached(struct fscache_retrieval *op, | |||
954 | pagevec_reinit(pagevec); | 954 | pagevec_reinit(pagevec); |
955 | } | 955 | } |
956 | EXPORT_SYMBOL(fscache_mark_pages_cached); | 956 | EXPORT_SYMBOL(fscache_mark_pages_cached); |
957 | |||
958 | /* | ||
959 | * Uncache all the pages in an inode that are marked PG_fscache, assuming them | ||
960 | * to be associated with the given cookie. | ||
961 | */ | ||
962 | void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | ||
963 | struct inode *inode) | ||
964 | { | ||
965 | struct address_space *mapping = inode->i_mapping; | ||
966 | struct pagevec pvec; | ||
967 | pgoff_t next; | ||
968 | int i; | ||
969 | |||
970 | _enter("%p,%p", cookie, inode); | ||
971 | |||
972 | if (!mapping || mapping->nrpages == 0) { | ||
973 | _leave(" [no pages]"); | ||
974 | return; | ||
975 | } | ||
976 | |||
977 | pagevec_init(&pvec, 0); | ||
978 | next = 0; | ||
979 | while (next <= (loff_t)-1 && | ||
980 | pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE) | ||
981 | ) { | ||
982 | for (i = 0; i < pagevec_count(&pvec); i++) { | ||
983 | struct page *page = pvec.pages[i]; | ||
984 | pgoff_t page_index = page->index; | ||
985 | |||
986 | ASSERTCMP(page_index, >=, next); | ||
987 | next = page_index + 1; | ||
988 | |||
989 | if (PageFsCache(page)) { | ||
990 | __fscache_wait_on_page_write(cookie, page); | ||
991 | __fscache_uncache_page(cookie, page); | ||
992 | } | ||
993 | } | ||
994 | pagevec_release(&pvec); | ||
995 | cond_resched(); | ||
996 | } | ||
997 | |||
998 | _leave(""); | ||
999 | } | ||
1000 | EXPORT_SYMBOL(__fscache_uncache_all_inode_pages); | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index cc6ec4b2f0ff..38f84cd48b67 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -921,6 +921,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
921 | if (sb->s_flags & MS_MANDLOCK) | 921 | if (sb->s_flags & MS_MANDLOCK) |
922 | goto err; | 922 | goto err; |
923 | 923 | ||
924 | sb->s_flags &= ~MS_NOSEC; | ||
925 | |||
924 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) | 926 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
925 | goto err; | 927 | goto err; |
926 | 928 | ||
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 2792a790e50b..1c1336e7b3b2 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -663,14 +663,19 @@ static void glock_work_func(struct work_struct *work) | |||
663 | drop_ref = 1; | 663 | drop_ref = 1; |
664 | } | 664 | } |
665 | spin_lock(&gl->gl_spin); | 665 | spin_lock(&gl->gl_spin); |
666 | if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && | 666 | if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && |
667 | gl->gl_state != LM_ST_UNLOCKED && | 667 | gl->gl_state != LM_ST_UNLOCKED && |
668 | gl->gl_demote_state != LM_ST_EXCLUSIVE) { | 668 | gl->gl_demote_state != LM_ST_EXCLUSIVE) { |
669 | unsigned long holdtime, now = jiffies; | 669 | unsigned long holdtime, now = jiffies; |
670 | |||
670 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; | 671 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; |
671 | if (time_before(now, holdtime)) | 672 | if (time_before(now, holdtime)) |
672 | delay = holdtime - now; | 673 | delay = holdtime - now; |
673 | set_bit(delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE, &gl->gl_flags); | 674 | |
675 | if (!delay) { | ||
676 | clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags); | ||
677 | set_bit(GLF_DEMOTE, &gl->gl_flags); | ||
678 | } | ||
674 | } | 679 | } |
675 | run_queue(gl, 0); | 680 | run_queue(gl, 0); |
676 | spin_unlock(&gl->gl_spin); | 681 | spin_unlock(&gl->gl_spin); |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index b49b55584c84..84a47b709f51 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -500,7 +500,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
500 | out_put_hidden_dir: | 500 | out_put_hidden_dir: |
501 | iput(sbi->hidden_dir); | 501 | iput(sbi->hidden_dir); |
502 | out_put_root: | 502 | out_put_root: |
503 | iput(sbi->alloc_file); | 503 | iput(root); |
504 | out_put_alloc_file: | 504 | out_put_alloc_file: |
505 | iput(sbi->alloc_file); | 505 | iput(sbi->alloc_file); |
506 | out_close_cat_tree: | 506 | out_close_cat_tree: |
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 3031d81f5f0f..4ac88ff79aa6 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
@@ -36,6 +36,7 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, | |||
36 | { | 36 | { |
37 | DECLARE_COMPLETION_ONSTACK(wait); | 37 | DECLARE_COMPLETION_ONSTACK(wait); |
38 | struct bio *bio; | 38 | struct bio *bio; |
39 | int ret = 0; | ||
39 | 40 | ||
40 | bio = bio_alloc(GFP_NOIO, 1); | 41 | bio = bio_alloc(GFP_NOIO, 1); |
41 | bio->bi_sector = sector; | 42 | bio->bi_sector = sector; |
@@ -54,8 +55,10 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, | |||
54 | wait_for_completion(&wait); | 55 | wait_for_completion(&wait); |
55 | 56 | ||
56 | if (!bio_flagged(bio, BIO_UPTODATE)) | 57 | if (!bio_flagged(bio, BIO_UPTODATE)) |
57 | return -EIO; | 58 | ret = -EIO; |
58 | return 0; | 59 | |
60 | bio_put(bio); | ||
61 | return ret; | ||
59 | } | 62 | } |
60 | 63 | ||
61 | static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) | 64 | static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) |
diff --git a/fs/inode.c b/fs/inode.c index 0f7e88a7803f..43566d17d1b8 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -423,7 +423,14 @@ EXPORT_SYMBOL(remove_inode_hash); | |||
423 | void end_writeback(struct inode *inode) | 423 | void end_writeback(struct inode *inode) |
424 | { | 424 | { |
425 | might_sleep(); | 425 | might_sleep(); |
426 | /* | ||
427 | * We have to cycle tree_lock here because reclaim can be still in the | ||
428 | * process of removing the last page (in __delete_from_page_cache()) | ||
429 | * and we must not free mapping under it. | ||
430 | */ | ||
431 | spin_lock_irq(&inode->i_data.tree_lock); | ||
426 | BUG_ON(inode->i_data.nrpages); | 432 | BUG_ON(inode->i_data.nrpages); |
433 | spin_unlock_irq(&inode->i_data.tree_lock); | ||
427 | BUG_ON(!list_empty(&inode->i_data.private_list)); | 434 | BUG_ON(!list_empty(&inode->i_data.private_list)); |
428 | BUG_ON(!(inode->i_state & I_FREEING)); | 435 | BUG_ON(!(inode->i_state & I_FREEING)); |
429 | BUG_ON(inode->i_state & I_CLEAR); | 436 | BUG_ON(inode->i_state & I_CLEAR); |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 3db5ba4568fc..b3cc8586984e 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -974,7 +974,7 @@ out_no_inode: | |||
974 | out_no_read: | 974 | out_no_read: |
975 | printk(KERN_WARNING "%s: bread failed, dev=%s, iso_blknum=%d, block=%d\n", | 975 | printk(KERN_WARNING "%s: bread failed, dev=%s, iso_blknum=%d, block=%d\n", |
976 | __func__, s->s_id, iso_blknum, block); | 976 | __func__, s->s_id, iso_blknum, block); |
977 | goto out_freesbi; | 977 | goto out_freebh; |
978 | out_bad_zone_size: | 978 | out_bad_zone_size: |
979 | printk(KERN_WARNING "ISOFS: Bad logical zone size %ld\n", | 979 | printk(KERN_WARNING "ISOFS: Bad logical zone size %ld\n", |
980 | sbi->s_log_zone_size); | 980 | sbi->s_log_zone_size); |
@@ -989,6 +989,7 @@ out_unknown_format: | |||
989 | 989 | ||
990 | out_freebh: | 990 | out_freebh: |
991 | brelse(bh); | 991 | brelse(bh); |
992 | brelse(pri_bh); | ||
992 | out_freesbi: | 993 | out_freesbi: |
993 | kfree(opt.iocharset); | 994 | kfree(opt.iocharset); |
994 | kfree(sbi); | 995 | kfree(sbi); |
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 6a79fd0a1a32..2c62c5aae82f 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -97,10 +97,14 @@ static int __try_to_free_cp_buf(struct journal_head *jh) | |||
97 | 97 | ||
98 | if (jh->b_jlist == BJ_None && !buffer_locked(bh) && | 98 | if (jh->b_jlist == BJ_None && !buffer_locked(bh) && |
99 | !buffer_dirty(bh) && !buffer_write_io_error(bh)) { | 99 | !buffer_dirty(bh) && !buffer_write_io_error(bh)) { |
100 | /* | ||
101 | * Get our reference so that bh cannot be freed before | ||
102 | * we unlock it | ||
103 | */ | ||
104 | get_bh(bh); | ||
100 | JBUFFER_TRACE(jh, "remove from checkpoint list"); | 105 | JBUFFER_TRACE(jh, "remove from checkpoint list"); |
101 | ret = __jbd2_journal_remove_checkpoint(jh) + 1; | 106 | ret = __jbd2_journal_remove_checkpoint(jh) + 1; |
102 | jbd_unlock_bh_state(bh); | 107 | jbd_unlock_bh_state(bh); |
103 | jbd2_journal_remove_journal_head(bh); | ||
104 | BUFFER_TRACE(bh, "release"); | 108 | BUFFER_TRACE(bh, "release"); |
105 | __brelse(bh); | 109 | __brelse(bh); |
106 | } else { | 110 | } else { |
@@ -223,8 +227,8 @@ restart: | |||
223 | spin_lock(&journal->j_list_lock); | 227 | spin_lock(&journal->j_list_lock); |
224 | goto restart; | 228 | goto restart; |
225 | } | 229 | } |
230 | get_bh(bh); | ||
226 | if (buffer_locked(bh)) { | 231 | if (buffer_locked(bh)) { |
227 | atomic_inc(&bh->b_count); | ||
228 | spin_unlock(&journal->j_list_lock); | 232 | spin_unlock(&journal->j_list_lock); |
229 | jbd_unlock_bh_state(bh); | 233 | jbd_unlock_bh_state(bh); |
230 | wait_on_buffer(bh); | 234 | wait_on_buffer(bh); |
@@ -243,7 +247,6 @@ restart: | |||
243 | */ | 247 | */ |
244 | released = __jbd2_journal_remove_checkpoint(jh); | 248 | released = __jbd2_journal_remove_checkpoint(jh); |
245 | jbd_unlock_bh_state(bh); | 249 | jbd_unlock_bh_state(bh); |
246 | jbd2_journal_remove_journal_head(bh); | ||
247 | __brelse(bh); | 250 | __brelse(bh); |
248 | } | 251 | } |
249 | 252 | ||
@@ -284,7 +287,7 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh, | |||
284 | int ret = 0; | 287 | int ret = 0; |
285 | 288 | ||
286 | if (buffer_locked(bh)) { | 289 | if (buffer_locked(bh)) { |
287 | atomic_inc(&bh->b_count); | 290 | get_bh(bh); |
288 | spin_unlock(&journal->j_list_lock); | 291 | spin_unlock(&journal->j_list_lock); |
289 | jbd_unlock_bh_state(bh); | 292 | jbd_unlock_bh_state(bh); |
290 | wait_on_buffer(bh); | 293 | wait_on_buffer(bh); |
@@ -316,12 +319,12 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh, | |||
316 | ret = 1; | 319 | ret = 1; |
317 | if (unlikely(buffer_write_io_error(bh))) | 320 | if (unlikely(buffer_write_io_error(bh))) |
318 | ret = -EIO; | 321 | ret = -EIO; |
322 | get_bh(bh); | ||
319 | J_ASSERT_JH(jh, !buffer_jbddirty(bh)); | 323 | J_ASSERT_JH(jh, !buffer_jbddirty(bh)); |
320 | BUFFER_TRACE(bh, "remove from checkpoint"); | 324 | BUFFER_TRACE(bh, "remove from checkpoint"); |
321 | __jbd2_journal_remove_checkpoint(jh); | 325 | __jbd2_journal_remove_checkpoint(jh); |
322 | spin_unlock(&journal->j_list_lock); | 326 | spin_unlock(&journal->j_list_lock); |
323 | jbd_unlock_bh_state(bh); | 327 | jbd_unlock_bh_state(bh); |
324 | jbd2_journal_remove_journal_head(bh); | ||
325 | __brelse(bh); | 328 | __brelse(bh); |
326 | } else { | 329 | } else { |
327 | /* | 330 | /* |
@@ -554,7 +557,8 @@ int jbd2_cleanup_journal_tail(journal_t *journal) | |||
554 | /* | 557 | /* |
555 | * journal_clean_one_cp_list | 558 | * journal_clean_one_cp_list |
556 | * | 559 | * |
557 | * Find all the written-back checkpoint buffers in the given list and release them. | 560 | * Find all the written-back checkpoint buffers in the given list and |
561 | * release them. | ||
558 | * | 562 | * |
559 | * Called with the journal locked. | 563 | * Called with the journal locked. |
560 | * Called with j_list_lock held. | 564 | * Called with j_list_lock held. |
@@ -663,8 +667,8 @@ out: | |||
663 | * checkpoint lists. | 667 | * checkpoint lists. |
664 | * | 668 | * |
665 | * The function returns 1 if it frees the transaction, 0 otherwise. | 669 | * The function returns 1 if it frees the transaction, 0 otherwise. |
670 | * The function can free jh and bh. | ||
666 | * | 671 | * |
667 | * This function is called with the journal locked. | ||
668 | * This function is called with j_list_lock held. | 672 | * This function is called with j_list_lock held. |
669 | * This function is called with jbd_lock_bh_state(jh2bh(jh)) | 673 | * This function is called with jbd_lock_bh_state(jh2bh(jh)) |
670 | */ | 674 | */ |
@@ -684,13 +688,14 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | |||
684 | } | 688 | } |
685 | journal = transaction->t_journal; | 689 | journal = transaction->t_journal; |
686 | 690 | ||
691 | JBUFFER_TRACE(jh, "removing from transaction"); | ||
687 | __buffer_unlink(jh); | 692 | __buffer_unlink(jh); |
688 | jh->b_cp_transaction = NULL; | 693 | jh->b_cp_transaction = NULL; |
694 | jbd2_journal_put_journal_head(jh); | ||
689 | 695 | ||
690 | if (transaction->t_checkpoint_list != NULL || | 696 | if (transaction->t_checkpoint_list != NULL || |
691 | transaction->t_checkpoint_io_list != NULL) | 697 | transaction->t_checkpoint_io_list != NULL) |
692 | goto out; | 698 | goto out; |
693 | JBUFFER_TRACE(jh, "transaction has no more buffers"); | ||
694 | 699 | ||
695 | /* | 700 | /* |
696 | * There is one special case to worry about: if we have just pulled the | 701 | * There is one special case to worry about: if we have just pulled the |
@@ -701,10 +706,8 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | |||
701 | * The locking here around t_state is a bit sleazy. | 706 | * The locking here around t_state is a bit sleazy. |
702 | * See the comment at the end of jbd2_journal_commit_transaction(). | 707 | * See the comment at the end of jbd2_journal_commit_transaction(). |
703 | */ | 708 | */ |
704 | if (transaction->t_state != T_FINISHED) { | 709 | if (transaction->t_state != T_FINISHED) |
705 | JBUFFER_TRACE(jh, "belongs to running/committing transaction"); | ||
706 | goto out; | 710 | goto out; |
707 | } | ||
708 | 711 | ||
709 | /* OK, that was the last buffer for the transaction: we can now | 712 | /* OK, that was the last buffer for the transaction: we can now |
710 | safely remove this transaction from the log */ | 713 | safely remove this transaction from the log */ |
@@ -723,7 +726,6 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | |||
723 | wake_up(&journal->j_wait_logspace); | 726 | wake_up(&journal->j_wait_logspace); |
724 | ret = 1; | 727 | ret = 1; |
725 | out: | 728 | out: |
726 | JBUFFER_TRACE(jh, "exit"); | ||
727 | return ret; | 729 | return ret; |
728 | } | 730 | } |
729 | 731 | ||
@@ -742,6 +744,8 @@ void __jbd2_journal_insert_checkpoint(struct journal_head *jh, | |||
742 | J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh))); | 744 | J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh))); |
743 | J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); | 745 | J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); |
744 | 746 | ||
747 | /* Get reference for checkpointing transaction */ | ||
748 | jbd2_journal_grab_journal_head(jh2bh(jh)); | ||
745 | jh->b_cp_transaction = transaction; | 749 | jh->b_cp_transaction = transaction; |
746 | 750 | ||
747 | if (!transaction->t_checkpoint_list) { | 751 | if (!transaction->t_checkpoint_list) { |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 7f21cf3aaf92..eef6979821a4 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -848,10 +848,16 @@ restart_loop: | |||
848 | while (commit_transaction->t_forget) { | 848 | while (commit_transaction->t_forget) { |
849 | transaction_t *cp_transaction; | 849 | transaction_t *cp_transaction; |
850 | struct buffer_head *bh; | 850 | struct buffer_head *bh; |
851 | int try_to_free = 0; | ||
851 | 852 | ||
852 | jh = commit_transaction->t_forget; | 853 | jh = commit_transaction->t_forget; |
853 | spin_unlock(&journal->j_list_lock); | 854 | spin_unlock(&journal->j_list_lock); |
854 | bh = jh2bh(jh); | 855 | bh = jh2bh(jh); |
856 | /* | ||
857 | * Get a reference so that bh cannot be freed before we are | ||
858 | * done with it. | ||
859 | */ | ||
860 | get_bh(bh); | ||
855 | jbd_lock_bh_state(bh); | 861 | jbd_lock_bh_state(bh); |
856 | J_ASSERT_JH(jh, jh->b_transaction == commit_transaction); | 862 | J_ASSERT_JH(jh, jh->b_transaction == commit_transaction); |
857 | 863 | ||
@@ -914,28 +920,27 @@ restart_loop: | |||
914 | __jbd2_journal_insert_checkpoint(jh, commit_transaction); | 920 | __jbd2_journal_insert_checkpoint(jh, commit_transaction); |
915 | if (is_journal_aborted(journal)) | 921 | if (is_journal_aborted(journal)) |
916 | clear_buffer_jbddirty(bh); | 922 | clear_buffer_jbddirty(bh); |
917 | JBUFFER_TRACE(jh, "refile for checkpoint writeback"); | ||
918 | __jbd2_journal_refile_buffer(jh); | ||
919 | jbd_unlock_bh_state(bh); | ||
920 | } else { | 923 | } else { |
921 | J_ASSERT_BH(bh, !buffer_dirty(bh)); | 924 | J_ASSERT_BH(bh, !buffer_dirty(bh)); |
922 | /* The buffer on BJ_Forget list and not jbddirty means | 925 | /* |
926 | * The buffer on BJ_Forget list and not jbddirty means | ||
923 | * it has been freed by this transaction and hence it | 927 | * it has been freed by this transaction and hence it |
924 | * could not have been reallocated until this | 928 | * could not have been reallocated until this |
925 | * transaction has committed. *BUT* it could be | 929 | * transaction has committed. *BUT* it could be |
926 | * reallocated once we have written all the data to | 930 | * reallocated once we have written all the data to |
927 | * disk and before we process the buffer on BJ_Forget | 931 | * disk and before we process the buffer on BJ_Forget |
928 | * list. */ | 932 | * list. |
929 | JBUFFER_TRACE(jh, "refile or unfile freed buffer"); | 933 | */ |
930 | __jbd2_journal_refile_buffer(jh); | 934 | if (!jh->b_next_transaction) |
931 | if (!jh->b_transaction) { | 935 | try_to_free = 1; |
932 | jbd_unlock_bh_state(bh); | ||
933 | /* needs a brelse */ | ||
934 | jbd2_journal_remove_journal_head(bh); | ||
935 | release_buffer_page(bh); | ||
936 | } else | ||
937 | jbd_unlock_bh_state(bh); | ||
938 | } | 936 | } |
937 | JBUFFER_TRACE(jh, "refile or unfile buffer"); | ||
938 | __jbd2_journal_refile_buffer(jh); | ||
939 | jbd_unlock_bh_state(bh); | ||
940 | if (try_to_free) | ||
941 | release_buffer_page(bh); /* Drops bh reference */ | ||
942 | else | ||
943 | __brelse(bh); | ||
939 | cond_resched_lock(&journal->j_list_lock); | 944 | cond_resched_lock(&journal->j_list_lock); |
940 | } | 945 | } |
941 | spin_unlock(&journal->j_list_lock); | 946 | spin_unlock(&journal->j_list_lock); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 9a7826990304..0dfa5b598e68 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -2078,10 +2078,9 @@ static void journal_free_journal_head(struct journal_head *jh) | |||
2078 | * When a buffer has its BH_JBD bit set it is immune from being released by | 2078 | * When a buffer has its BH_JBD bit set it is immune from being released by |
2079 | * core kernel code, mainly via ->b_count. | 2079 | * core kernel code, mainly via ->b_count. |
2080 | * | 2080 | * |
2081 | * A journal_head may be detached from its buffer_head when the journal_head's | 2081 | * A journal_head is detached from its buffer_head when the journal_head's |
2082 | * b_transaction, b_cp_transaction and b_next_transaction pointers are NULL. | 2082 | * b_jcount reaches zero. Running transaction (b_transaction) and checkpoint |
2083 | * Various places in JBD call jbd2_journal_remove_journal_head() to indicate that the | 2083 | * transaction (b_cp_transaction) hold their references to b_jcount. |
2084 | * journal_head can be dropped if needed. | ||
2085 | * | 2084 | * |
2086 | * Various places in the kernel want to attach a journal_head to a buffer_head | 2085 | * Various places in the kernel want to attach a journal_head to a buffer_head |
2087 | * _before_ attaching the journal_head to a transaction. To protect the | 2086 | * _before_ attaching the journal_head to a transaction. To protect the |
@@ -2094,17 +2093,16 @@ static void journal_free_journal_head(struct journal_head *jh) | |||
2094 | * (Attach a journal_head if needed. Increments b_jcount) | 2093 | * (Attach a journal_head if needed. Increments b_jcount) |
2095 | * struct journal_head *jh = jbd2_journal_add_journal_head(bh); | 2094 | * struct journal_head *jh = jbd2_journal_add_journal_head(bh); |
2096 | * ... | 2095 | * ... |
2096 | * (Get another reference for transaction) | ||
2097 | * jbd2_journal_grab_journal_head(bh); | ||
2097 | * jh->b_transaction = xxx; | 2098 | * jh->b_transaction = xxx; |
2099 | * (Put original reference) | ||
2098 | * jbd2_journal_put_journal_head(jh); | 2100 | * jbd2_journal_put_journal_head(jh); |
2099 | * | ||
2100 | * Now, the journal_head's b_jcount is zero, but it is safe from being released | ||
2101 | * because it has a non-zero b_transaction. | ||
2102 | */ | 2101 | */ |
2103 | 2102 | ||
2104 | /* | 2103 | /* |
2105 | * Give a buffer_head a journal_head. | 2104 | * Give a buffer_head a journal_head. |
2106 | * | 2105 | * |
2107 | * Doesn't need the journal lock. | ||
2108 | * May sleep. | 2106 | * May sleep. |
2109 | */ | 2107 | */ |
2110 | struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh) | 2108 | struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh) |
@@ -2168,61 +2166,29 @@ static void __journal_remove_journal_head(struct buffer_head *bh) | |||
2168 | struct journal_head *jh = bh2jh(bh); | 2166 | struct journal_head *jh = bh2jh(bh); |
2169 | 2167 | ||
2170 | J_ASSERT_JH(jh, jh->b_jcount >= 0); | 2168 | J_ASSERT_JH(jh, jh->b_jcount >= 0); |
2171 | 2169 | J_ASSERT_JH(jh, jh->b_transaction == NULL); | |
2172 | get_bh(bh); | 2170 | J_ASSERT_JH(jh, jh->b_next_transaction == NULL); |
2173 | if (jh->b_jcount == 0) { | 2171 | J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); |
2174 | if (jh->b_transaction == NULL && | 2172 | J_ASSERT_JH(jh, jh->b_jlist == BJ_None); |
2175 | jh->b_next_transaction == NULL && | 2173 | J_ASSERT_BH(bh, buffer_jbd(bh)); |
2176 | jh->b_cp_transaction == NULL) { | 2174 | J_ASSERT_BH(bh, jh2bh(jh) == bh); |
2177 | J_ASSERT_JH(jh, jh->b_jlist == BJ_None); | 2175 | BUFFER_TRACE(bh, "remove journal_head"); |
2178 | J_ASSERT_BH(bh, buffer_jbd(bh)); | 2176 | if (jh->b_frozen_data) { |
2179 | J_ASSERT_BH(bh, jh2bh(jh) == bh); | 2177 | printk(KERN_WARNING "%s: freeing b_frozen_data\n", __func__); |
2180 | BUFFER_TRACE(bh, "remove journal_head"); | 2178 | jbd2_free(jh->b_frozen_data, bh->b_size); |
2181 | if (jh->b_frozen_data) { | ||
2182 | printk(KERN_WARNING "%s: freeing " | ||
2183 | "b_frozen_data\n", | ||
2184 | __func__); | ||
2185 | jbd2_free(jh->b_frozen_data, bh->b_size); | ||
2186 | } | ||
2187 | if (jh->b_committed_data) { | ||
2188 | printk(KERN_WARNING "%s: freeing " | ||
2189 | "b_committed_data\n", | ||
2190 | __func__); | ||
2191 | jbd2_free(jh->b_committed_data, bh->b_size); | ||
2192 | } | ||
2193 | bh->b_private = NULL; | ||
2194 | jh->b_bh = NULL; /* debug, really */ | ||
2195 | clear_buffer_jbd(bh); | ||
2196 | __brelse(bh); | ||
2197 | journal_free_journal_head(jh); | ||
2198 | } else { | ||
2199 | BUFFER_TRACE(bh, "journal_head was locked"); | ||
2200 | } | ||
2201 | } | 2179 | } |
2180 | if (jh->b_committed_data) { | ||
2181 | printk(KERN_WARNING "%s: freeing b_committed_data\n", __func__); | ||
2182 | jbd2_free(jh->b_committed_data, bh->b_size); | ||
2183 | } | ||
2184 | bh->b_private = NULL; | ||
2185 | jh->b_bh = NULL; /* debug, really */ | ||
2186 | clear_buffer_jbd(bh); | ||
2187 | journal_free_journal_head(jh); | ||
2202 | } | 2188 | } |
2203 | 2189 | ||
2204 | /* | 2190 | /* |
2205 | * jbd2_journal_remove_journal_head(): if the buffer isn't attached to a transaction | 2191 | * Drop a reference on the passed journal_head. If it fell to zero then |
2206 | * and has a zero b_jcount then remove and release its journal_head. If we did | ||
2207 | * see that the buffer is not used by any transaction we also "logically" | ||
2208 | * decrement ->b_count. | ||
2209 | * | ||
2210 | * We in fact take an additional increment on ->b_count as a convenience, | ||
2211 | * because the caller usually wants to do additional things with the bh | ||
2212 | * after calling here. | ||
2213 | * The caller of jbd2_journal_remove_journal_head() *must* run __brelse(bh) at some | ||
2214 | * time. Once the caller has run __brelse(), the buffer is eligible for | ||
2215 | * reaping by try_to_free_buffers(). | ||
2216 | */ | ||
2217 | void jbd2_journal_remove_journal_head(struct buffer_head *bh) | ||
2218 | { | ||
2219 | jbd_lock_bh_journal_head(bh); | ||
2220 | __journal_remove_journal_head(bh); | ||
2221 | jbd_unlock_bh_journal_head(bh); | ||
2222 | } | ||
2223 | |||
2224 | /* | ||
2225 | * Drop a reference on the passed journal_head. If it fell to zero then try to | ||
2226 | * release the journal_head from the buffer_head. | 2192 | * release the journal_head from the buffer_head. |
2227 | */ | 2193 | */ |
2228 | void jbd2_journal_put_journal_head(struct journal_head *jh) | 2194 | void jbd2_journal_put_journal_head(struct journal_head *jh) |
@@ -2232,11 +2198,12 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) | |||
2232 | jbd_lock_bh_journal_head(bh); | 2198 | jbd_lock_bh_journal_head(bh); |
2233 | J_ASSERT_JH(jh, jh->b_jcount > 0); | 2199 | J_ASSERT_JH(jh, jh->b_jcount > 0); |
2234 | --jh->b_jcount; | 2200 | --jh->b_jcount; |
2235 | if (!jh->b_jcount && !jh->b_transaction) { | 2201 | if (!jh->b_jcount) { |
2236 | __journal_remove_journal_head(bh); | 2202 | __journal_remove_journal_head(bh); |
2203 | jbd_unlock_bh_journal_head(bh); | ||
2237 | __brelse(bh); | 2204 | __brelse(bh); |
2238 | } | 2205 | } else |
2239 | jbd_unlock_bh_journal_head(bh); | 2206 | jbd_unlock_bh_journal_head(bh); |
2240 | } | 2207 | } |
2241 | 2208 | ||
2242 | /* | 2209 | /* |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 3eec82d32fd4..2d7109414cdd 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | 31 | ||
32 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); | 32 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); |
33 | static void __jbd2_journal_unfile_buffer(struct journal_head *jh); | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * jbd2_get_transaction: obtain a new transaction_t object. | 36 | * jbd2_get_transaction: obtain a new transaction_t object. |
@@ -764,7 +765,6 @@ repeat: | |||
764 | if (!jh->b_transaction) { | 765 | if (!jh->b_transaction) { |
765 | JBUFFER_TRACE(jh, "no transaction"); | 766 | JBUFFER_TRACE(jh, "no transaction"); |
766 | J_ASSERT_JH(jh, !jh->b_next_transaction); | 767 | J_ASSERT_JH(jh, !jh->b_next_transaction); |
767 | jh->b_transaction = transaction; | ||
768 | JBUFFER_TRACE(jh, "file as BJ_Reserved"); | 768 | JBUFFER_TRACE(jh, "file as BJ_Reserved"); |
769 | spin_lock(&journal->j_list_lock); | 769 | spin_lock(&journal->j_list_lock); |
770 | __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); | 770 | __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); |
@@ -814,7 +814,6 @@ out: | |||
814 | * int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update. | 814 | * int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update. |
815 | * @handle: transaction to add buffer modifications to | 815 | * @handle: transaction to add buffer modifications to |
816 | * @bh: bh to be used for metadata writes | 816 | * @bh: bh to be used for metadata writes |
817 | * @credits: variable that will receive credits for the buffer | ||
818 | * | 817 | * |
819 | * Returns an error code or 0 on success. | 818 | * Returns an error code or 0 on success. |
820 | * | 819 | * |
@@ -896,8 +895,6 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) | |||
896 | * committed and so it's safe to clear the dirty bit. | 895 | * committed and so it's safe to clear the dirty bit. |
897 | */ | 896 | */ |
898 | clear_buffer_dirty(jh2bh(jh)); | 897 | clear_buffer_dirty(jh2bh(jh)); |
899 | jh->b_transaction = transaction; | ||
900 | |||
901 | /* first access by this transaction */ | 898 | /* first access by this transaction */ |
902 | jh->b_modified = 0; | 899 | jh->b_modified = 0; |
903 | 900 | ||
@@ -932,7 +929,6 @@ out: | |||
932 | * non-rewindable consequences | 929 | * non-rewindable consequences |
933 | * @handle: transaction | 930 | * @handle: transaction |
934 | * @bh: buffer to undo | 931 | * @bh: buffer to undo |
935 | * @credits: store the number of taken credits here (if not NULL) | ||
936 | * | 932 | * |
937 | * Sometimes there is a need to distinguish between metadata which has | 933 | * Sometimes there is a need to distinguish between metadata which has |
938 | * been committed to disk and that which has not. The ext3fs code uses | 934 | * been committed to disk and that which has not. The ext3fs code uses |
@@ -1232,8 +1228,6 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
1232 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); | 1228 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); |
1233 | } else { | 1229 | } else { |
1234 | __jbd2_journal_unfile_buffer(jh); | 1230 | __jbd2_journal_unfile_buffer(jh); |
1235 | jbd2_journal_remove_journal_head(bh); | ||
1236 | __brelse(bh); | ||
1237 | if (!buffer_jbd(bh)) { | 1231 | if (!buffer_jbd(bh)) { |
1238 | spin_unlock(&journal->j_list_lock); | 1232 | spin_unlock(&journal->j_list_lock); |
1239 | jbd_unlock_bh_state(bh); | 1233 | jbd_unlock_bh_state(bh); |
@@ -1556,19 +1550,32 @@ void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh) | |||
1556 | mark_buffer_dirty(bh); /* Expose it to the VM */ | 1550 | mark_buffer_dirty(bh); /* Expose it to the VM */ |
1557 | } | 1551 | } |
1558 | 1552 | ||
1559 | void __jbd2_journal_unfile_buffer(struct journal_head *jh) | 1553 | /* |
1554 | * Remove buffer from all transactions. | ||
1555 | * | ||
1556 | * Called with bh_state lock and j_list_lock | ||
1557 | * | ||
1558 | * jh and bh may be already freed when this function returns. | ||
1559 | */ | ||
1560 | static void __jbd2_journal_unfile_buffer(struct journal_head *jh) | ||
1560 | { | 1561 | { |
1561 | __jbd2_journal_temp_unlink_buffer(jh); | 1562 | __jbd2_journal_temp_unlink_buffer(jh); |
1562 | jh->b_transaction = NULL; | 1563 | jh->b_transaction = NULL; |
1564 | jbd2_journal_put_journal_head(jh); | ||
1563 | } | 1565 | } |
1564 | 1566 | ||
1565 | void jbd2_journal_unfile_buffer(journal_t *journal, struct journal_head *jh) | 1567 | void jbd2_journal_unfile_buffer(journal_t *journal, struct journal_head *jh) |
1566 | { | 1568 | { |
1567 | jbd_lock_bh_state(jh2bh(jh)); | 1569 | struct buffer_head *bh = jh2bh(jh); |
1570 | |||
1571 | /* Get reference so that buffer cannot be freed before we unlock it */ | ||
1572 | get_bh(bh); | ||
1573 | jbd_lock_bh_state(bh); | ||
1568 | spin_lock(&journal->j_list_lock); | 1574 | spin_lock(&journal->j_list_lock); |
1569 | __jbd2_journal_unfile_buffer(jh); | 1575 | __jbd2_journal_unfile_buffer(jh); |
1570 | spin_unlock(&journal->j_list_lock); | 1576 | spin_unlock(&journal->j_list_lock); |
1571 | jbd_unlock_bh_state(jh2bh(jh)); | 1577 | jbd_unlock_bh_state(bh); |
1578 | __brelse(bh); | ||
1572 | } | 1579 | } |
1573 | 1580 | ||
1574 | /* | 1581 | /* |
@@ -1595,8 +1602,6 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) | |||
1595 | if (jh->b_jlist == BJ_None) { | 1602 | if (jh->b_jlist == BJ_None) { |
1596 | JBUFFER_TRACE(jh, "remove from checkpoint list"); | 1603 | JBUFFER_TRACE(jh, "remove from checkpoint list"); |
1597 | __jbd2_journal_remove_checkpoint(jh); | 1604 | __jbd2_journal_remove_checkpoint(jh); |
1598 | jbd2_journal_remove_journal_head(bh); | ||
1599 | __brelse(bh); | ||
1600 | } | 1605 | } |
1601 | } | 1606 | } |
1602 | spin_unlock(&journal->j_list_lock); | 1607 | spin_unlock(&journal->j_list_lock); |
@@ -1659,7 +1664,6 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, | |||
1659 | /* | 1664 | /* |
1660 | * We take our own ref against the journal_head here to avoid | 1665 | * We take our own ref against the journal_head here to avoid |
1661 | * having to add tons of locking around each instance of | 1666 | * having to add tons of locking around each instance of |
1662 | * jbd2_journal_remove_journal_head() and | ||
1663 | * jbd2_journal_put_journal_head(). | 1667 | * jbd2_journal_put_journal_head(). |
1664 | */ | 1668 | */ |
1665 | jh = jbd2_journal_grab_journal_head(bh); | 1669 | jh = jbd2_journal_grab_journal_head(bh); |
@@ -1697,10 +1701,9 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) | |||
1697 | int may_free = 1; | 1701 | int may_free = 1; |
1698 | struct buffer_head *bh = jh2bh(jh); | 1702 | struct buffer_head *bh = jh2bh(jh); |
1699 | 1703 | ||
1700 | __jbd2_journal_unfile_buffer(jh); | ||
1701 | |||
1702 | if (jh->b_cp_transaction) { | 1704 | if (jh->b_cp_transaction) { |
1703 | JBUFFER_TRACE(jh, "on running+cp transaction"); | 1705 | JBUFFER_TRACE(jh, "on running+cp transaction"); |
1706 | __jbd2_journal_temp_unlink_buffer(jh); | ||
1704 | /* | 1707 | /* |
1705 | * We don't want to write the buffer anymore, clear the | 1708 | * We don't want to write the buffer anymore, clear the |
1706 | * bit so that we don't confuse checks in | 1709 | * bit so that we don't confuse checks in |
@@ -1711,8 +1714,7 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) | |||
1711 | may_free = 0; | 1714 | may_free = 0; |
1712 | } else { | 1715 | } else { |
1713 | JBUFFER_TRACE(jh, "on running transaction"); | 1716 | JBUFFER_TRACE(jh, "on running transaction"); |
1714 | jbd2_journal_remove_journal_head(bh); | 1717 | __jbd2_journal_unfile_buffer(jh); |
1715 | __brelse(bh); | ||
1716 | } | 1718 | } |
1717 | return may_free; | 1719 | return may_free; |
1718 | } | 1720 | } |
@@ -1990,6 +1992,8 @@ void __jbd2_journal_file_buffer(struct journal_head *jh, | |||
1990 | 1992 | ||
1991 | if (jh->b_transaction) | 1993 | if (jh->b_transaction) |
1992 | __jbd2_journal_temp_unlink_buffer(jh); | 1994 | __jbd2_journal_temp_unlink_buffer(jh); |
1995 | else | ||
1996 | jbd2_journal_grab_journal_head(bh); | ||
1993 | jh->b_transaction = transaction; | 1997 | jh->b_transaction = transaction; |
1994 | 1998 | ||
1995 | switch (jlist) { | 1999 | switch (jlist) { |
@@ -2041,9 +2045,10 @@ void jbd2_journal_file_buffer(struct journal_head *jh, | |||
2041 | * already started to be used by a subsequent transaction, refile the | 2045 | * already started to be used by a subsequent transaction, refile the |
2042 | * buffer on that transaction's metadata list. | 2046 | * buffer on that transaction's metadata list. |
2043 | * | 2047 | * |
2044 | * Called under journal->j_list_lock | 2048 | * Called under j_list_lock |
2045 | * | ||
2046 | * Called under jbd_lock_bh_state(jh2bh(jh)) | 2049 | * Called under jbd_lock_bh_state(jh2bh(jh)) |
2050 | * | ||
2051 | * jh and bh may be already free when this function returns | ||
2047 | */ | 2052 | */ |
2048 | void __jbd2_journal_refile_buffer(struct journal_head *jh) | 2053 | void __jbd2_journal_refile_buffer(struct journal_head *jh) |
2049 | { | 2054 | { |
@@ -2067,6 +2072,11 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) | |||
2067 | 2072 | ||
2068 | was_dirty = test_clear_buffer_jbddirty(bh); | 2073 | was_dirty = test_clear_buffer_jbddirty(bh); |
2069 | __jbd2_journal_temp_unlink_buffer(jh); | 2074 | __jbd2_journal_temp_unlink_buffer(jh); |
2075 | /* | ||
2076 | * We set b_transaction here because b_next_transaction will inherit | ||
2077 | * our jh reference and thus __jbd2_journal_file_buffer() must not | ||
2078 | * take a new one. | ||
2079 | */ | ||
2070 | jh->b_transaction = jh->b_next_transaction; | 2080 | jh->b_transaction = jh->b_next_transaction; |
2071 | jh->b_next_transaction = NULL; | 2081 | jh->b_next_transaction = NULL; |
2072 | if (buffer_freed(bh)) | 2082 | if (buffer_freed(bh)) |
@@ -2083,30 +2093,21 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) | |||
2083 | } | 2093 | } |
2084 | 2094 | ||
2085 | /* | 2095 | /* |
2086 | * For the unlocked version of this call, also make sure that any | 2096 | * __jbd2_journal_refile_buffer() with necessary locking added. We take our |
2087 | * hanging journal_head is cleaned up if necessary. | 2097 | * bh reference so that we can safely unlock bh. |
2088 | * | 2098 | * |
2089 | * __jbd2_journal_refile_buffer is usually called as part of a single locked | 2099 | * The jh and bh may be freed by this call. |
2090 | * operation on a buffer_head, in which the caller is probably going to | ||
2091 | * be hooking the journal_head onto other lists. In that case it is up | ||
2092 | * to the caller to remove the journal_head if necessary. For the | ||
2093 | * unlocked jbd2_journal_refile_buffer call, the caller isn't going to be | ||
2094 | * doing anything else to the buffer so we need to do the cleanup | ||
2095 | * ourselves to avoid a jh leak. | ||
2096 | * | ||
2097 | * *** The journal_head may be freed by this call! *** | ||
2098 | */ | 2100 | */ |
2099 | void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh) | 2101 | void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh) |
2100 | { | 2102 | { |
2101 | struct buffer_head *bh = jh2bh(jh); | 2103 | struct buffer_head *bh = jh2bh(jh); |
2102 | 2104 | ||
2105 | /* Get reference so that buffer cannot be freed before we unlock it */ | ||
2106 | get_bh(bh); | ||
2103 | jbd_lock_bh_state(bh); | 2107 | jbd_lock_bh_state(bh); |
2104 | spin_lock(&journal->j_list_lock); | 2108 | spin_lock(&journal->j_list_lock); |
2105 | |||
2106 | __jbd2_journal_refile_buffer(jh); | 2109 | __jbd2_journal_refile_buffer(jh); |
2107 | jbd_unlock_bh_state(bh); | 2110 | jbd_unlock_bh_state(bh); |
2108 | jbd2_journal_remove_journal_head(bh); | ||
2109 | |||
2110 | spin_unlock(&journal->j_list_lock); | 2111 | spin_unlock(&journal->j_list_lock); |
2111 | __brelse(bh); | 2112 | __brelse(bh); |
2112 | } | 2113 | } |
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index c5ce6c1d1ff4..2f3f531f3606 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -66,9 +66,9 @@ static int jfs_open(struct inode *inode, struct file *file) | |||
66 | struct jfs_inode_info *ji = JFS_IP(inode); | 66 | struct jfs_inode_info *ji = JFS_IP(inode); |
67 | spin_lock_irq(&ji->ag_lock); | 67 | spin_lock_irq(&ji->ag_lock); |
68 | if (ji->active_ag == -1) { | 68 | if (ji->active_ag == -1) { |
69 | ji->active_ag = ji->agno; | 69 | struct jfs_sb_info *jfs_sb = JFS_SBI(inode->i_sb); |
70 | atomic_inc( | 70 | ji->active_ag = BLKTOAG(addressPXD(&ji->ixpxd), jfs_sb); |
71 | &JFS_SBI(inode->i_sb)->bmap->db_active[ji->agno]); | 71 | atomic_inc( &jfs_sb->bmap->db_active[ji->active_ag]); |
72 | } | 72 | } |
73 | spin_unlock_irq(&ji->ag_lock); | 73 | spin_unlock_irq(&ji->ag_lock); |
74 | } | 74 | } |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index ed53a4740168..b78b2f978f04 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -397,7 +397,7 @@ int diRead(struct inode *ip) | |||
397 | release_metapage(mp); | 397 | release_metapage(mp); |
398 | 398 | ||
399 | /* set the ag for the inode */ | 399 | /* set the ag for the inode */ |
400 | JFS_IP(ip)->agno = BLKTOAG(agstart, sbi); | 400 | JFS_IP(ip)->agstart = agstart; |
401 | JFS_IP(ip)->active_ag = -1; | 401 | JFS_IP(ip)->active_ag = -1; |
402 | 402 | ||
403 | return (rc); | 403 | return (rc); |
@@ -901,7 +901,7 @@ int diFree(struct inode *ip) | |||
901 | 901 | ||
902 | /* get the allocation group for this ino. | 902 | /* get the allocation group for this ino. |
903 | */ | 903 | */ |
904 | agno = JFS_IP(ip)->agno; | 904 | agno = BLKTOAG(JFS_IP(ip)->agstart, JFS_SBI(ip->i_sb)); |
905 | 905 | ||
906 | /* Lock the AG specific inode map information | 906 | /* Lock the AG specific inode map information |
907 | */ | 907 | */ |
@@ -1315,12 +1315,11 @@ int diFree(struct inode *ip) | |||
1315 | static inline void | 1315 | static inline void |
1316 | diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) | 1316 | diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) |
1317 | { | 1317 | { |
1318 | struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); | ||
1319 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); | 1318 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); |
1320 | 1319 | ||
1321 | ip->i_ino = (iagno << L2INOSPERIAG) + ino; | 1320 | ip->i_ino = (iagno << L2INOSPERIAG) + ino; |
1322 | jfs_ip->ixpxd = iagp->inoext[extno]; | 1321 | jfs_ip->ixpxd = iagp->inoext[extno]; |
1323 | jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); | 1322 | jfs_ip->agstart = le64_to_cpu(iagp->agstart); |
1324 | jfs_ip->active_ag = -1; | 1323 | jfs_ip->active_ag = -1; |
1325 | } | 1324 | } |
1326 | 1325 | ||
@@ -1379,7 +1378,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) | |||
1379 | */ | 1378 | */ |
1380 | 1379 | ||
1381 | /* get the ag number of this iag */ | 1380 | /* get the ag number of this iag */ |
1382 | agno = JFS_IP(pip)->agno; | 1381 | agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb)); |
1383 | 1382 | ||
1384 | if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { | 1383 | if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { |
1385 | /* | 1384 | /* |
@@ -2921,10 +2920,9 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) | |||
2921 | continue; | 2920 | continue; |
2922 | } | 2921 | } |
2923 | 2922 | ||
2924 | /* agstart that computes to the same ag is treated as same; */ | ||
2925 | agstart = le64_to_cpu(iagp->agstart); | 2923 | agstart = le64_to_cpu(iagp->agstart); |
2926 | /* iagp->agstart = agstart & ~(mp->db_agsize - 1); */ | ||
2927 | n = agstart >> mp->db_agl2size; | 2924 | n = agstart >> mp->db_agl2size; |
2925 | iagp->agstart = cpu_to_le64((s64)n << mp->db_agl2size); | ||
2928 | 2926 | ||
2929 | /* compute backed inodes */ | 2927 | /* compute backed inodes */ |
2930 | numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts)) | 2928 | numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts)) |
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index 1439f119ec83..584a4a1a6e81 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h | |||
@@ -50,8 +50,9 @@ struct jfs_inode_info { | |||
50 | short btindex; /* btpage entry index*/ | 50 | short btindex; /* btpage entry index*/ |
51 | struct inode *ipimap; /* inode map */ | 51 | struct inode *ipimap; /* inode map */ |
52 | unsigned long cflag; /* commit flags */ | 52 | unsigned long cflag; /* commit flags */ |
53 | u64 agstart; /* agstart of the containing IAG */ | ||
53 | u16 bxflag; /* xflag of pseudo buffer? */ | 54 | u16 bxflag; /* xflag of pseudo buffer? */ |
54 | unchar agno; /* ag number */ | 55 | unchar pad; |
55 | signed char active_ag; /* ag currently allocating from */ | 56 | signed char active_ag; /* ag currently allocating from */ |
56 | lid_t blid; /* lid of pseudo buffer? */ | 57 | lid_t blid; /* lid of pseudo buffer? */ |
57 | lid_t atlhead; /* anonymous tlock list head */ | 58 | lid_t atlhead; /* anonymous tlock list head */ |
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 278e3fb40b71..583636f745e5 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -1123,7 +1123,7 @@ int lmLogOpen(struct super_block *sb) | |||
1123 | bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, | 1123 | bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
1124 | log); | 1124 | log); |
1125 | if (IS_ERR(bdev)) { | 1125 | if (IS_ERR(bdev)) { |
1126 | rc = -PTR_ERR(bdev); | 1126 | rc = PTR_ERR(bdev); |
1127 | goto free; | 1127 | goto free; |
1128 | } | 1128 | } |
1129 | 1129 | ||
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c index 8ea5efb5a34e..8d0c1c7c0820 100644 --- a/fs/jfs/resize.c +++ b/fs/jfs/resize.c | |||
@@ -80,7 +80,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) | |||
80 | int log_formatted = 0; | 80 | int log_formatted = 0; |
81 | struct inode *iplist[1]; | 81 | struct inode *iplist[1]; |
82 | struct jfs_superblock *j_sb, *j_sb2; | 82 | struct jfs_superblock *j_sb, *j_sb2; |
83 | uint old_agsize; | 83 | s64 old_agsize; |
84 | int agsizechanged = 0; | 84 | int agsizechanged = 0; |
85 | struct buffer_head *bh, *bh2; | 85 | struct buffer_head *bh, *bh2; |
86 | 86 | ||
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index adb45ec9038c..e374050a911c 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -708,7 +708,13 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) | |||
708 | 708 | ||
709 | if (task->tk_status < 0) { | 709 | if (task->tk_status < 0) { |
710 | dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status); | 710 | dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status); |
711 | goto retry_rebind; | 711 | switch (task->tk_status) { |
712 | case -EACCES: | ||
713 | case -EIO: | ||
714 | goto die; | ||
715 | default: | ||
716 | goto retry_rebind; | ||
717 | } | ||
712 | } | 718 | } |
713 | if (status == NLM_LCK_DENIED_GRACE_PERIOD) { | 719 | if (status == NLM_LCK_DENIED_GRACE_PERIOD) { |
714 | rpc_delay(task, NLMCLNT_GRACE_WAIT); | 720 | rpc_delay(task, NLMCLNT_GRACE_WAIT); |
diff --git a/fs/locks.c b/fs/locks.c index 0a4f50dfadfb..b286539d547a 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -160,10 +160,28 @@ EXPORT_SYMBOL_GPL(unlock_flocks); | |||
160 | 160 | ||
161 | static struct kmem_cache *filelock_cache __read_mostly; | 161 | static struct kmem_cache *filelock_cache __read_mostly; |
162 | 162 | ||
163 | static void locks_init_lock_always(struct file_lock *fl) | ||
164 | { | ||
165 | fl->fl_next = NULL; | ||
166 | fl->fl_fasync = NULL; | ||
167 | fl->fl_owner = NULL; | ||
168 | fl->fl_pid = 0; | ||
169 | fl->fl_nspid = NULL; | ||
170 | fl->fl_file = NULL; | ||
171 | fl->fl_flags = 0; | ||
172 | fl->fl_type = 0; | ||
173 | fl->fl_start = fl->fl_end = 0; | ||
174 | } | ||
175 | |||
163 | /* Allocate an empty lock structure. */ | 176 | /* Allocate an empty lock structure. */ |
164 | struct file_lock *locks_alloc_lock(void) | 177 | struct file_lock *locks_alloc_lock(void) |
165 | { | 178 | { |
166 | return kmem_cache_alloc(filelock_cache, GFP_KERNEL); | 179 | struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL); |
180 | |||
181 | if (fl) | ||
182 | locks_init_lock_always(fl); | ||
183 | |||
184 | return fl; | ||
167 | } | 185 | } |
168 | EXPORT_SYMBOL_GPL(locks_alloc_lock); | 186 | EXPORT_SYMBOL_GPL(locks_alloc_lock); |
169 | 187 | ||
@@ -200,17 +218,9 @@ void locks_init_lock(struct file_lock *fl) | |||
200 | INIT_LIST_HEAD(&fl->fl_link); | 218 | INIT_LIST_HEAD(&fl->fl_link); |
201 | INIT_LIST_HEAD(&fl->fl_block); | 219 | INIT_LIST_HEAD(&fl->fl_block); |
202 | init_waitqueue_head(&fl->fl_wait); | 220 | init_waitqueue_head(&fl->fl_wait); |
203 | fl->fl_next = NULL; | ||
204 | fl->fl_fasync = NULL; | ||
205 | fl->fl_owner = NULL; | ||
206 | fl->fl_pid = 0; | ||
207 | fl->fl_nspid = NULL; | ||
208 | fl->fl_file = NULL; | ||
209 | fl->fl_flags = 0; | ||
210 | fl->fl_type = 0; | ||
211 | fl->fl_start = fl->fl_end = 0; | ||
212 | fl->fl_ops = NULL; | 221 | fl->fl_ops = NULL; |
213 | fl->fl_lmops = NULL; | 222 | fl->fl_lmops = NULL; |
223 | locks_init_lock_always(fl); | ||
214 | } | 224 | } |
215 | 225 | ||
216 | EXPORT_SYMBOL(locks_init_lock); | 226 | EXPORT_SYMBOL(locks_init_lock); |
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 9ed89d1663f8..1afae26cf236 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -555,13 +555,6 @@ static int logfs_symlink(struct inode *dir, struct dentry *dentry, | |||
555 | return __logfs_create(dir, dentry, inode, target, destlen); | 555 | return __logfs_create(dir, dentry, inode, target, destlen); |
556 | } | 556 | } |
557 | 557 | ||
558 | static int logfs_permission(struct inode *inode, int mask, unsigned int flags) | ||
559 | { | ||
560 | if (flags & IPERM_FLAG_RCU) | ||
561 | return -ECHILD; | ||
562 | return generic_permission(inode, mask, flags, NULL); | ||
563 | } | ||
564 | |||
565 | static int logfs_link(struct dentry *old_dentry, struct inode *dir, | 558 | static int logfs_link(struct dentry *old_dentry, struct inode *dir, |
566 | struct dentry *dentry) | 559 | struct dentry *dentry) |
567 | { | 560 | { |
@@ -820,7 +813,6 @@ const struct inode_operations logfs_dir_iops = { | |||
820 | .mknod = logfs_mknod, | 813 | .mknod = logfs_mknod, |
821 | .rename = logfs_rename, | 814 | .rename = logfs_rename, |
822 | .rmdir = logfs_rmdir, | 815 | .rmdir = logfs_rmdir, |
823 | .permission = logfs_permission, | ||
824 | .symlink = logfs_symlink, | 816 | .symlink = logfs_symlink, |
825 | .unlink = logfs_unlink, | 817 | .unlink = logfs_unlink, |
826 | }; | 818 | }; |
diff --git a/fs/namei.c b/fs/namei.c index e2e4e8d032ee..0223c41fb114 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -238,7 +238,8 @@ int generic_permission(struct inode *inode, int mask, unsigned int flags, | |||
238 | 238 | ||
239 | /* | 239 | /* |
240 | * Read/write DACs are always overridable. | 240 | * Read/write DACs are always overridable. |
241 | * Executable DACs are overridable if at least one exec bit is set. | 241 | * Executable DACs are overridable for all directories and |
242 | * for non-directories that have least one exec bit set. | ||
242 | */ | 243 | */ |
243 | if (!(mask & MAY_EXEC) || execute_ok(inode)) | 244 | if (!(mask & MAY_EXEC) || execute_ok(inode)) |
244 | if (ns_capable(inode_userns(inode), CAP_DAC_OVERRIDE)) | 245 | if (ns_capable(inode_userns(inode), CAP_DAC_OVERRIDE)) |
@@ -812,6 +813,11 @@ static int follow_automount(struct path *path, unsigned flags, | |||
812 | if (!mnt) /* mount collision */ | 813 | if (!mnt) /* mount collision */ |
813 | return 0; | 814 | return 0; |
814 | 815 | ||
816 | if (!*need_mntput) { | ||
817 | /* lock_mount() may release path->mnt on error */ | ||
818 | mntget(path->mnt); | ||
819 | *need_mntput = true; | ||
820 | } | ||
815 | err = finish_automount(mnt, path); | 821 | err = finish_automount(mnt, path); |
816 | 822 | ||
817 | switch (err) { | 823 | switch (err) { |
@@ -819,12 +825,9 @@ static int follow_automount(struct path *path, unsigned flags, | |||
819 | /* Someone else made a mount here whilst we were busy */ | 825 | /* Someone else made a mount here whilst we were busy */ |
820 | return 0; | 826 | return 0; |
821 | case 0: | 827 | case 0: |
822 | dput(path->dentry); | 828 | path_put(path); |
823 | if (*need_mntput) | ||
824 | mntput(path->mnt); | ||
825 | path->mnt = mnt; | 829 | path->mnt = mnt; |
826 | path->dentry = dget(mnt->mnt_root); | 830 | path->dentry = dget(mnt->mnt_root); |
827 | *need_mntput = true; | ||
828 | return 0; | 831 | return 0; |
829 | default: | 832 | default: |
830 | return err; | 833 | return err; |
@@ -844,9 +847,10 @@ static int follow_automount(struct path *path, unsigned flags, | |||
844 | */ | 847 | */ |
845 | static int follow_managed(struct path *path, unsigned flags) | 848 | static int follow_managed(struct path *path, unsigned flags) |
846 | { | 849 | { |
850 | struct vfsmount *mnt = path->mnt; /* held by caller, must be left alone */ | ||
847 | unsigned managed; | 851 | unsigned managed; |
848 | bool need_mntput = false; | 852 | bool need_mntput = false; |
849 | int ret; | 853 | int ret = 0; |
850 | 854 | ||
851 | /* Given that we're not holding a lock here, we retain the value in a | 855 | /* Given that we're not holding a lock here, we retain the value in a |
852 | * local variable for each dentry as we look at it so that we don't see | 856 | * local variable for each dentry as we look at it so that we don't see |
@@ -861,7 +865,7 @@ static int follow_managed(struct path *path, unsigned flags) | |||
861 | BUG_ON(!path->dentry->d_op->d_manage); | 865 | BUG_ON(!path->dentry->d_op->d_manage); |
862 | ret = path->dentry->d_op->d_manage(path->dentry, false); | 866 | ret = path->dentry->d_op->d_manage(path->dentry, false); |
863 | if (ret < 0) | 867 | if (ret < 0) |
864 | return ret == -EISDIR ? 0 : ret; | 868 | break; |
865 | } | 869 | } |
866 | 870 | ||
867 | /* Transit to a mounted filesystem. */ | 871 | /* Transit to a mounted filesystem. */ |
@@ -887,14 +891,19 @@ static int follow_managed(struct path *path, unsigned flags) | |||
887 | if (managed & DCACHE_NEED_AUTOMOUNT) { | 891 | if (managed & DCACHE_NEED_AUTOMOUNT) { |
888 | ret = follow_automount(path, flags, &need_mntput); | 892 | ret = follow_automount(path, flags, &need_mntput); |
889 | if (ret < 0) | 893 | if (ret < 0) |
890 | return ret == -EISDIR ? 0 : ret; | 894 | break; |
891 | continue; | 895 | continue; |
892 | } | 896 | } |
893 | 897 | ||
894 | /* We didn't change the current path point */ | 898 | /* We didn't change the current path point */ |
895 | break; | 899 | break; |
896 | } | 900 | } |
897 | return 0; | 901 | |
902 | if (need_mntput && path->mnt == mnt) | ||
903 | mntput(path->mnt); | ||
904 | if (ret == -EISDIR) | ||
905 | ret = 0; | ||
906 | return ret; | ||
898 | } | 907 | } |
899 | 908 | ||
900 | int follow_down_one(struct path *path) | 909 | int follow_down_one(struct path *path) |
@@ -1003,9 +1012,6 @@ failed: | |||
1003 | * Follow down to the covering mount currently visible to userspace. At each | 1012 | * Follow down to the covering mount currently visible to userspace. At each |
1004 | * point, the filesystem owning that dentry may be queried as to whether the | 1013 | * point, the filesystem owning that dentry may be queried as to whether the |
1005 | * caller is permitted to proceed or not. | 1014 | * caller is permitted to proceed or not. |
1006 | * | ||
1007 | * Care must be taken as namespace_sem may be held (indicated by mounting_here | ||
1008 | * being true). | ||
1009 | */ | 1015 | */ |
1010 | int follow_down(struct path *path) | 1016 | int follow_down(struct path *path) |
1011 | { | 1017 | { |
@@ -2624,6 +2630,10 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2624 | error = PTR_ERR(dentry); | 2630 | error = PTR_ERR(dentry); |
2625 | if (IS_ERR(dentry)) | 2631 | if (IS_ERR(dentry)) |
2626 | goto exit2; | 2632 | goto exit2; |
2633 | if (!dentry->d_inode) { | ||
2634 | error = -ENOENT; | ||
2635 | goto exit3; | ||
2636 | } | ||
2627 | error = mnt_want_write(nd.path.mnt); | 2637 | error = mnt_want_write(nd.path.mnt); |
2628 | if (error) | 2638 | if (error) |
2629 | goto exit3; | 2639 | goto exit3; |
@@ -2712,8 +2722,9 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2712 | if (nd.last.name[nd.last.len]) | 2722 | if (nd.last.name[nd.last.len]) |
2713 | goto slashes; | 2723 | goto slashes; |
2714 | inode = dentry->d_inode; | 2724 | inode = dentry->d_inode; |
2715 | if (inode) | 2725 | if (!inode) |
2716 | ihold(inode); | 2726 | goto slashes; |
2727 | ihold(inode); | ||
2717 | error = mnt_want_write(nd.path.mnt); | 2728 | error = mnt_want_write(nd.path.mnt); |
2718 | if (error) | 2729 | if (error) |
2719 | goto exit2; | 2730 | goto exit2; |
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index ce153a6b3aec..419119c371bf 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -259,12 +259,10 @@ static void nfs_fscache_disable_inode_cookie(struct inode *inode) | |||
259 | dfprintk(FSCACHE, | 259 | dfprintk(FSCACHE, |
260 | "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); | 260 | "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); |
261 | 261 | ||
262 | /* Need to invalidate any mapped pages that were read in before | 262 | /* Need to uncache any pages attached to this inode that |
263 | * turning off the cache. | 263 | * fscache knows about before turning off the cache. |
264 | */ | 264 | */ |
265 | if (inode->i_mapping && inode->i_mapping->nrpages) | 265 | fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode); |
266 | invalidate_inode_pages2(inode->i_mapping); | ||
267 | |||
268 | nfs_fscache_zap_inode_cookie(inode); | 266 | nfs_fscache_zap_inode_cookie(inode); |
269 | } | 267 | } |
270 | } | 268 | } |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 144f2a3c7185..6f4850deb272 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -256,7 +256,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
256 | 256 | ||
257 | nfs_attr_check_mountpoint(sb, fattr); | 257 | nfs_attr_check_mountpoint(sb, fattr); |
258 | 258 | ||
259 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0 && (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) | 259 | if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) && |
260 | !nfs_attr_use_mounted_on_fileid(fattr)) | ||
260 | goto out_no_inode; | 261 | goto out_no_inode; |
261 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) | 262 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) |
262 | goto out_no_inode; | 263 | goto out_no_inode; |
@@ -1294,7 +1295,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1294 | if (new_isize != cur_isize) { | 1295 | if (new_isize != cur_isize) { |
1295 | /* Do we perhaps have any outstanding writes, or has | 1296 | /* Do we perhaps have any outstanding writes, or has |
1296 | * the file grown beyond our last write? */ | 1297 | * the file grown beyond our last write? */ |
1297 | if (nfsi->npages == 0 || new_isize > cur_isize) { | 1298 | if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) || |
1299 | new_isize > cur_isize) { | ||
1298 | i_size_write(inode, new_isize); | 1300 | i_size_write(inode, new_isize); |
1299 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1301 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1300 | } | 1302 | } |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index b9056cbe68d6..2a55347a2daa 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -45,6 +45,17 @@ static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct | |||
45 | fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT; | 45 | fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT; |
46 | } | 46 | } |
47 | 47 | ||
48 | static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr) | ||
49 | { | ||
50 | if (((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) == 0) || | ||
51 | (((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) && | ||
52 | ((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0))) | ||
53 | return 0; | ||
54 | |||
55 | fattr->fileid = fattr->mounted_on_fileid; | ||
56 | return 1; | ||
57 | } | ||
58 | |||
48 | struct nfs_clone_mount { | 59 | struct nfs_clone_mount { |
49 | const struct super_block *sb; | 60 | const struct super_block *sb; |
50 | const struct dentry *dentry; | 61 | const struct dentry *dentry; |
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 426908809c97..0bafcc91c27f 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -30,6 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include <linux/nfs_fs.h> | 32 | #include <linux/nfs_fs.h> |
33 | #include <linux/nfs_page.h> | ||
33 | 34 | ||
34 | #include "internal.h" | 35 | #include "internal.h" |
35 | #include "nfs4filelayout.h" | 36 | #include "nfs4filelayout.h" |
@@ -552,13 +553,18 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
552 | __func__, nfl_util, fl->num_fh, fl->first_stripe_index, | 553 | __func__, nfl_util, fl->num_fh, fl->first_stripe_index, |
553 | fl->pattern_offset); | 554 | fl->pattern_offset); |
554 | 555 | ||
555 | if (!fl->num_fh) | 556 | /* Note that a zero value for num_fh is legal for STRIPE_SPARSE. |
557 | * Futher checking is done in filelayout_check_layout */ | ||
558 | if (fl->num_fh < 0 || fl->num_fh > | ||
559 | max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT)) | ||
556 | goto out_err; | 560 | goto out_err; |
557 | 561 | ||
558 | fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), | 562 | if (fl->num_fh > 0) { |
559 | gfp_flags); | 563 | fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), |
560 | if (!fl->fh_array) | 564 | gfp_flags); |
561 | goto out_err; | 565 | if (!fl->fh_array) |
566 | goto out_err; | ||
567 | } | ||
562 | 568 | ||
563 | for (i = 0; i < fl->num_fh; i++) { | 569 | for (i = 0; i < fl->num_fh; i++) { |
564 | /* Do we want to use a mempool here? */ | 570 | /* Do we want to use a mempool here? */ |
@@ -661,8 +667,9 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | |||
661 | u64 p_stripe, r_stripe; | 667 | u64 p_stripe, r_stripe; |
662 | u32 stripe_unit; | 668 | u32 stripe_unit; |
663 | 669 | ||
664 | if (!pnfs_generic_pg_test(pgio, prev, req)) | 670 | if (!pnfs_generic_pg_test(pgio, prev, req) || |
665 | return 0; | 671 | !nfs_generic_pg_test(pgio, prev, req)) |
672 | return false; | ||
666 | 673 | ||
667 | if (!pgio->pg_lseg) | 674 | if (!pgio->pg_lseg) |
668 | return 1; | 675 | return 1; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index d2c4b59c896d..5879b23e0c99 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2265,12 +2265,14 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | |||
2265 | return nfs4_map_errors(status); | 2265 | return nfs4_map_errors(status); |
2266 | } | 2266 | } |
2267 | 2267 | ||
2268 | static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); | ||
2268 | /* | 2269 | /* |
2269 | * Get locations and (maybe) other attributes of a referral. | 2270 | * Get locations and (maybe) other attributes of a referral. |
2270 | * Note that we'll actually follow the referral later when | 2271 | * Note that we'll actually follow the referral later when |
2271 | * we detect fsid mismatch in inode revalidation | 2272 | * we detect fsid mismatch in inode revalidation |
2272 | */ | 2273 | */ |
2273 | static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle) | 2274 | static int nfs4_get_referral(struct inode *dir, const struct qstr *name, |
2275 | struct nfs_fattr *fattr, struct nfs_fh *fhandle) | ||
2274 | { | 2276 | { |
2275 | int status = -ENOMEM; | 2277 | int status = -ENOMEM; |
2276 | struct page *page = NULL; | 2278 | struct page *page = NULL; |
@@ -2288,15 +2290,16 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct | |||
2288 | goto out; | 2290 | goto out; |
2289 | /* Make sure server returned a different fsid for the referral */ | 2291 | /* Make sure server returned a different fsid for the referral */ |
2290 | if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { | 2292 | if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { |
2291 | dprintk("%s: server did not return a different fsid for a referral at %s\n", __func__, name->name); | 2293 | dprintk("%s: server did not return a different fsid for" |
2294 | " a referral at %s\n", __func__, name->name); | ||
2292 | status = -EIO; | 2295 | status = -EIO; |
2293 | goto out; | 2296 | goto out; |
2294 | } | 2297 | } |
2298 | /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */ | ||
2299 | nfs_fixup_referral_attributes(&locations->fattr); | ||
2295 | 2300 | ||
2301 | /* replace the lookup nfs_fattr with the locations nfs_fattr */ | ||
2296 | memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr)); | 2302 | memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr)); |
2297 | fattr->valid |= NFS_ATTR_FATTR_V4_REFERRAL; | ||
2298 | if (!fattr->mode) | ||
2299 | fattr->mode = S_IFDIR; | ||
2300 | memset(fhandle, 0, sizeof(struct nfs_fh)); | 2303 | memset(fhandle, 0, sizeof(struct nfs_fh)); |
2301 | out: | 2304 | out: |
2302 | if (page) | 2305 | if (page) |
@@ -4667,11 +4670,15 @@ static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, | |||
4667 | return len; | 4670 | return len; |
4668 | } | 4671 | } |
4669 | 4672 | ||
4673 | /* | ||
4674 | * nfs_fhget will use either the mounted_on_fileid or the fileid | ||
4675 | */ | ||
4670 | static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) | 4676 | static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) |
4671 | { | 4677 | { |
4672 | if (!((fattr->valid & NFS_ATTR_FATTR_FILEID) && | 4678 | if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) || |
4673 | (fattr->valid & NFS_ATTR_FATTR_FSID) && | 4679 | (fattr->valid & NFS_ATTR_FATTR_FILEID)) && |
4674 | (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) | 4680 | (fattr->valid & NFS_ATTR_FATTR_FSID) && |
4681 | (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) | ||
4675 | return; | 4682 | return; |
4676 | 4683 | ||
4677 | fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | | 4684 | fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | |
@@ -4686,7 +4693,6 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | |||
4686 | struct nfs_server *server = NFS_SERVER(dir); | 4693 | struct nfs_server *server = NFS_SERVER(dir); |
4687 | u32 bitmask[2] = { | 4694 | u32 bitmask[2] = { |
4688 | [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, | 4695 | [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, |
4689 | [1] = FATTR4_WORD1_MOUNTED_ON_FILEID, | ||
4690 | }; | 4696 | }; |
4691 | struct nfs4_fs_locations_arg args = { | 4697 | struct nfs4_fs_locations_arg args = { |
4692 | .dir_fh = NFS_FH(dir), | 4698 | .dir_fh = NFS_FH(dir), |
@@ -4705,11 +4711,18 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, | |||
4705 | int status; | 4711 | int status; |
4706 | 4712 | ||
4707 | dprintk("%s: start\n", __func__); | 4713 | dprintk("%s: start\n", __func__); |
4714 | |||
4715 | /* Ask for the fileid of the absent filesystem if mounted_on_fileid | ||
4716 | * is not supported */ | ||
4717 | if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) | ||
4718 | bitmask[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; | ||
4719 | else | ||
4720 | bitmask[0] |= FATTR4_WORD0_FILEID; | ||
4721 | |||
4708 | nfs_fattr_init(&fs_locations->fattr); | 4722 | nfs_fattr_init(&fs_locations->fattr); |
4709 | fs_locations->server = server; | 4723 | fs_locations->server = server; |
4710 | fs_locations->nlocations = 0; | 4724 | fs_locations->nlocations = 0; |
4711 | status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); | 4725 | status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); |
4712 | nfs_fixup_referral_attributes(&fs_locations->fattr); | ||
4713 | dprintk("%s: returned status = %d\n", __func__, status); | 4726 | dprintk("%s: returned status = %d\n", __func__, status); |
4714 | return status; | 4727 | return status; |
4715 | } | 4728 | } |
@@ -5098,7 +5111,6 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) | |||
5098 | if (mxresp_sz == 0) | 5111 | if (mxresp_sz == 0) |
5099 | mxresp_sz = NFS_MAX_FILE_IO_SIZE; | 5112 | mxresp_sz = NFS_MAX_FILE_IO_SIZE; |
5100 | /* Fore channel attributes */ | 5113 | /* Fore channel attributes */ |
5101 | args->fc_attrs.headerpadsz = 0; | ||
5102 | args->fc_attrs.max_rqst_sz = mxrqst_sz; | 5114 | args->fc_attrs.max_rqst_sz = mxrqst_sz; |
5103 | args->fc_attrs.max_resp_sz = mxresp_sz; | 5115 | args->fc_attrs.max_resp_sz = mxresp_sz; |
5104 | args->fc_attrs.max_ops = NFS4_MAX_OPS; | 5116 | args->fc_attrs.max_ops = NFS4_MAX_OPS; |
@@ -5111,7 +5123,6 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) | |||
5111 | args->fc_attrs.max_ops, args->fc_attrs.max_reqs); | 5123 | args->fc_attrs.max_ops, args->fc_attrs.max_reqs); |
5112 | 5124 | ||
5113 | /* Back channel attributes */ | 5125 | /* Back channel attributes */ |
5114 | args->bc_attrs.headerpadsz = 0; | ||
5115 | args->bc_attrs.max_rqst_sz = PAGE_SIZE; | 5126 | args->bc_attrs.max_rqst_sz = PAGE_SIZE; |
5116 | args->bc_attrs.max_resp_sz = PAGE_SIZE; | 5127 | args->bc_attrs.max_resp_sz = PAGE_SIZE; |
5117 | args->bc_attrs.max_resp_sz_cached = 0; | 5128 | args->bc_attrs.max_resp_sz_cached = 0; |
@@ -5131,8 +5142,6 @@ static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args | |||
5131 | struct nfs4_channel_attrs *sent = &args->fc_attrs; | 5142 | struct nfs4_channel_attrs *sent = &args->fc_attrs; |
5132 | struct nfs4_channel_attrs *rcvd = &session->fc_attrs; | 5143 | struct nfs4_channel_attrs *rcvd = &session->fc_attrs; |
5133 | 5144 | ||
5134 | if (rcvd->headerpadsz > sent->headerpadsz) | ||
5135 | return -EINVAL; | ||
5136 | if (rcvd->max_resp_sz > sent->max_resp_sz) | 5145 | if (rcvd->max_resp_sz > sent->max_resp_sz) |
5137 | return -EINVAL; | 5146 | return -EINVAL; |
5138 | /* | 5147 | /* |
@@ -5697,6 +5706,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | |||
5697 | { | 5706 | { |
5698 | struct nfs4_layoutreturn *lrp = calldata; | 5707 | struct nfs4_layoutreturn *lrp = calldata; |
5699 | struct nfs_server *server; | 5708 | struct nfs_server *server; |
5709 | struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; | ||
5700 | 5710 | ||
5701 | dprintk("--> %s\n", __func__); | 5711 | dprintk("--> %s\n", __func__); |
5702 | 5712 | ||
@@ -5708,16 +5718,15 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | |||
5708 | nfs_restart_rpc(task, lrp->clp); | 5718 | nfs_restart_rpc(task, lrp->clp); |
5709 | return; | 5719 | return; |
5710 | } | 5720 | } |
5721 | spin_lock(&lo->plh_inode->i_lock); | ||
5711 | if (task->tk_status == 0) { | 5722 | if (task->tk_status == 0) { |
5712 | struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; | ||
5713 | |||
5714 | if (lrp->res.lrs_present) { | 5723 | if (lrp->res.lrs_present) { |
5715 | spin_lock(&lo->plh_inode->i_lock); | ||
5716 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | 5724 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); |
5717 | spin_unlock(&lo->plh_inode->i_lock); | ||
5718 | } else | 5725 | } else |
5719 | BUG_ON(!list_empty(&lo->plh_segs)); | 5726 | BUG_ON(!list_empty(&lo->plh_segs)); |
5720 | } | 5727 | } |
5728 | lo->plh_block_lgets--; | ||
5729 | spin_unlock(&lo->plh_inode->i_lock); | ||
5721 | dprintk("<-- %s\n", __func__); | 5730 | dprintk("<-- %s\n", __func__); |
5722 | } | 5731 | } |
5723 | 5732 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index d869a5e5464b..6870bc61ceec 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -255,7 +255,7 @@ static int nfs4_stat_to_errno(int); | |||
255 | #define decode_fs_locations_maxsz \ | 255 | #define decode_fs_locations_maxsz \ |
256 | (0) | 256 | (0) |
257 | #define encode_secinfo_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz) | 257 | #define encode_secinfo_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz) |
258 | #define decode_secinfo_maxsz (op_decode_hdr_maxsz + 4 + (NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN))) | 258 | #define decode_secinfo_maxsz (op_decode_hdr_maxsz + 1 + ((NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)) / 4)) |
259 | 259 | ||
260 | #if defined(CONFIG_NFS_V4_1) | 260 | #if defined(CONFIG_NFS_V4_1) |
261 | #define NFS4_MAX_MACHINE_NAME_LEN (64) | 261 | #define NFS4_MAX_MACHINE_NAME_LEN (64) |
@@ -1725,7 +1725,7 @@ static void encode_create_session(struct xdr_stream *xdr, | |||
1725 | *p++ = cpu_to_be32(args->flags); /*flags */ | 1725 | *p++ = cpu_to_be32(args->flags); /*flags */ |
1726 | 1726 | ||
1727 | /* Fore Channel */ | 1727 | /* Fore Channel */ |
1728 | *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */ | 1728 | *p++ = cpu_to_be32(0); /* header padding size */ |
1729 | *p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */ | 1729 | *p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */ |
1730 | *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */ | 1730 | *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */ |
1731 | *p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */ | 1731 | *p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */ |
@@ -1734,7 +1734,7 @@ static void encode_create_session(struct xdr_stream *xdr, | |||
1734 | *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ | 1734 | *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ |
1735 | 1735 | ||
1736 | /* Back Channel */ | 1736 | /* Back Channel */ |
1737 | *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */ | 1737 | *p++ = cpu_to_be32(0); /* header padding size */ |
1738 | *p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz); /* max req size */ | 1738 | *p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz); /* max req size */ |
1739 | *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz); /* max resp size */ | 1739 | *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz); /* max resp size */ |
1740 | *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */ | 1740 | *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */ |
@@ -3098,7 +3098,7 @@ out_overflow: | |||
3098 | return -EIO; | 3098 | return -EIO; |
3099 | } | 3099 | } |
3100 | 3100 | ||
3101 | static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap) | 3101 | static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res) |
3102 | { | 3102 | { |
3103 | __be32 *p; | 3103 | __be32 *p; |
3104 | 3104 | ||
@@ -3109,7 +3109,7 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap) | |||
3109 | if (unlikely(!p)) | 3109 | if (unlikely(!p)) |
3110 | goto out_overflow; | 3110 | goto out_overflow; |
3111 | bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; | 3111 | bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; |
3112 | return -be32_to_cpup(p); | 3112 | *res = -be32_to_cpup(p); |
3113 | } | 3113 | } |
3114 | return 0; | 3114 | return 0; |
3115 | out_overflow: | 3115 | out_overflow: |
@@ -4070,6 +4070,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4070 | int status; | 4070 | int status; |
4071 | umode_t fmode = 0; | 4071 | umode_t fmode = 0; |
4072 | uint32_t type; | 4072 | uint32_t type; |
4073 | int32_t err; | ||
4073 | 4074 | ||
4074 | status = decode_attr_type(xdr, bitmap, &type); | 4075 | status = decode_attr_type(xdr, bitmap, &type); |
4075 | if (status < 0) | 4076 | if (status < 0) |
@@ -4095,13 +4096,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4095 | goto xdr_error; | 4096 | goto xdr_error; |
4096 | fattr->valid |= status; | 4097 | fattr->valid |= status; |
4097 | 4098 | ||
4098 | status = decode_attr_error(xdr, bitmap); | 4099 | err = 0; |
4099 | if (status == -NFS4ERR_WRONGSEC) { | 4100 | status = decode_attr_error(xdr, bitmap, &err); |
4100 | nfs_fixup_secinfo_attributes(fattr, fh); | ||
4101 | status = 0; | ||
4102 | } | ||
4103 | if (status < 0) | 4101 | if (status < 0) |
4104 | goto xdr_error; | 4102 | goto xdr_error; |
4103 | if (err == -NFS4ERR_WRONGSEC) | ||
4104 | nfs_fixup_secinfo_attributes(fattr, fh); | ||
4105 | 4105 | ||
4106 | status = decode_attr_filehandle(xdr, bitmap, fh); | 4106 | status = decode_attr_filehandle(xdr, bitmap, fh); |
4107 | if (status < 0) | 4107 | if (status < 0) |
@@ -4997,12 +4997,14 @@ static int decode_chan_attrs(struct xdr_stream *xdr, | |||
4997 | struct nfs4_channel_attrs *attrs) | 4997 | struct nfs4_channel_attrs *attrs) |
4998 | { | 4998 | { |
4999 | __be32 *p; | 4999 | __be32 *p; |
5000 | u32 nr_attrs; | 5000 | u32 nr_attrs, val; |
5001 | 5001 | ||
5002 | p = xdr_inline_decode(xdr, 28); | 5002 | p = xdr_inline_decode(xdr, 28); |
5003 | if (unlikely(!p)) | 5003 | if (unlikely(!p)) |
5004 | goto out_overflow; | 5004 | goto out_overflow; |
5005 | attrs->headerpadsz = be32_to_cpup(p++); | 5005 | val = be32_to_cpup(p++); /* headerpadsz */ |
5006 | if (val) | ||
5007 | return -EINVAL; /* no support for header padding yet */ | ||
5006 | attrs->max_rqst_sz = be32_to_cpup(p++); | 5008 | attrs->max_rqst_sz = be32_to_cpup(p++); |
5007 | attrs->max_resp_sz = be32_to_cpup(p++); | 5009 | attrs->max_resp_sz = be32_to_cpup(p++); |
5008 | attrs->max_resp_sz_cached = be32_to_cpup(p++); | 5010 | attrs->max_resp_sz_cached = be32_to_cpup(p++); |
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index 9cf208df1f25..8ff2ea3f10ef 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -108,7 +108,6 @@ _dev_list_add(const struct nfs_server *nfss, | |||
108 | de = n; | 108 | de = n; |
109 | } | 109 | } |
110 | 110 | ||
111 | atomic_inc(&de->id_node.ref); | ||
112 | return de; | 111 | return de; |
113 | } | 112 | } |
114 | 113 | ||
@@ -1001,6 +1000,9 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, | |||
1001 | if (!pnfs_generic_pg_test(pgio, prev, req)) | 1000 | if (!pnfs_generic_pg_test(pgio, prev, req)) |
1002 | return false; | 1001 | return false; |
1003 | 1002 | ||
1003 | if (pgio->pg_lseg == NULL) | ||
1004 | return true; | ||
1005 | |||
1004 | return pgio->pg_count + req->wb_bytes <= | 1006 | return pgio->pg_count + req->wb_bytes <= |
1005 | OBJIO_LSEG(pgio->pg_lseg)->max_io_size; | 1007 | OBJIO_LSEG(pgio->pg_lseg)->max_io_size; |
1006 | } | 1008 | } |
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c index dc3956c0de80..1d06f8e2adea 100644 --- a/fs/nfs/objlayout/objlayout.c +++ b/fs/nfs/objlayout/objlayout.c | |||
@@ -291,7 +291,7 @@ objlayout_read_done(struct objlayout_io_state *state, ssize_t status, bool sync) | |||
291 | struct nfs_read_data *rdata; | 291 | struct nfs_read_data *rdata; |
292 | 292 | ||
293 | state->status = status; | 293 | state->status = status; |
294 | dprintk("%s: Begin status=%ld eof=%d\n", __func__, status, eof); | 294 | dprintk("%s: Begin status=%zd eof=%d\n", __func__, status, eof); |
295 | rdata = state->rpcdata; | 295 | rdata = state->rpcdata; |
296 | rdata->task.tk_status = status; | 296 | rdata->task.tk_status = status; |
297 | if (status >= 0) { | 297 | if (status >= 0) { |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 7913961aff22..009855716286 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -204,7 +204,7 @@ nfs_wait_on_request(struct nfs_page *req) | |||
204 | TASK_UNINTERRUPTIBLE); | 204 | TASK_UNINTERRUPTIBLE); |
205 | } | 205 | } |
206 | 206 | ||
207 | static bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req) | 207 | bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req) |
208 | { | 208 | { |
209 | /* | 209 | /* |
210 | * FIXME: ideally we should be able to coalesce all requests | 210 | * FIXME: ideally we should be able to coalesce all requests |
@@ -218,6 +218,7 @@ static bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_p | |||
218 | 218 | ||
219 | return desc->pg_count + req->wb_bytes <= desc->pg_bsize; | 219 | return desc->pg_count + req->wb_bytes <= desc->pg_bsize; |
220 | } | 220 | } |
221 | EXPORT_SYMBOL_GPL(nfs_generic_pg_test); | ||
221 | 222 | ||
222 | /** | 223 | /** |
223 | * nfs_pageio_init - initialise a page io descriptor | 224 | * nfs_pageio_init - initialise a page io descriptor |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 8c1309d852a6..29c0ca7fc347 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -634,14 +634,16 @@ _pnfs_return_layout(struct inode *ino) | |||
634 | 634 | ||
635 | spin_lock(&ino->i_lock); | 635 | spin_lock(&ino->i_lock); |
636 | lo = nfsi->layout; | 636 | lo = nfsi->layout; |
637 | if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) { | 637 | if (!lo) { |
638 | spin_unlock(&ino->i_lock); | 638 | spin_unlock(&ino->i_lock); |
639 | dprintk("%s: no layout segments to return\n", __func__); | 639 | dprintk("%s: no layout to return\n", __func__); |
640 | goto out; | 640 | return status; |
641 | } | 641 | } |
642 | stateid = nfsi->layout->plh_stateid; | 642 | stateid = nfsi->layout->plh_stateid; |
643 | /* Reference matched in nfs4_layoutreturn_release */ | 643 | /* Reference matched in nfs4_layoutreturn_release */ |
644 | get_layout_hdr(lo); | 644 | get_layout_hdr(lo); |
645 | mark_matching_lsegs_invalid(lo, &tmp_list, NULL); | ||
646 | lo->plh_block_lgets++; | ||
645 | spin_unlock(&ino->i_lock); | 647 | spin_unlock(&ino->i_lock); |
646 | pnfs_free_lseg_list(&tmp_list); | 648 | pnfs_free_lseg_list(&tmp_list); |
647 | 649 | ||
@@ -650,6 +652,9 @@ _pnfs_return_layout(struct inode *ino) | |||
650 | lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); | 652 | lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); |
651 | if (unlikely(lrp == NULL)) { | 653 | if (unlikely(lrp == NULL)) { |
652 | status = -ENOMEM; | 654 | status = -ENOMEM; |
655 | set_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags); | ||
656 | set_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags); | ||
657 | put_layout_hdr(lo); | ||
653 | goto out; | 658 | goto out; |
654 | } | 659 | } |
655 | 660 | ||
@@ -887,7 +892,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, | |||
887 | ret = get_lseg(lseg); | 892 | ret = get_lseg(lseg); |
888 | break; | 893 | break; |
889 | } | 894 | } |
890 | if (cmp_layout(range, &lseg->pls_range) > 0) | 895 | if (lseg->pls_range.offset > range->offset) |
891 | break; | 896 | break; |
892 | } | 897 | } |
893 | 898 | ||
@@ -1059,23 +1064,36 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | |||
1059 | gfp_flags = GFP_NOFS; | 1064 | gfp_flags = GFP_NOFS; |
1060 | } | 1065 | } |
1061 | 1066 | ||
1062 | if (pgio->pg_count == prev->wb_bytes) { | 1067 | if (pgio->pg_lseg == NULL) { |
1068 | if (pgio->pg_count != prev->wb_bytes) | ||
1069 | return true; | ||
1063 | /* This is first coelesce call for a series of nfs_pages */ | 1070 | /* This is first coelesce call for a series of nfs_pages */ |
1064 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | 1071 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, |
1065 | prev->wb_context, | 1072 | prev->wb_context, |
1066 | req_offset(req), | 1073 | req_offset(prev), |
1067 | pgio->pg_count, | 1074 | pgio->pg_count, |
1068 | access_type, | 1075 | access_type, |
1069 | gfp_flags); | 1076 | gfp_flags); |
1070 | return true; | 1077 | if (pgio->pg_lseg == NULL) |
1078 | return true; | ||
1071 | } | 1079 | } |
1072 | 1080 | ||
1073 | if (pgio->pg_lseg && | 1081 | /* |
1074 | req_offset(req) > end_offset(pgio->pg_lseg->pls_range.offset, | 1082 | * Test if a nfs_page is fully contained in the pnfs_layout_range. |
1075 | pgio->pg_lseg->pls_range.length)) | 1083 | * Note that this test makes several assumptions: |
1076 | return false; | 1084 | * - that the previous nfs_page in the struct nfs_pageio_descriptor |
1077 | 1085 | * is known to lie within the range. | |
1078 | return true; | 1086 | * - that the nfs_page being tested is known to be contiguous with the |
1087 | * previous nfs_page. | ||
1088 | * - Layout ranges are page aligned, so we only have to test the | ||
1089 | * start offset of the request. | ||
1090 | * | ||
1091 | * Please also note that 'end_offset' is actually the offset of the | ||
1092 | * first byte that lies outside the pnfs_layout_range. FIXME? | ||
1093 | * | ||
1094 | */ | ||
1095 | return req_offset(req) < end_offset(pgio->pg_lseg->pls_range.offset, | ||
1096 | pgio->pg_lseg->pls_range.length); | ||
1079 | } | 1097 | } |
1080 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); | 1098 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); |
1081 | 1099 | ||
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 48d0a8e4d062..96bf4e6f45be 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -186,6 +186,7 @@ int pnfs_ld_read_done(struct nfs_read_data *); | |||
186 | /* pnfs_dev.c */ | 186 | /* pnfs_dev.c */ |
187 | struct nfs4_deviceid_node { | 187 | struct nfs4_deviceid_node { |
188 | struct hlist_node node; | 188 | struct hlist_node node; |
189 | struct hlist_node tmpnode; | ||
189 | const struct pnfs_layoutdriver_type *ld; | 190 | const struct pnfs_layoutdriver_type *ld; |
190 | const struct nfs_client *nfs_client; | 191 | const struct nfs_client *nfs_client; |
191 | struct nfs4_deviceid deviceid; | 192 | struct nfs4_deviceid deviceid; |
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c index c65e133ce9c0..f0f8e1e22f6c 100644 --- a/fs/nfs/pnfs_dev.c +++ b/fs/nfs/pnfs_dev.c | |||
@@ -174,6 +174,7 @@ nfs4_init_deviceid_node(struct nfs4_deviceid_node *d, | |||
174 | const struct nfs4_deviceid *id) | 174 | const struct nfs4_deviceid *id) |
175 | { | 175 | { |
176 | INIT_HLIST_NODE(&d->node); | 176 | INIT_HLIST_NODE(&d->node); |
177 | INIT_HLIST_NODE(&d->tmpnode); | ||
177 | d->ld = ld; | 178 | d->ld = ld; |
178 | d->nfs_client = nfs_client; | 179 | d->nfs_client = nfs_client; |
179 | d->deviceid = *id; | 180 | d->deviceid = *id; |
@@ -208,6 +209,7 @@ nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new) | |||
208 | 209 | ||
209 | hlist_add_head_rcu(&new->node, &nfs4_deviceid_cache[hash]); | 210 | hlist_add_head_rcu(&new->node, &nfs4_deviceid_cache[hash]); |
210 | spin_unlock(&nfs4_deviceid_lock); | 211 | spin_unlock(&nfs4_deviceid_lock); |
212 | atomic_inc(&new->ref); | ||
211 | 213 | ||
212 | return new; | 214 | return new; |
213 | } | 215 | } |
@@ -238,24 +240,29 @@ static void | |||
238 | _deviceid_purge_client(const struct nfs_client *clp, long hash) | 240 | _deviceid_purge_client(const struct nfs_client *clp, long hash) |
239 | { | 241 | { |
240 | struct nfs4_deviceid_node *d; | 242 | struct nfs4_deviceid_node *d; |
241 | struct hlist_node *n, *next; | 243 | struct hlist_node *n; |
242 | HLIST_HEAD(tmp); | 244 | HLIST_HEAD(tmp); |
243 | 245 | ||
246 | spin_lock(&nfs4_deviceid_lock); | ||
244 | rcu_read_lock(); | 247 | rcu_read_lock(); |
245 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) | 248 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) |
246 | if (d->nfs_client == clp && atomic_read(&d->ref)) { | 249 | if (d->nfs_client == clp && atomic_read(&d->ref)) { |
247 | hlist_del_init_rcu(&d->node); | 250 | hlist_del_init_rcu(&d->node); |
248 | hlist_add_head(&d->node, &tmp); | 251 | hlist_add_head(&d->tmpnode, &tmp); |
249 | } | 252 | } |
250 | rcu_read_unlock(); | 253 | rcu_read_unlock(); |
254 | spin_unlock(&nfs4_deviceid_lock); | ||
251 | 255 | ||
252 | if (hlist_empty(&tmp)) | 256 | if (hlist_empty(&tmp)) |
253 | return; | 257 | return; |
254 | 258 | ||
255 | synchronize_rcu(); | 259 | synchronize_rcu(); |
256 | hlist_for_each_entry_safe(d, n, next, &tmp, node) | 260 | while (!hlist_empty(&tmp)) { |
261 | d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode); | ||
262 | hlist_del(&d->tmpnode); | ||
257 | if (atomic_dec_and_test(&d->ref)) | 263 | if (atomic_dec_and_test(&d->ref)) |
258 | d->ld->free_deviceid_node(d); | 264 | d->ld->free_deviceid_node(d); |
265 | } | ||
259 | } | 266 | } |
260 | 267 | ||
261 | void | 268 | void |
@@ -263,8 +270,8 @@ nfs4_deviceid_purge_client(const struct nfs_client *clp) | |||
263 | { | 270 | { |
264 | long h; | 271 | long h; |
265 | 272 | ||
266 | spin_lock(&nfs4_deviceid_lock); | 273 | if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_MDS)) |
274 | return; | ||
267 | for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) | 275 | for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) |
268 | _deviceid_purge_client(clp, h); | 276 | _deviceid_purge_client(clp, h); |
269 | spin_unlock(&nfs4_deviceid_lock); | ||
270 | } | 277 | } |
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index 18b3e8975fe0..fbb2a5ef5817 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig | |||
@@ -82,6 +82,7 @@ config NFSD_V4 | |||
82 | select NFSD_V3 | 82 | select NFSD_V3 |
83 | select FS_POSIX_ACL | 83 | select FS_POSIX_ACL |
84 | select SUNRPC_GSS | 84 | select SUNRPC_GSS |
85 | select CRYPTO | ||
85 | help | 86 | help |
86 | This option enables support in your system's NFS server for | 87 | This option enables support in your system's NFS server for |
87 | version 4 of the NFS protocol (RFC 3530). | 88 | version 4 of the NFS protocol (RFC 3530). |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 1f5eae40f34e..2b1449dd2f49 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/lockd/lockd.h> | 13 | #include <linux/lockd/lockd.h> |
14 | #include <linux/sunrpc/clnt.h> | 14 | #include <linux/sunrpc/clnt.h> |
15 | #include <linux/sunrpc/gss_api.h> | 15 | #include <linux/sunrpc/gss_api.h> |
16 | #include <linux/sunrpc/gss_krb5_enctypes.h> | ||
16 | 17 | ||
17 | #include "idmap.h" | 18 | #include "idmap.h" |
18 | #include "nfsd.h" | 19 | #include "nfsd.h" |
@@ -189,18 +190,10 @@ static struct file_operations export_features_operations = { | |||
189 | .release = single_release, | 190 | .release = single_release, |
190 | }; | 191 | }; |
191 | 192 | ||
192 | #ifdef CONFIG_SUNRPC_GSS | 193 | #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) |
193 | static int supported_enctypes_show(struct seq_file *m, void *v) | 194 | static int supported_enctypes_show(struct seq_file *m, void *v) |
194 | { | 195 | { |
195 | struct gss_api_mech *k5mech; | 196 | seq_printf(m, KRB5_SUPPORTED_ENCTYPES); |
196 | |||
197 | k5mech = gss_mech_get_by_name("krb5"); | ||
198 | if (k5mech == NULL) | ||
199 | goto out; | ||
200 | if (k5mech->gm_upcall_enctypes != NULL) | ||
201 | seq_printf(m, k5mech->gm_upcall_enctypes); | ||
202 | gss_mech_put(k5mech); | ||
203 | out: | ||
204 | return 0; | 197 | return 0; |
205 | } | 198 | } |
206 | 199 | ||
@@ -215,7 +208,7 @@ static struct file_operations supported_enctypes_ops = { | |||
215 | .llseek = seq_lseek, | 208 | .llseek = seq_lseek, |
216 | .release = single_release, | 209 | .release = single_release, |
217 | }; | 210 | }; |
218 | #endif /* CONFIG_SUNRPC_GSS */ | 211 | #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ |
219 | 212 | ||
220 | extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); | 213 | extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); |
221 | extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); | 214 | extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); |
@@ -1427,9 +1420,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
1427 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, | 1420 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, |
1428 | [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, | 1421 | [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, |
1429 | [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, | 1422 | [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, |
1430 | #ifdef CONFIG_SUNRPC_GSS | 1423 | #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) |
1431 | [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO}, | 1424 | [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO}, |
1432 | #endif /* CONFIG_SUNRPC_GSS */ | 1425 | #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ |
1433 | #ifdef CONFIG_NFSD_V4 | 1426 | #ifdef CONFIG_NFSD_V4 |
1434 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, | 1427 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
1435 | [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, | 1428 | [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index d5718273bb32..fd0acca5370a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -696,7 +696,15 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor | |||
696 | } | 696 | } |
697 | #endif /* CONFIG_NFSD_V3 */ | 697 | #endif /* CONFIG_NFSD_V3 */ |
698 | 698 | ||
699 | static int nfsd_open_break_lease(struct inode *inode, int access) | ||
700 | { | ||
701 | unsigned int mode; | ||
699 | 702 | ||
703 | if (access & NFSD_MAY_NOT_BREAK_LEASE) | ||
704 | return 0; | ||
705 | mode = (access & NFSD_MAY_WRITE) ? O_WRONLY : O_RDONLY; | ||
706 | return break_lease(inode, mode | O_NONBLOCK); | ||
707 | } | ||
700 | 708 | ||
701 | /* | 709 | /* |
702 | * Open an existing file or directory. | 710 | * Open an existing file or directory. |
@@ -744,12 +752,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
744 | if (!inode->i_fop) | 752 | if (!inode->i_fop) |
745 | goto out; | 753 | goto out; |
746 | 754 | ||
747 | /* | 755 | host_err = nfsd_open_break_lease(inode, access); |
748 | * Check to see if there are any leases on this file. | ||
749 | * This may block while leases are broken. | ||
750 | */ | ||
751 | if (!(access & NFSD_MAY_NOT_BREAK_LEASE)) | ||
752 | host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0)); | ||
753 | if (host_err) /* NOMEM or WOULDBLOCK */ | 756 | if (host_err) /* NOMEM or WOULDBLOCK */ |
754 | goto out_nfserr; | 757 | goto out_nfserr; |
755 | 758 | ||
@@ -1660,8 +1663,10 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1660 | if (!dold->d_inode) | 1663 | if (!dold->d_inode) |
1661 | goto out_drop_write; | 1664 | goto out_drop_write; |
1662 | host_err = nfsd_break_lease(dold->d_inode); | 1665 | host_err = nfsd_break_lease(dold->d_inode); |
1663 | if (host_err) | 1666 | if (host_err) { |
1667 | err = nfserrno(host_err); | ||
1664 | goto out_drop_write; | 1668 | goto out_drop_write; |
1669 | } | ||
1665 | host_err = vfs_link(dold, dirp, dnew); | 1670 | host_err = vfs_link(dold, dirp, dnew); |
1666 | if (!host_err) { | 1671 | if (!host_err) { |
1667 | err = nfserrno(commit_metadata(ffhp)); | 1672 | err = nfserrno(commit_metadata(ffhp)); |
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index 7eafe468a29c..b2e3ff347620 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
@@ -1346,6 +1346,11 @@ static void nilfs_btree_shrink(struct nilfs_bmap *btree, | |||
1346 | path[level].bp_bh = NULL; | 1346 | path[level].bp_bh = NULL; |
1347 | } | 1347 | } |
1348 | 1348 | ||
1349 | static void nilfs_btree_nop(struct nilfs_bmap *btree, | ||
1350 | struct nilfs_btree_path *path, | ||
1351 | int level, __u64 *keyp, __u64 *ptrp) | ||
1352 | { | ||
1353 | } | ||
1349 | 1354 | ||
1350 | static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, | 1355 | static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, |
1351 | struct nilfs_btree_path *path, | 1356 | struct nilfs_btree_path *path, |
@@ -1356,20 +1361,19 @@ static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, | |||
1356 | struct buffer_head *bh; | 1361 | struct buffer_head *bh; |
1357 | struct nilfs_btree_node *node, *parent, *sib; | 1362 | struct nilfs_btree_node *node, *parent, *sib; |
1358 | __u64 sibptr; | 1363 | __u64 sibptr; |
1359 | int pindex, level, ncmin, ncmax, ncblk, ret; | 1364 | int pindex, dindex, level, ncmin, ncmax, ncblk, ret; |
1360 | 1365 | ||
1361 | ret = 0; | 1366 | ret = 0; |
1362 | stats->bs_nblocks = 0; | 1367 | stats->bs_nblocks = 0; |
1363 | ncmin = NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree)); | 1368 | ncmin = NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree)); |
1364 | ncblk = nilfs_btree_nchildren_per_block(btree); | 1369 | ncblk = nilfs_btree_nchildren_per_block(btree); |
1365 | 1370 | ||
1366 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; | 1371 | for (level = NILFS_BTREE_LEVEL_NODE_MIN, dindex = path[level].bp_index; |
1367 | level < nilfs_btree_height(btree) - 1; | 1372 | level < nilfs_btree_height(btree) - 1; |
1368 | level++) { | 1373 | level++) { |
1369 | node = nilfs_btree_get_nonroot_node(path, level); | 1374 | node = nilfs_btree_get_nonroot_node(path, level); |
1370 | path[level].bp_oldreq.bpr_ptr = | 1375 | path[level].bp_oldreq.bpr_ptr = |
1371 | nilfs_btree_node_get_ptr(node, path[level].bp_index, | 1376 | nilfs_btree_node_get_ptr(node, dindex, ncblk); |
1372 | ncblk); | ||
1373 | ret = nilfs_bmap_prepare_end_ptr(btree, | 1377 | ret = nilfs_bmap_prepare_end_ptr(btree, |
1374 | &path[level].bp_oldreq, dat); | 1378 | &path[level].bp_oldreq, dat); |
1375 | if (ret < 0) | 1379 | if (ret < 0) |
@@ -1383,6 +1387,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, | |||
1383 | 1387 | ||
1384 | parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax); | 1388 | parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax); |
1385 | pindex = path[level + 1].bp_index; | 1389 | pindex = path[level + 1].bp_index; |
1390 | dindex = pindex; | ||
1386 | 1391 | ||
1387 | if (pindex > 0) { | 1392 | if (pindex > 0) { |
1388 | /* left sibling */ | 1393 | /* left sibling */ |
@@ -1421,6 +1426,14 @@ static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, | |||
1421 | path[level].bp_sib_bh = bh; | 1426 | path[level].bp_sib_bh = bh; |
1422 | path[level].bp_op = nilfs_btree_concat_right; | 1427 | path[level].bp_op = nilfs_btree_concat_right; |
1423 | stats->bs_nblocks++; | 1428 | stats->bs_nblocks++; |
1429 | /* | ||
1430 | * When merging right sibling node | ||
1431 | * into the current node, pointer to | ||
1432 | * the right sibling node must be | ||
1433 | * terminated instead. The adjustment | ||
1434 | * below is required for that. | ||
1435 | */ | ||
1436 | dindex = pindex + 1; | ||
1424 | /* continue; */ | 1437 | /* continue; */ |
1425 | } | 1438 | } |
1426 | } else { | 1439 | } else { |
@@ -1431,29 +1444,31 @@ static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, | |||
1431 | NILFS_BTREE_ROOT_NCHILDREN_MAX) { | 1444 | NILFS_BTREE_ROOT_NCHILDREN_MAX) { |
1432 | path[level].bp_op = nilfs_btree_shrink; | 1445 | path[level].bp_op = nilfs_btree_shrink; |
1433 | stats->bs_nblocks += 2; | 1446 | stats->bs_nblocks += 2; |
1447 | level++; | ||
1448 | path[level].bp_op = nilfs_btree_nop; | ||
1449 | goto shrink_root_child; | ||
1434 | } else { | 1450 | } else { |
1435 | path[level].bp_op = nilfs_btree_do_delete; | 1451 | path[level].bp_op = nilfs_btree_do_delete; |
1436 | stats->bs_nblocks++; | 1452 | stats->bs_nblocks++; |
1453 | goto out; | ||
1437 | } | 1454 | } |
1438 | |||
1439 | goto out; | ||
1440 | |||
1441 | } | 1455 | } |
1442 | } | 1456 | } |
1443 | 1457 | ||
1458 | /* child of the root node is deleted */ | ||
1459 | path[level].bp_op = nilfs_btree_do_delete; | ||
1460 | stats->bs_nblocks++; | ||
1461 | |||
1462 | shrink_root_child: | ||
1444 | node = nilfs_btree_get_root(btree); | 1463 | node = nilfs_btree_get_root(btree); |
1445 | path[level].bp_oldreq.bpr_ptr = | 1464 | path[level].bp_oldreq.bpr_ptr = |
1446 | nilfs_btree_node_get_ptr(node, path[level].bp_index, | 1465 | nilfs_btree_node_get_ptr(node, dindex, |
1447 | NILFS_BTREE_ROOT_NCHILDREN_MAX); | 1466 | NILFS_BTREE_ROOT_NCHILDREN_MAX); |
1448 | 1467 | ||
1449 | ret = nilfs_bmap_prepare_end_ptr(btree, &path[level].bp_oldreq, dat); | 1468 | ret = nilfs_bmap_prepare_end_ptr(btree, &path[level].bp_oldreq, dat); |
1450 | if (ret < 0) | 1469 | if (ret < 0) |
1451 | goto err_out_child_node; | 1470 | goto err_out_child_node; |
1452 | 1471 | ||
1453 | /* child of the root node is deleted */ | ||
1454 | path[level].bp_op = nilfs_btree_do_delete; | ||
1455 | stats->bs_nblocks++; | ||
1456 | |||
1457 | /* success */ | 1472 | /* success */ |
1458 | out: | 1473 | out: |
1459 | *levelp = level; | 1474 | *levelp = level; |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index b954878ad6ce..b9b45fc2903e 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -801,12 +801,7 @@ out_err: | |||
801 | 801 | ||
802 | int nilfs_permission(struct inode *inode, int mask, unsigned int flags) | 802 | int nilfs_permission(struct inode *inode, int mask, unsigned int flags) |
803 | { | 803 | { |
804 | struct nilfs_root *root; | 804 | struct nilfs_root *root = NILFS_I(inode)->i_root; |
805 | |||
806 | if (flags & IPERM_FLAG_RCU) | ||
807 | return -ECHILD; | ||
808 | |||
809 | root = NILFS_I(inode)->i_root; | ||
810 | if ((mask & MAY_WRITE) && root && | 805 | if ((mask & MAY_WRITE) && root && |
811 | root->cno != NILFS_CPTREE_CURRENT_CNO) | 806 | root->cno != NILFS_CPTREE_CURRENT_CNO) |
812 | return -EROFS; /* snapshot is not writable */ | 807 | return -EROFS; /* snapshot is not writable */ |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 141646e88fb5..bb24ab6c282f 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -2573,7 +2573,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb, | |||
2573 | sci->sc_watermark = NILFS_SC_DEFAULT_WATERMARK; | 2573 | sci->sc_watermark = NILFS_SC_DEFAULT_WATERMARK; |
2574 | 2574 | ||
2575 | if (nilfs->ns_interval) | 2575 | if (nilfs->ns_interval) |
2576 | sci->sc_interval = nilfs->ns_interval; | 2576 | sci->sc_interval = HZ * nilfs->ns_interval; |
2577 | if (nilfs->ns_watermark) | 2577 | if (nilfs->ns_watermark) |
2578 | sci->sc_watermark = nilfs->ns_watermark; | 2578 | sci->sc_watermark = nilfs->ns_watermark; |
2579 | return sci; | 2579 | return sci; |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index cdbaf5e97308..56f61027236b 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -1072,7 +1072,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
1072 | 1072 | ||
1073 | sb->s_magic = OCFS2_SUPER_MAGIC; | 1073 | sb->s_magic = OCFS2_SUPER_MAGIC; |
1074 | 1074 | ||
1075 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 1075 | sb->s_flags = (sb->s_flags & ~(MS_POSIXACL | MS_NOSEC)) | |
1076 | ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 1076 | ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); |
1077 | 1077 | ||
1078 | /* Hard readonly mode only if: bdev_read_only, MS_RDONLY, | 1078 | /* Hard readonly mode only if: bdev_read_only, MS_RDONLY, |
diff --git a/fs/omfs/file.c b/fs/omfs/file.c index d738a7e493dd..2c6d95257a4d 100644 --- a/fs/omfs/file.c +++ b/fs/omfs/file.c | |||
@@ -4,7 +4,6 @@ | |||
4 | * Released under GPL v2. | 4 | * Released under GPL v2. |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/version.h> | ||
8 | #include <linux/module.h> | 7 | #include <linux/module.h> |
9 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
10 | #include <linux/buffer_head.h> | 9 | #include <linux/buffer_head.h> |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 14def991d9dd..fc5bc2767692 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2169,11 +2169,7 @@ static const struct file_operations proc_fd_operations = { | |||
2169 | */ | 2169 | */ |
2170 | static int proc_fd_permission(struct inode *inode, int mask, unsigned int flags) | 2170 | static int proc_fd_permission(struct inode *inode, int mask, unsigned int flags) |
2171 | { | 2171 | { |
2172 | int rv; | 2172 | int rv = generic_permission(inode, mask, flags, NULL); |
2173 | |||
2174 | if (flags & IPERM_FLAG_RCU) | ||
2175 | return -ECHILD; | ||
2176 | rv = generic_permission(inode, mask, flags, NULL); | ||
2177 | if (rv == 0) | 2173 | if (rv == 0) |
2178 | return 0; | 2174 | return 0; |
2179 | if (task_pid(current) == proc_pid(inode)) | 2175 | if (task_pid(current) == proc_pid(inode)) |
@@ -2712,6 +2708,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | |||
2712 | struct task_io_accounting acct = task->ioac; | 2708 | struct task_io_accounting acct = task->ioac; |
2713 | unsigned long flags; | 2709 | unsigned long flags; |
2714 | 2710 | ||
2711 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) | ||
2712 | return -EACCES; | ||
2713 | |||
2715 | if (whole && lock_task_sighand(task, &flags)) { | 2714 | if (whole && lock_task_sighand(task, &flags)) { |
2716 | struct task_struct *t = task; | 2715 | struct task_struct *t = task; |
2717 | 2716 | ||
@@ -2843,7 +2842,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2843 | REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), | 2842 | REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), |
2844 | #endif | 2843 | #endif |
2845 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2844 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2846 | INF("io", S_IRUGO, proc_tgid_io_accounting), | 2845 | INF("io", S_IRUSR, proc_tgid_io_accounting), |
2847 | #endif | 2846 | #endif |
2848 | #ifdef CONFIG_HARDWALL | 2847 | #ifdef CONFIG_HARDWALL |
2849 | INF("hardwall", S_IRUGO, proc_pid_hardwall), | 2848 | INF("hardwall", S_IRUGO, proc_pid_hardwall), |
@@ -3185,7 +3184,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3185 | REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), | 3184 | REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), |
3186 | #endif | 3185 | #endif |
3187 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 3186 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
3188 | INF("io", S_IRUGO, proc_tid_io_accounting), | 3187 | INF("io", S_IRUSR, proc_tid_io_accounting), |
3189 | #endif | 3188 | #endif |
3190 | #ifdef CONFIG_HARDWALL | 3189 | #ifdef CONFIG_HARDWALL |
3191 | INF("hardwall", S_IRUGO, proc_pid_hardwall), | 3190 | INF("hardwall", S_IRUGO, proc_pid_hardwall), |
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 781dec5bd682..be177f702acb 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c | |||
@@ -38,18 +38,21 @@ static struct dentry *proc_ns_instantiate(struct inode *dir, | |||
38 | struct inode *inode; | 38 | struct inode *inode; |
39 | struct proc_inode *ei; | 39 | struct proc_inode *ei; |
40 | struct dentry *error = ERR_PTR(-ENOENT); | 40 | struct dentry *error = ERR_PTR(-ENOENT); |
41 | void *ns; | ||
41 | 42 | ||
42 | inode = proc_pid_make_inode(dir->i_sb, task); | 43 | inode = proc_pid_make_inode(dir->i_sb, task); |
43 | if (!inode) | 44 | if (!inode) |
44 | goto out; | 45 | goto out; |
45 | 46 | ||
47 | ns = ns_ops->get(task); | ||
48 | if (!ns) | ||
49 | goto out_iput; | ||
50 | |||
46 | ei = PROC_I(inode); | 51 | ei = PROC_I(inode); |
47 | inode->i_mode = S_IFREG|S_IRUSR; | 52 | inode->i_mode = S_IFREG|S_IRUSR; |
48 | inode->i_fop = &ns_file_operations; | 53 | inode->i_fop = &ns_file_operations; |
49 | ei->ns_ops = ns_ops; | 54 | ei->ns_ops = ns_ops; |
50 | ei->ns = ns_ops->get(task); | 55 | ei->ns = ns; |
51 | if (!ei->ns) | ||
52 | goto out_iput; | ||
53 | 56 | ||
54 | dentry->d_op = &pid_dentry_operations; | 57 | dentry->d_op = &pid_dentry_operations; |
55 | d_add(dentry, inode); | 58 | d_add(dentry, inode); |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index f50133c11c24..d167de365a8d 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -304,9 +304,6 @@ static int proc_sys_permission(struct inode *inode, int mask,unsigned int flags) | |||
304 | struct ctl_table *table; | 304 | struct ctl_table *table; |
305 | int error; | 305 | int error; |
306 | 306 | ||
307 | if (flags & IPERM_FLAG_RCU) | ||
308 | return -ECHILD; | ||
309 | |||
310 | /* Executable files are not allowed under /proc/sys/ */ | 307 | /* Executable files are not allowed under /proc/sys/ */ |
311 | if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) | 308 | if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) |
312 | return -EACCES; | 309 | return -EACCES; |
diff --git a/fs/proc/root.c b/fs/proc/root.c index a9000e9cfee5..d6c3b416529b 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -28,11 +28,12 @@ static int proc_test_super(struct super_block *sb, void *data) | |||
28 | 28 | ||
29 | static int proc_set_super(struct super_block *sb, void *data) | 29 | static int proc_set_super(struct super_block *sb, void *data) |
30 | { | 30 | { |
31 | struct pid_namespace *ns; | 31 | int err = set_anon_super(sb, NULL); |
32 | 32 | if (!err) { | |
33 | ns = (struct pid_namespace *)data; | 33 | struct pid_namespace *ns = (struct pid_namespace *)data; |
34 | sb->s_fs_info = get_pid_ns(ns); | 34 | sb->s_fs_info = get_pid_ns(ns); |
35 | return set_anon_super(sb, NULL); | 35 | } |
36 | return err; | ||
36 | } | 37 | } |
37 | 38 | ||
38 | static struct dentry *proc_mount(struct file_system_type *fs_type, | 39 | static struct dentry *proc_mount(struct file_system_type *fs_type, |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index e8a62f41b458..d78089690965 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -954,8 +954,6 @@ static int xattr_mount_check(struct super_block *s) | |||
954 | 954 | ||
955 | int reiserfs_permission(struct inode *inode, int mask, unsigned int flags) | 955 | int reiserfs_permission(struct inode *inode, int mask, unsigned int flags) |
956 | { | 956 | { |
957 | if (flags & IPERM_FLAG_RCU) | ||
958 | return -ECHILD; | ||
959 | /* | 957 | /* |
960 | * We don't do permission checks on the internal objects. | 958 | * We don't do permission checks on the internal objects. |
961 | * Permissions are determined by the "owning" object. | 959 | * Permissions are determined by the "owning" object. |
diff --git a/fs/romfs/mmap-nommu.c b/fs/romfs/mmap-nommu.c index f0511e816967..eed99428f104 100644 --- a/fs/romfs/mmap-nommu.c +++ b/fs/romfs/mmap-nommu.c | |||
@@ -27,14 +27,18 @@ static unsigned long romfs_get_unmapped_area(struct file *file, | |||
27 | { | 27 | { |
28 | struct inode *inode = file->f_mapping->host; | 28 | struct inode *inode = file->f_mapping->host; |
29 | struct mtd_info *mtd = inode->i_sb->s_mtd; | 29 | struct mtd_info *mtd = inode->i_sb->s_mtd; |
30 | unsigned long isize, offset; | 30 | unsigned long isize, offset, maxpages, lpages; |
31 | 31 | ||
32 | if (!mtd) | 32 | if (!mtd) |
33 | goto cant_map_directly; | 33 | goto cant_map_directly; |
34 | 34 | ||
35 | /* the mapping mustn't extend beyond the EOF */ | ||
36 | lpages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
35 | isize = i_size_read(inode); | 37 | isize = i_size_read(inode); |
36 | offset = pgoff << PAGE_SHIFT; | 38 | offset = pgoff << PAGE_SHIFT; |
37 | if (offset > isize || len > isize || offset > isize - len) | 39 | |
40 | maxpages = (isize + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
41 | if ((pgoff >= maxpages) || (maxpages - pgoff < lpages)) | ||
38 | return (unsigned long) -EINVAL; | 42 | return (unsigned long) -EINVAL; |
39 | 43 | ||
40 | /* we need to call down to the MTD layer to do the actual mapping */ | 44 | /* we need to call down to the MTD layer to do the actual mapping */ |
diff --git a/fs/super.c b/fs/super.c index c75593953c52..ab3d672db0de 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -822,7 +822,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, | |||
822 | } else { | 822 | } else { |
823 | char b[BDEVNAME_SIZE]; | 823 | char b[BDEVNAME_SIZE]; |
824 | 824 | ||
825 | s->s_flags = flags; | 825 | s->s_flags = flags | MS_NOSEC; |
826 | s->s_mode = mode; | 826 | s->s_mode = mode; |
827 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 827 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
828 | sb_set_blocksize(s, block_size(bdev)); | 828 | sb_set_blocksize(s, block_size(bdev)); |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 266895783b47..e34f0d99ea4e 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -95,6 +95,14 @@ static int sysfs_set_super(struct super_block *sb, void *data) | |||
95 | return error; | 95 | return error; |
96 | } | 96 | } |
97 | 97 | ||
98 | static void free_sysfs_super_info(struct sysfs_super_info *info) | ||
99 | { | ||
100 | int type; | ||
101 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) | ||
102 | kobj_ns_drop(type, info->ns[type]); | ||
103 | kfree(info); | ||
104 | } | ||
105 | |||
98 | static struct dentry *sysfs_mount(struct file_system_type *fs_type, | 106 | static struct dentry *sysfs_mount(struct file_system_type *fs_type, |
99 | int flags, const char *dev_name, void *data) | 107 | int flags, const char *dev_name, void *data) |
100 | { | 108 | { |
@@ -108,11 +116,11 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
108 | return ERR_PTR(-ENOMEM); | 116 | return ERR_PTR(-ENOMEM); |
109 | 117 | ||
110 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) | 118 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) |
111 | info->ns[type] = kobj_ns_current(type); | 119 | info->ns[type] = kobj_ns_grab_current(type); |
112 | 120 | ||
113 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); | 121 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); |
114 | if (IS_ERR(sb) || sb->s_fs_info != info) | 122 | if (IS_ERR(sb) || sb->s_fs_info != info) |
115 | kfree(info); | 123 | free_sysfs_super_info(info); |
116 | if (IS_ERR(sb)) | 124 | if (IS_ERR(sb)) |
117 | return ERR_CAST(sb); | 125 | return ERR_CAST(sb); |
118 | if (!sb->s_root) { | 126 | if (!sb->s_root) { |
@@ -131,12 +139,11 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
131 | static void sysfs_kill_sb(struct super_block *sb) | 139 | static void sysfs_kill_sb(struct super_block *sb) |
132 | { | 140 | { |
133 | struct sysfs_super_info *info = sysfs_info(sb); | 141 | struct sysfs_super_info *info = sysfs_info(sb); |
134 | |||
135 | /* Remove the superblock from fs_supers/s_instances | 142 | /* Remove the superblock from fs_supers/s_instances |
136 | * so we can't find it, before freeing sysfs_super_info. | 143 | * so we can't find it, before freeing sysfs_super_info. |
137 | */ | 144 | */ |
138 | kill_anon_super(sb); | 145 | kill_anon_super(sb); |
139 | kfree(info); | 146 | free_sysfs_super_info(info); |
140 | } | 147 | } |
141 | 148 | ||
142 | static struct file_system_type sysfs_fs_type = { | 149 | static struct file_system_type sysfs_fs_type = { |
@@ -145,28 +152,6 @@ static struct file_system_type sysfs_fs_type = { | |||
145 | .kill_sb = sysfs_kill_sb, | 152 | .kill_sb = sysfs_kill_sb, |
146 | }; | 153 | }; |
147 | 154 | ||
148 | void sysfs_exit_ns(enum kobj_ns_type type, const void *ns) | ||
149 | { | ||
150 | struct super_block *sb; | ||
151 | |||
152 | mutex_lock(&sysfs_mutex); | ||
153 | spin_lock(&sb_lock); | ||
154 | list_for_each_entry(sb, &sysfs_fs_type.fs_supers, s_instances) { | ||
155 | struct sysfs_super_info *info = sysfs_info(sb); | ||
156 | /* | ||
157 | * If we see a superblock on the fs_supers/s_instances | ||
158 | * list the unmount has not completed and sb->s_fs_info | ||
159 | * points to a valid struct sysfs_super_info. | ||
160 | */ | ||
161 | /* Ignore superblocks with the wrong ns */ | ||
162 | if (info->ns[type] != ns) | ||
163 | continue; | ||
164 | info->ns[type] = NULL; | ||
165 | } | ||
166 | spin_unlock(&sb_lock); | ||
167 | mutex_unlock(&sysfs_mutex); | ||
168 | } | ||
169 | |||
170 | int __init sysfs_init(void) | 155 | int __init sysfs_init(void) |
171 | { | 156 | { |
172 | int err = -ENOMEM; | 157 | int err = -ENOMEM; |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 3d28af31d863..2ed2404f3113 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -136,7 +136,7 @@ struct sysfs_addrm_cxt { | |||
136 | * instance). | 136 | * instance). |
137 | */ | 137 | */ |
138 | struct sysfs_super_info { | 138 | struct sysfs_super_info { |
139 | const void *ns[KOBJ_NS_TYPES]; | 139 | void *ns[KOBJ_NS_TYPES]; |
140 | }; | 140 | }; |
141 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) | 141 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) |
142 | extern struct sysfs_dirent sysfs_root; | 142 | extern struct sysfs_dirent sysfs_root; |
diff --git a/fs/timerfd.c b/fs/timerfd.c index f67acbdda5e8..dffeb3795af1 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
@@ -61,7 +61,9 @@ static enum hrtimer_restart timerfd_tmrproc(struct hrtimer *htmr) | |||
61 | 61 | ||
62 | /* | 62 | /* |
63 | * Called when the clock was set to cancel the timers in the cancel | 63 | * Called when the clock was set to cancel the timers in the cancel |
64 | * list. | 64 | * list. This will wake up processes waiting on these timers. The |
65 | * wake-up requires ctx->ticks to be non zero, therefore we increment | ||
66 | * it before calling wake_up_locked(). | ||
65 | */ | 67 | */ |
66 | void timerfd_clock_was_set(void) | 68 | void timerfd_clock_was_set(void) |
67 | { | 69 | { |
@@ -76,6 +78,7 @@ void timerfd_clock_was_set(void) | |||
76 | spin_lock_irqsave(&ctx->wqh.lock, flags); | 78 | spin_lock_irqsave(&ctx->wqh.lock, flags); |
77 | if (ctx->moffs.tv64 != moffs.tv64) { | 79 | if (ctx->moffs.tv64 != moffs.tv64) { |
78 | ctx->moffs.tv64 = KTIME_MAX; | 80 | ctx->moffs.tv64 = KTIME_MAX; |
81 | ctx->ticks++; | ||
79 | wake_up_locked(&ctx->wqh); | 82 | wake_up_locked(&ctx->wqh); |
80 | } | 83 | } |
81 | spin_unlock_irqrestore(&ctx->wqh.lock, flags); | 84 | spin_unlock_irqrestore(&ctx->wqh.lock, flags); |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index b5aeb5a8ebed..529be0582029 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1848,7 +1848,6 @@ static void ubifs_put_super(struct super_block *sb) | |||
1848 | bdi_destroy(&c->bdi); | 1848 | bdi_destroy(&c->bdi); |
1849 | ubi_close_volume(c->ubi); | 1849 | ubi_close_volume(c->ubi); |
1850 | mutex_unlock(&c->umount_mutex); | 1850 | mutex_unlock(&c->umount_mutex); |
1851 | kfree(c); | ||
1852 | } | 1851 | } |
1853 | 1852 | ||
1854 | static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | 1853 | static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) |
@@ -1971,61 +1970,65 @@ static struct ubi_volume_desc *open_ubi(const char *name, int mode) | |||
1971 | return ERR_PTR(-EINVAL); | 1970 | return ERR_PTR(-EINVAL); |
1972 | } | 1971 | } |
1973 | 1972 | ||
1974 | static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | 1973 | static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi) |
1975 | { | 1974 | { |
1976 | struct ubi_volume_desc *ubi = sb->s_fs_info; | ||
1977 | struct ubifs_info *c; | 1975 | struct ubifs_info *c; |
1978 | struct inode *root; | ||
1979 | int err; | ||
1980 | 1976 | ||
1981 | c = kzalloc(sizeof(struct ubifs_info), GFP_KERNEL); | 1977 | c = kzalloc(sizeof(struct ubifs_info), GFP_KERNEL); |
1982 | if (!c) | 1978 | if (c) { |
1983 | return -ENOMEM; | 1979 | spin_lock_init(&c->cnt_lock); |
1980 | spin_lock_init(&c->cs_lock); | ||
1981 | spin_lock_init(&c->buds_lock); | ||
1982 | spin_lock_init(&c->space_lock); | ||
1983 | spin_lock_init(&c->orphan_lock); | ||
1984 | init_rwsem(&c->commit_sem); | ||
1985 | mutex_init(&c->lp_mutex); | ||
1986 | mutex_init(&c->tnc_mutex); | ||
1987 | mutex_init(&c->log_mutex); | ||
1988 | mutex_init(&c->mst_mutex); | ||
1989 | mutex_init(&c->umount_mutex); | ||
1990 | mutex_init(&c->bu_mutex); | ||
1991 | mutex_init(&c->write_reserve_mutex); | ||
1992 | init_waitqueue_head(&c->cmt_wq); | ||
1993 | c->buds = RB_ROOT; | ||
1994 | c->old_idx = RB_ROOT; | ||
1995 | c->size_tree = RB_ROOT; | ||
1996 | c->orph_tree = RB_ROOT; | ||
1997 | INIT_LIST_HEAD(&c->infos_list); | ||
1998 | INIT_LIST_HEAD(&c->idx_gc); | ||
1999 | INIT_LIST_HEAD(&c->replay_list); | ||
2000 | INIT_LIST_HEAD(&c->replay_buds); | ||
2001 | INIT_LIST_HEAD(&c->uncat_list); | ||
2002 | INIT_LIST_HEAD(&c->empty_list); | ||
2003 | INIT_LIST_HEAD(&c->freeable_list); | ||
2004 | INIT_LIST_HEAD(&c->frdi_idx_list); | ||
2005 | INIT_LIST_HEAD(&c->unclean_leb_list); | ||
2006 | INIT_LIST_HEAD(&c->old_buds); | ||
2007 | INIT_LIST_HEAD(&c->orph_list); | ||
2008 | INIT_LIST_HEAD(&c->orph_new); | ||
2009 | c->no_chk_data_crc = 1; | ||
2010 | |||
2011 | c->highest_inum = UBIFS_FIRST_INO; | ||
2012 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; | ||
2013 | |||
2014 | ubi_get_volume_info(ubi, &c->vi); | ||
2015 | ubi_get_device_info(c->vi.ubi_num, &c->di); | ||
2016 | } | ||
2017 | return c; | ||
2018 | } | ||
1984 | 2019 | ||
1985 | spin_lock_init(&c->cnt_lock); | 2020 | static int ubifs_fill_super(struct super_block *sb, void *data, int silent) |
1986 | spin_lock_init(&c->cs_lock); | 2021 | { |
1987 | spin_lock_init(&c->buds_lock); | 2022 | struct ubifs_info *c = sb->s_fs_info; |
1988 | spin_lock_init(&c->space_lock); | 2023 | struct inode *root; |
1989 | spin_lock_init(&c->orphan_lock); | 2024 | int err; |
1990 | init_rwsem(&c->commit_sem); | ||
1991 | mutex_init(&c->lp_mutex); | ||
1992 | mutex_init(&c->tnc_mutex); | ||
1993 | mutex_init(&c->log_mutex); | ||
1994 | mutex_init(&c->mst_mutex); | ||
1995 | mutex_init(&c->umount_mutex); | ||
1996 | mutex_init(&c->bu_mutex); | ||
1997 | mutex_init(&c->write_reserve_mutex); | ||
1998 | init_waitqueue_head(&c->cmt_wq); | ||
1999 | c->buds = RB_ROOT; | ||
2000 | c->old_idx = RB_ROOT; | ||
2001 | c->size_tree = RB_ROOT; | ||
2002 | c->orph_tree = RB_ROOT; | ||
2003 | INIT_LIST_HEAD(&c->infos_list); | ||
2004 | INIT_LIST_HEAD(&c->idx_gc); | ||
2005 | INIT_LIST_HEAD(&c->replay_list); | ||
2006 | INIT_LIST_HEAD(&c->replay_buds); | ||
2007 | INIT_LIST_HEAD(&c->uncat_list); | ||
2008 | INIT_LIST_HEAD(&c->empty_list); | ||
2009 | INIT_LIST_HEAD(&c->freeable_list); | ||
2010 | INIT_LIST_HEAD(&c->frdi_idx_list); | ||
2011 | INIT_LIST_HEAD(&c->unclean_leb_list); | ||
2012 | INIT_LIST_HEAD(&c->old_buds); | ||
2013 | INIT_LIST_HEAD(&c->orph_list); | ||
2014 | INIT_LIST_HEAD(&c->orph_new); | ||
2015 | c->no_chk_data_crc = 1; | ||
2016 | 2025 | ||
2017 | c->vfs_sb = sb; | 2026 | c->vfs_sb = sb; |
2018 | c->highest_inum = UBIFS_FIRST_INO; | ||
2019 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; | ||
2020 | |||
2021 | ubi_get_volume_info(ubi, &c->vi); | ||
2022 | ubi_get_device_info(c->vi.ubi_num, &c->di); | ||
2023 | |||
2024 | /* Re-open the UBI device in read-write mode */ | 2027 | /* Re-open the UBI device in read-write mode */ |
2025 | c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READWRITE); | 2028 | c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READWRITE); |
2026 | if (IS_ERR(c->ubi)) { | 2029 | if (IS_ERR(c->ubi)) { |
2027 | err = PTR_ERR(c->ubi); | 2030 | err = PTR_ERR(c->ubi); |
2028 | goto out_free; | 2031 | goto out; |
2029 | } | 2032 | } |
2030 | 2033 | ||
2031 | /* | 2034 | /* |
@@ -2091,24 +2094,29 @@ out_bdi: | |||
2091 | bdi_destroy(&c->bdi); | 2094 | bdi_destroy(&c->bdi); |
2092 | out_close: | 2095 | out_close: |
2093 | ubi_close_volume(c->ubi); | 2096 | ubi_close_volume(c->ubi); |
2094 | out_free: | 2097 | out: |
2095 | kfree(c); | ||
2096 | return err; | 2098 | return err; |
2097 | } | 2099 | } |
2098 | 2100 | ||
2099 | static int sb_test(struct super_block *sb, void *data) | 2101 | static int sb_test(struct super_block *sb, void *data) |
2100 | { | 2102 | { |
2101 | dev_t *dev = data; | 2103 | struct ubifs_info *c1 = data; |
2102 | struct ubifs_info *c = sb->s_fs_info; | 2104 | struct ubifs_info *c = sb->s_fs_info; |
2103 | 2105 | ||
2104 | return c->vi.cdev == *dev; | 2106 | return c->vi.cdev == c1->vi.cdev; |
2107 | } | ||
2108 | |||
2109 | static int sb_set(struct super_block *sb, void *data) | ||
2110 | { | ||
2111 | sb->s_fs_info = data; | ||
2112 | return set_anon_super(sb, NULL); | ||
2105 | } | 2113 | } |
2106 | 2114 | ||
2107 | static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | 2115 | static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, |
2108 | const char *name, void *data) | 2116 | const char *name, void *data) |
2109 | { | 2117 | { |
2110 | struct ubi_volume_desc *ubi; | 2118 | struct ubi_volume_desc *ubi; |
2111 | struct ubi_volume_info vi; | 2119 | struct ubifs_info *c; |
2112 | struct super_block *sb; | 2120 | struct super_block *sb; |
2113 | int err; | 2121 | int err; |
2114 | 2122 | ||
@@ -2125,19 +2133,25 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2125 | name, (int)PTR_ERR(ubi)); | 2133 | name, (int)PTR_ERR(ubi)); |
2126 | return ERR_CAST(ubi); | 2134 | return ERR_CAST(ubi); |
2127 | } | 2135 | } |
2128 | ubi_get_volume_info(ubi, &vi); | ||
2129 | 2136 | ||
2130 | dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id); | 2137 | c = alloc_ubifs_info(ubi); |
2138 | if (!c) { | ||
2139 | err = -ENOMEM; | ||
2140 | goto out_close; | ||
2141 | } | ||
2142 | |||
2143 | dbg_gen("opened ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); | ||
2131 | 2144 | ||
2132 | sb = sget(fs_type, &sb_test, &set_anon_super, &vi.cdev); | 2145 | sb = sget(fs_type, sb_test, sb_set, c); |
2133 | if (IS_ERR(sb)) { | 2146 | if (IS_ERR(sb)) { |
2134 | err = PTR_ERR(sb); | 2147 | err = PTR_ERR(sb); |
2148 | kfree(c); | ||
2135 | goto out_close; | 2149 | goto out_close; |
2136 | } | 2150 | } |
2137 | 2151 | ||
2138 | if (sb->s_root) { | 2152 | if (sb->s_root) { |
2139 | struct ubifs_info *c1 = sb->s_fs_info; | 2153 | struct ubifs_info *c1 = sb->s_fs_info; |
2140 | 2154 | kfree(c); | |
2141 | /* A new mount point for already mounted UBIFS */ | 2155 | /* A new mount point for already mounted UBIFS */ |
2142 | dbg_gen("this ubi volume is already mounted"); | 2156 | dbg_gen("this ubi volume is already mounted"); |
2143 | if (!!(flags & MS_RDONLY) != c1->ro_mount) { | 2157 | if (!!(flags & MS_RDONLY) != c1->ro_mount) { |
@@ -2146,11 +2160,6 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2146 | } | 2160 | } |
2147 | } else { | 2161 | } else { |
2148 | sb->s_flags = flags; | 2162 | sb->s_flags = flags; |
2149 | /* | ||
2150 | * Pass 'ubi' to 'fill_super()' in sb->s_fs_info where it is | ||
2151 | * replaced by 'c'. | ||
2152 | */ | ||
2153 | sb->s_fs_info = ubi; | ||
2154 | err = ubifs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); | 2163 | err = ubifs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); |
2155 | if (err) | 2164 | if (err) |
2156 | goto out_deact; | 2165 | goto out_deact; |
@@ -2170,11 +2179,18 @@ out_close: | |||
2170 | return ERR_PTR(err); | 2179 | return ERR_PTR(err); |
2171 | } | 2180 | } |
2172 | 2181 | ||
2182 | static void kill_ubifs_super(struct super_block *s) | ||
2183 | { | ||
2184 | struct ubifs_info *c = s->s_fs_info; | ||
2185 | kill_anon_super(s); | ||
2186 | kfree(c); | ||
2187 | } | ||
2188 | |||
2173 | static struct file_system_type ubifs_fs_type = { | 2189 | static struct file_system_type ubifs_fs_type = { |
2174 | .name = "ubifs", | 2190 | .name = "ubifs", |
2175 | .owner = THIS_MODULE, | 2191 | .owner = THIS_MODULE, |
2176 | .mount = ubifs_mount, | 2192 | .mount = ubifs_mount, |
2177 | .kill_sb = kill_anon_super, | 2193 | .kill_sb = kill_ubifs_super, |
2178 | }; | 2194 | }; |
2179 | 2195 | ||
2180 | /* | 2196 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index f4213ba1ff85..7f782af286bf 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -131,19 +131,34 @@ xfs_file_fsync( | |||
131 | { | 131 | { |
132 | struct inode *inode = file->f_mapping->host; | 132 | struct inode *inode = file->f_mapping->host; |
133 | struct xfs_inode *ip = XFS_I(inode); | 133 | struct xfs_inode *ip = XFS_I(inode); |
134 | struct xfs_mount *mp = ip->i_mount; | ||
134 | struct xfs_trans *tp; | 135 | struct xfs_trans *tp; |
135 | int error = 0; | 136 | int error = 0; |
136 | int log_flushed = 0; | 137 | int log_flushed = 0; |
137 | 138 | ||
138 | trace_xfs_file_fsync(ip); | 139 | trace_xfs_file_fsync(ip); |
139 | 140 | ||
140 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 141 | if (XFS_FORCED_SHUTDOWN(mp)) |
141 | return -XFS_ERROR(EIO); | 142 | return -XFS_ERROR(EIO); |
142 | 143 | ||
143 | xfs_iflags_clear(ip, XFS_ITRUNCATED); | 144 | xfs_iflags_clear(ip, XFS_ITRUNCATED); |
144 | 145 | ||
145 | xfs_ioend_wait(ip); | 146 | xfs_ioend_wait(ip); |
146 | 147 | ||
148 | if (mp->m_flags & XFS_MOUNT_BARRIER) { | ||
149 | /* | ||
150 | * If we have an RT and/or log subvolume we need to make sure | ||
151 | * to flush the write cache the device used for file data | ||
152 | * first. This is to ensure newly written file data make | ||
153 | * it to disk before logging the new inode size in case of | ||
154 | * an extending write. | ||
155 | */ | ||
156 | if (XFS_IS_REALTIME_INODE(ip)) | ||
157 | xfs_blkdev_issue_flush(mp->m_rtdev_targp); | ||
158 | else if (mp->m_logdev_targp != mp->m_ddev_targp) | ||
159 | xfs_blkdev_issue_flush(mp->m_ddev_targp); | ||
160 | } | ||
161 | |||
147 | /* | 162 | /* |
148 | * We always need to make sure that the required inode state is safe on | 163 | * We always need to make sure that the required inode state is safe on |
149 | * disk. The inode might be clean but we still might need to force the | 164 | * disk. The inode might be clean but we still might need to force the |
@@ -175,9 +190,9 @@ xfs_file_fsync( | |||
175 | * updates. The sync transaction will also force the log. | 190 | * updates. The sync transaction will also force the log. |
176 | */ | 191 | */ |
177 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 192 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
178 | tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS); | 193 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); |
179 | error = xfs_trans_reserve(tp, 0, | 194 | error = xfs_trans_reserve(tp, 0, |
180 | XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0); | 195 | XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); |
181 | if (error) { | 196 | if (error) { |
182 | xfs_trans_cancel(tp, 0); | 197 | xfs_trans_cancel(tp, 0); |
183 | return -error; | 198 | return -error; |
@@ -209,28 +224,25 @@ xfs_file_fsync( | |||
209 | * force the log. | 224 | * force the log. |
210 | */ | 225 | */ |
211 | if (xfs_ipincount(ip)) { | 226 | if (xfs_ipincount(ip)) { |
212 | error = _xfs_log_force_lsn(ip->i_mount, | 227 | error = _xfs_log_force_lsn(mp, |
213 | ip->i_itemp->ili_last_lsn, | 228 | ip->i_itemp->ili_last_lsn, |
214 | XFS_LOG_SYNC, &log_flushed); | 229 | XFS_LOG_SYNC, &log_flushed); |
215 | } | 230 | } |
216 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 231 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
217 | } | 232 | } |
218 | 233 | ||
219 | if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) { | 234 | /* |
220 | /* | 235 | * If we only have a single device, and the log force about was |
221 | * If the log write didn't issue an ordered tag we need | 236 | * a no-op we might have to flush the data device cache here. |
222 | * to flush the disk cache for the data device now. | 237 | * This can only happen for fdatasync/O_DSYNC if we were overwriting |
223 | */ | 238 | * an already allocated file and thus do not have any metadata to |
224 | if (!log_flushed) | 239 | * commit. |
225 | xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp); | 240 | */ |
226 | 241 | if ((mp->m_flags & XFS_MOUNT_BARRIER) && | |
227 | /* | 242 | mp->m_logdev_targp == mp->m_ddev_targp && |
228 | * If this inode is on the RT dev we need to flush that | 243 | !XFS_IS_REALTIME_INODE(ip) && |
229 | * cache as well. | 244 | !log_flushed) |
230 | */ | 245 | xfs_blkdev_issue_flush(mp->m_ddev_targp); |
231 | if (XFS_IS_REALTIME_INODE(ip)) | ||
232 | xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp); | ||
233 | } | ||
234 | 246 | ||
235 | return -error; | 247 | return -error; |
236 | } | 248 | } |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index dd21784525a8..d44d92cd12b1 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -182,7 +182,7 @@ xfs_vn_mknod( | |||
182 | if (IS_POSIXACL(dir)) { | 182 | if (IS_POSIXACL(dir)) { |
183 | default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT); | 183 | default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT); |
184 | if (IS_ERR(default_acl)) | 184 | if (IS_ERR(default_acl)) |
185 | return -PTR_ERR(default_acl); | 185 | return PTR_ERR(default_acl); |
186 | 186 | ||
187 | if (!default_acl) | 187 | if (!default_acl) |
188 | mode &= ~current_umask(); | 188 | mode &= ~current_umask(); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 1e3a7ce804dc..a1a881e68a9a 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -627,68 +627,6 @@ xfs_blkdev_put( | |||
627 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | 627 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
628 | } | 628 | } |
629 | 629 | ||
630 | /* | ||
631 | * Try to write out the superblock using barriers. | ||
632 | */ | ||
633 | STATIC int | ||
634 | xfs_barrier_test( | ||
635 | xfs_mount_t *mp) | ||
636 | { | ||
637 | xfs_buf_t *sbp = xfs_getsb(mp, 0); | ||
638 | int error; | ||
639 | |||
640 | XFS_BUF_UNDONE(sbp); | ||
641 | XFS_BUF_UNREAD(sbp); | ||
642 | XFS_BUF_UNDELAYWRITE(sbp); | ||
643 | XFS_BUF_WRITE(sbp); | ||
644 | XFS_BUF_UNASYNC(sbp); | ||
645 | XFS_BUF_ORDERED(sbp); | ||
646 | |||
647 | xfsbdstrat(mp, sbp); | ||
648 | error = xfs_buf_iowait(sbp); | ||
649 | |||
650 | /* | ||
651 | * Clear all the flags we set and possible error state in the | ||
652 | * buffer. We only did the write to try out whether barriers | ||
653 | * worked and shouldn't leave any traces in the superblock | ||
654 | * buffer. | ||
655 | */ | ||
656 | XFS_BUF_DONE(sbp); | ||
657 | XFS_BUF_ERROR(sbp, 0); | ||
658 | XFS_BUF_UNORDERED(sbp); | ||
659 | |||
660 | xfs_buf_relse(sbp); | ||
661 | return error; | ||
662 | } | ||
663 | |||
664 | STATIC void | ||
665 | xfs_mountfs_check_barriers(xfs_mount_t *mp) | ||
666 | { | ||
667 | int error; | ||
668 | |||
669 | if (mp->m_logdev_targp != mp->m_ddev_targp) { | ||
670 | xfs_notice(mp, | ||
671 | "Disabling barriers, not supported with external log device"); | ||
672 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
673 | return; | ||
674 | } | ||
675 | |||
676 | if (xfs_readonly_buftarg(mp->m_ddev_targp)) { | ||
677 | xfs_notice(mp, | ||
678 | "Disabling barriers, underlying device is readonly"); | ||
679 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
680 | return; | ||
681 | } | ||
682 | |||
683 | error = xfs_barrier_test(mp); | ||
684 | if (error) { | ||
685 | xfs_notice(mp, | ||
686 | "Disabling barriers, trial barrier write failed"); | ||
687 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
688 | return; | ||
689 | } | ||
690 | } | ||
691 | |||
692 | void | 630 | void |
693 | xfs_blkdev_issue_flush( | 631 | xfs_blkdev_issue_flush( |
694 | xfs_buftarg_t *buftarg) | 632 | xfs_buftarg_t *buftarg) |
@@ -1240,14 +1178,6 @@ xfs_fs_remount( | |||
1240 | switch (token) { | 1178 | switch (token) { |
1241 | case Opt_barrier: | 1179 | case Opt_barrier: |
1242 | mp->m_flags |= XFS_MOUNT_BARRIER; | 1180 | mp->m_flags |= XFS_MOUNT_BARRIER; |
1243 | |||
1244 | /* | ||
1245 | * Test if barriers are actually working if we can, | ||
1246 | * else delay this check until the filesystem is | ||
1247 | * marked writeable. | ||
1248 | */ | ||
1249 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) | ||
1250 | xfs_mountfs_check_barriers(mp); | ||
1251 | break; | 1181 | break; |
1252 | case Opt_nobarrier: | 1182 | case Opt_nobarrier: |
1253 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1183 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
@@ -1282,8 +1212,6 @@ xfs_fs_remount( | |||
1282 | /* ro -> rw */ | 1212 | /* ro -> rw */ |
1283 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { | 1213 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { |
1284 | mp->m_flags &= ~XFS_MOUNT_RDONLY; | 1214 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
1285 | if (mp->m_flags & XFS_MOUNT_BARRIER) | ||
1286 | xfs_mountfs_check_barriers(mp); | ||
1287 | 1215 | ||
1288 | /* | 1216 | /* |
1289 | * If this is the first remount to writeable state we | 1217 | * If this is the first remount to writeable state we |
@@ -1465,9 +1393,6 @@ xfs_fs_fill_super( | |||
1465 | if (error) | 1393 | if (error) |
1466 | goto out_free_sb; | 1394 | goto out_free_sb; |
1467 | 1395 | ||
1468 | if (mp->m_flags & XFS_MOUNT_BARRIER) | ||
1469 | xfs_mountfs_check_barriers(mp); | ||
1470 | |||
1471 | error = xfs_filestream_mount(mp); | 1396 | error = xfs_filestream_mount(mp); |
1472 | if (error) | 1397 | if (error) |
1473 | goto out_free_sb; | 1398 | goto out_free_sb; |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index c86375378810..01d2072fb6d4 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -490,6 +490,13 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) | |||
490 | args.whichfork = XFS_ATTR_FORK; | 490 | args.whichfork = XFS_ATTR_FORK; |
491 | 491 | ||
492 | /* | 492 | /* |
493 | * we have no control over the attribute names that userspace passes us | ||
494 | * to remove, so we have to allow the name lookup prior to attribute | ||
495 | * removal to fail. | ||
496 | */ | ||
497 | args.op_flags = XFS_DA_OP_OKNOENT; | ||
498 | |||
499 | /* | ||
493 | * Attach the dquots to the inode. | 500 | * Attach the dquots to the inode. |
494 | */ | 501 | */ |
495 | error = xfs_qm_dqattach(dp, 0); | 502 | error = xfs_qm_dqattach(dp, 0); |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index cb9b6d1469f7..3631783b2b53 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -253,16 +253,21 @@ xfs_iget_cache_hit( | |||
253 | rcu_read_lock(); | 253 | rcu_read_lock(); |
254 | spin_lock(&ip->i_flags_lock); | 254 | spin_lock(&ip->i_flags_lock); |
255 | 255 | ||
256 | ip->i_flags &= ~XFS_INEW; | 256 | ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM); |
257 | ip->i_flags |= XFS_IRECLAIMABLE; | 257 | ASSERT(ip->i_flags & XFS_IRECLAIMABLE); |
258 | __xfs_inode_set_reclaim_tag(pag, ip); | ||
259 | trace_xfs_iget_reclaim_fail(ip); | 258 | trace_xfs_iget_reclaim_fail(ip); |
260 | goto out_error; | 259 | goto out_error; |
261 | } | 260 | } |
262 | 261 | ||
263 | spin_lock(&pag->pag_ici_lock); | 262 | spin_lock(&pag->pag_ici_lock); |
264 | spin_lock(&ip->i_flags_lock); | 263 | spin_lock(&ip->i_flags_lock); |
265 | ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM); | 264 | |
265 | /* | ||
266 | * Clear the per-lifetime state in the inode as we are now | ||
267 | * effectively a new inode and need to return to the initial | ||
268 | * state before reuse occurs. | ||
269 | */ | ||
270 | ip->i_flags &= ~XFS_IRECLAIM_RESET_FLAGS; | ||
266 | ip->i_flags |= XFS_INEW; | 271 | ip->i_flags |= XFS_INEW; |
267 | __xfs_inode_clear_reclaim_tag(mp, pag, ip); | 272 | __xfs_inode_clear_reclaim_tag(mp, pag, ip); |
268 | inode->i_state = I_NEW; | 273 | inode->i_state = I_NEW; |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 3ae6d58e5473..964cfea77686 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -384,6 +384,16 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) | |||
384 | #define XFS_IDIRTY_RELEASE 0x0040 /* dirty release already seen */ | 384 | #define XFS_IDIRTY_RELEASE 0x0040 /* dirty release already seen */ |
385 | 385 | ||
386 | /* | 386 | /* |
387 | * Per-lifetime flags need to be reset when re-using a reclaimable inode during | ||
388 | * inode lookup. Thi prevents unintended behaviour on the new inode from | ||
389 | * ocurring. | ||
390 | */ | ||
391 | #define XFS_IRECLAIM_RESET_FLAGS \ | ||
392 | (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ | ||
393 | XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | \ | ||
394 | XFS_IFILESTREAM); | ||
395 | |||
396 | /* | ||
387 | * Flags for inode locking. | 397 | * Flags for inode locking. |
388 | * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) | 398 | * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) |
389 | * 1<<16 - 1<<32-1 -- lockdep annotation (integers) | 399 | * 1<<16 - 1<<32-1 -- lockdep annotation (integers) |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 09983a3344a5..b1e88d56069c 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -681,15 +681,15 @@ xfs_inode_item_unlock( | |||
681 | * where the cluster buffer may be unpinned before the inode is inserted into | 681 | * where the cluster buffer may be unpinned before the inode is inserted into |
682 | * the AIL during transaction committed processing. If the buffer is unpinned | 682 | * the AIL during transaction committed processing. If the buffer is unpinned |
683 | * before the inode item has been committed and inserted, then it is possible | 683 | * before the inode item has been committed and inserted, then it is possible |
684 | * for the buffer to be written and IO completions before the inode is inserted | 684 | * for the buffer to be written and IO completes before the inode is inserted |
685 | * into the AIL. In that case, we'd be inserting a clean, stale inode into the | 685 | * into the AIL. In that case, we'd be inserting a clean, stale inode into the |
686 | * AIL which will never get removed. It will, however, get reclaimed which | 686 | * AIL which will never get removed. It will, however, get reclaimed which |
687 | * triggers an assert in xfs_inode_free() complaining about freein an inode | 687 | * triggers an assert in xfs_inode_free() complaining about freein an inode |
688 | * still in the AIL. | 688 | * still in the AIL. |
689 | * | 689 | * |
690 | * To avoid this, return a lower LSN than the one passed in so that the | 690 | * To avoid this, just unpin the inode directly and return a LSN of -1 so the |
691 | * transaction committed code will not move the inode forward in the AIL but | 691 | * transaction committed code knows that it does not need to do any further |
692 | * will still unpin it properly. | 692 | * processing on the item. |
693 | */ | 693 | */ |
694 | STATIC xfs_lsn_t | 694 | STATIC xfs_lsn_t |
695 | xfs_inode_item_committed( | 695 | xfs_inode_item_committed( |
@@ -699,8 +699,10 @@ xfs_inode_item_committed( | |||
699 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); | 699 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); |
700 | struct xfs_inode *ip = iip->ili_inode; | 700 | struct xfs_inode *ip = iip->ili_inode; |
701 | 701 | ||
702 | if (xfs_iflags_test(ip, XFS_ISTALE)) | 702 | if (xfs_iflags_test(ip, XFS_ISTALE)) { |
703 | return lsn - 1; | 703 | xfs_inode_item_unpin(lip, 0); |
704 | return -1; | ||
705 | } | ||
704 | return lsn; | 706 | return lsn; |
705 | } | 707 | } |
706 | 708 | ||
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 211930246f20..41d5b8f2bf92 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1372,8 +1372,17 @@ xlog_sync(xlog_t *log, | |||
1372 | XFS_BUF_ASYNC(bp); | 1372 | XFS_BUF_ASYNC(bp); |
1373 | bp->b_flags |= XBF_LOG_BUFFER; | 1373 | bp->b_flags |= XBF_LOG_BUFFER; |
1374 | 1374 | ||
1375 | if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) | 1375 | if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { |
1376 | /* | ||
1377 | * If we have an external log device, flush the data device | ||
1378 | * before flushing the log to make sure all meta data | ||
1379 | * written back from the AIL actually made it to disk | ||
1380 | * before writing out the new log tail LSN in the log buffer. | ||
1381 | */ | ||
1382 | if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp) | ||
1383 | xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp); | ||
1376 | XFS_BUF_ORDERED(bp); | 1384 | XFS_BUF_ORDERED(bp); |
1385 | } | ||
1377 | 1386 | ||
1378 | ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); | 1387 | ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); |
1379 | ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); | 1388 | ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 7c7bc2b786bd..c83f63b33aae 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1361,7 +1361,7 @@ xfs_trans_item_committed( | |||
1361 | lip->li_flags |= XFS_LI_ABORTED; | 1361 | lip->li_flags |= XFS_LI_ABORTED; |
1362 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | 1362 | item_lsn = IOP_COMMITTED(lip, commit_lsn); |
1363 | 1363 | ||
1364 | /* If the committed routine returns -1, item has been freed. */ | 1364 | /* item_lsn of -1 means the item needs no further processing */ |
1365 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | 1365 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) |
1366 | return; | 1366 | return; |
1367 | 1367 | ||
@@ -1474,7 +1474,7 @@ xfs_trans_committed_bulk( | |||
1474 | lip->li_flags |= XFS_LI_ABORTED; | 1474 | lip->li_flags |= XFS_LI_ABORTED; |
1475 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | 1475 | item_lsn = IOP_COMMITTED(lip, commit_lsn); |
1476 | 1476 | ||
1477 | /* item_lsn of -1 means the item was freed */ | 1477 | /* item_lsn of -1 means the item needs no further processing */ |
1478 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | 1478 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) |
1479 | continue; | 1479 | continue; |
1480 | 1480 | ||
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index b7a5fe7c52c8..619720705bc6 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -960,8 +960,11 @@ xfs_release( | |||
960 | * be exposed to that problem. | 960 | * be exposed to that problem. |
961 | */ | 961 | */ |
962 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); | 962 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); |
963 | if (truncated && VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) | 963 | if (truncated) { |
964 | xfs_flush_pages(ip, 0, -1, XBF_ASYNC, FI_NONE); | 964 | xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE); |
965 | if (VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) | ||
966 | xfs_flush_pages(ip, 0, -1, XBF_ASYNC, FI_NONE); | ||
967 | } | ||
965 | } | 968 | } |
966 | 969 | ||
967 | if (ip->i_d.di_nlink == 0) | 970 | if (ip->i_d.di_nlink == 0) |