diff options
Diffstat (limited to 'fs')
139 files changed, 2651 insertions, 1780 deletions
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 0efd1524b977..370b24cee4d8 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt | |||
@@ -65,6 +65,20 @@ config CORE_DUMP_DEFAULT_ELF_HEADERS | |||
65 | This config option changes the default setting of coredump_filter | 65 | This config option changes the default setting of coredump_filter |
66 | seen at boot time. If unsure, say Y. | 66 | seen at boot time. If unsure, say Y. |
67 | 67 | ||
68 | config BINFMT_SCRIPT | ||
69 | tristate "Kernel support for scripts starting with #!" | ||
70 | default y | ||
71 | help | ||
72 | Say Y here if you want to execute interpreted scripts starting with | ||
73 | #! followed by the path to an interpreter. | ||
74 | |||
75 | You can build this support as a module; however, until that module | ||
76 | gets loaded, you cannot run scripts. Thus, if you want to load this | ||
77 | module from an initramfs, the portion of the initramfs before loading | ||
78 | this module must consist of compiled binaries only. | ||
79 | |||
80 | Most systems will not boot if you say M or N here. If unsure, say Y. | ||
81 | |||
68 | config BINFMT_FLAT | 82 | config BINFMT_FLAT |
69 | bool "Kernel support for flat binaries" | 83 | bool "Kernel support for flat binaries" |
70 | depends on !MMU && (!FRV || BROKEN) | 84 | depends on !MMU && (!FRV || BROKEN) |
diff --git a/fs/Makefile b/fs/Makefile index 9d53192236fc..5e67e57b59dc 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -10,7 +10,7 @@ obj-y := open.o read_write.o file_table.o super.o \ | |||
10 | ioctl.o readdir.o select.o fifo.o dcache.o inode.o \ | 10 | ioctl.o readdir.o select.o fifo.o dcache.o inode.o \ |
11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ | 11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ |
12 | seq_file.o xattr.o libfs.o fs-writeback.o \ | 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ |
13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ | 13 | pnode.o splice.o sync.o utimes.o \ |
14 | stack.o fs_struct.o statfs.o | 14 | stack.o fs_struct.o statfs.o |
15 | 15 | ||
16 | ifeq ($(CONFIG_BLOCK),y) | 16 | ifeq ($(CONFIG_BLOCK),y) |
@@ -34,10 +34,7 @@ obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o | |||
34 | obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o | 34 | obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o |
35 | obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o | 35 | obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o |
36 | obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o | 36 | obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o |
37 | 37 | obj-$(CONFIG_BINFMT_SCRIPT) += binfmt_script.o | |
38 | # binfmt_script is always there | ||
39 | obj-y += binfmt_script.o | ||
40 | |||
41 | obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o | 38 | obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o |
42 | obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o | 39 | obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o |
43 | obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o | 40 | obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o |
@@ -49,6 +46,7 @@ obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o | |||
49 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ | 46 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ |
50 | obj-$(CONFIG_GENERIC_ACL) += generic_acl.o | 47 | obj-$(CONFIG_GENERIC_ACL) += generic_acl.o |
51 | obj-$(CONFIG_COREDUMP) += coredump.o | 48 | obj-$(CONFIG_COREDUMP) += coredump.o |
49 | obj-$(CONFIG_SYSCTL) += drop_caches.o | ||
52 | 50 | ||
53 | obj-$(CONFIG_FHANDLE) += fhandle.o | 51 | obj-$(CONFIG_FHANDLE) += fhandle.o |
54 | 52 | ||
@@ -1029,9 +1029,9 @@ static int aio_read_evt(struct kioctx *ioctx, struct io_event *ent) | |||
1029 | spin_unlock(&info->ring_lock); | 1029 | spin_unlock(&info->ring_lock); |
1030 | 1030 | ||
1031 | out: | 1031 | out: |
1032 | kunmap_atomic(ring); | ||
1033 | dprintk("leaving aio_read_evt: %d h%lu t%lu\n", ret, | 1032 | dprintk("leaving aio_read_evt: %d h%lu t%lu\n", ret, |
1034 | (unsigned long)ring->head, (unsigned long)ring->tail); | 1033 | (unsigned long)ring->head, (unsigned long)ring->tail); |
1034 | kunmap_atomic(ring); | ||
1035 | return ret; | 1035 | return ret; |
1036 | } | 1036 | } |
1037 | 1037 | ||
@@ -1790,7 +1790,5 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, | |||
1790 | ret = read_events(ioctx, min_nr, nr, events, timeout); | 1790 | ret = read_events(ioctx, min_nr, nr, events, timeout); |
1791 | put_ioctx(ioctx); | 1791 | put_ioctx(ioctx); |
1792 | } | 1792 | } |
1793 | |||
1794 | asmlinkage_protect(5, ret, ctx_id, min_nr, nr, events, timeout); | ||
1795 | return ret; | 1793 | return ret; |
1796 | } | 1794 | } |
diff --git a/fs/befs/btree.c b/fs/befs/btree.c index a66c9b1136e0..74e397db0b8b 100644 --- a/fs/befs/btree.c +++ b/fs/befs/btree.c | |||
@@ -436,8 +436,7 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds, | |||
436 | goto error; | 436 | goto error; |
437 | } | 437 | } |
438 | 438 | ||
439 | if ((this_node = (befs_btree_node *) | 439 | if ((this_node = kmalloc(sizeof (befs_btree_node), GFP_NOFS)) == NULL) { |
440 | kmalloc(sizeof (befs_btree_node), GFP_NOFS)) == NULL) { | ||
441 | befs_error(sb, "befs_btree_read() failed to allocate %u " | 440 | befs_error(sb, "befs_btree_read() failed to allocate %u " |
442 | "bytes of memory", sizeof (befs_btree_node)); | 441 | "bytes of memory", sizeof (befs_btree_node)); |
443 | goto error; | 442 | goto error; |
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index bbc8f8827eac..02fe378fc506 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -62,7 +62,6 @@ static int aout_core_dump(struct coredump_params *cprm) | |||
62 | fs = get_fs(); | 62 | fs = get_fs(); |
63 | set_fs(KERNEL_DS); | 63 | set_fs(KERNEL_DS); |
64 | has_dumped = 1; | 64 | has_dumped = 1; |
65 | current->flags |= PF_DUMPCORE; | ||
66 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); | 65 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); |
67 | dump.u_ar0 = offsetof(struct user, regs); | 66 | dump.u_ar0 = offsetof(struct user, regs); |
68 | dump.signal = cprm->siginfo->si_signo; | 67 | dump.signal = cprm->siginfo->si_signo; |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3939829f6c5c..34a9771eaa6c 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -803,7 +803,8 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
803 | * follow the loader, and is not movable. */ | 803 | * follow the loader, and is not movable. */ |
804 | #ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE | 804 | #ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE |
805 | /* Memory randomization might have been switched off | 805 | /* Memory randomization might have been switched off |
806 | * in runtime via sysctl. | 806 | * in runtime via sysctl or explicit setting of |
807 | * personality flags. | ||
807 | * If that is the case, retain the original non-zero | 808 | * If that is the case, retain the original non-zero |
808 | * load_bias value in order to establish proper | 809 | * load_bias value in order to establish proper |
809 | * non-randomized mappings. | 810 | * non-randomized mappings. |
@@ -1137,6 +1138,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, | |||
1137 | goto whole; | 1138 | goto whole; |
1138 | if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE)) | 1139 | if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE)) |
1139 | goto whole; | 1140 | goto whole; |
1141 | return 0; | ||
1140 | } | 1142 | } |
1141 | 1143 | ||
1142 | /* Do not dump I/O mapped devices or special mappings */ | 1144 | /* Do not dump I/O mapped devices or special mappings */ |
@@ -2090,8 +2092,7 @@ static int elf_core_dump(struct coredump_params *cprm) | |||
2090 | goto cleanup; | 2092 | goto cleanup; |
2091 | 2093 | ||
2092 | has_dumped = 1; | 2094 | has_dumped = 1; |
2093 | current->flags |= PF_DUMPCORE; | 2095 | |
2094 | |||
2095 | fs = get_fs(); | 2096 | fs = get_fs(); |
2096 | set_fs(KERNEL_DS); | 2097 | set_fs(KERNEL_DS); |
2097 | 2098 | ||
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 9c13e023e2b7..c1cc06aed601 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1687,8 +1687,6 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) | |||
1687 | fill_elf_fdpic_header(elf, e_phnum); | 1687 | fill_elf_fdpic_header(elf, e_phnum); |
1688 | 1688 | ||
1689 | has_dumped = 1; | 1689 | has_dumped = 1; |
1690 | current->flags |= PF_DUMPCORE; | ||
1691 | |||
1692 | /* | 1690 | /* |
1693 | * Set up the notes in similar form to SVR4 core dumps made | 1691 | * Set up the notes in similar form to SVR4 core dumps made |
1694 | * with info from their /proc. | 1692 | * with info from their /proc. |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 751df5e4f61a..1c740e152f38 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/binfmts.h> | 23 | #include <linux/binfmts.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/ctype.h> | 25 | #include <linux/ctype.h> |
26 | #include <linux/string_helpers.h> | ||
26 | #include <linux/file.h> | 27 | #include <linux/file.h> |
27 | #include <linux/pagemap.h> | 28 | #include <linux/pagemap.h> |
28 | #include <linux/namei.h> | 29 | #include <linux/namei.h> |
@@ -234,24 +235,6 @@ static char *scanarg(char *s, char del) | |||
234 | return s; | 235 | return s; |
235 | } | 236 | } |
236 | 237 | ||
237 | static int unquote(char *from) | ||
238 | { | ||
239 | char c = 0, *s = from, *p = from; | ||
240 | |||
241 | while ((c = *s++) != '\0') { | ||
242 | if (c == '\\' && *s == 'x') { | ||
243 | s++; | ||
244 | c = toupper(*s++); | ||
245 | *p = (c - (isdigit(c) ? '0' : 'A' - 10)) << 4; | ||
246 | c = toupper(*s++); | ||
247 | *p++ |= c - (isdigit(c) ? '0' : 'A' - 10); | ||
248 | continue; | ||
249 | } | ||
250 | *p++ = c; | ||
251 | } | ||
252 | return p - from; | ||
253 | } | ||
254 | |||
255 | static char * check_special_flags (char * sfs, Node * e) | 238 | static char * check_special_flags (char * sfs, Node * e) |
256 | { | 239 | { |
257 | char * p = sfs; | 240 | char * p = sfs; |
@@ -354,8 +337,9 @@ static Node *create_entry(const char __user *buffer, size_t count) | |||
354 | p[-1] = '\0'; | 337 | p[-1] = '\0'; |
355 | if (!e->mask[0]) | 338 | if (!e->mask[0]) |
356 | e->mask = NULL; | 339 | e->mask = NULL; |
357 | e->size = unquote(e->magic); | 340 | e->size = string_unescape_inplace(e->magic, UNESCAPE_HEX); |
358 | if (e->mask && unquote(e->mask) != e->size) | 341 | if (e->mask && |
342 | string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size) | ||
359 | goto Einval; | 343 | goto Einval; |
360 | if (e->size + e->offset > BINPRM_BUF_SIZE) | 344 | if (e->size + e->offset > BINPRM_BUF_SIZE) |
361 | goto Einval; | 345 | goto Einval; |
@@ -1428,8 +1428,6 @@ void bio_endio(struct bio *bio, int error) | |||
1428 | else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) | 1428 | else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) |
1429 | error = -EIO; | 1429 | error = -EIO; |
1430 | 1430 | ||
1431 | trace_block_bio_complete(bio, error); | ||
1432 | |||
1433 | if (bio->bi_end_io) | 1431 | if (bio->bi_end_io) |
1434 | bio->bi_end_io(bio, error); | 1432 | bio->bi_end_io(bio, error); |
1435 | } | 1433 | } |
diff --git a/fs/block_dev.c b/fs/block_dev.c index aea605c98ba6..ce08de7467a3 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -551,6 +551,7 @@ struct block_device *bdgrab(struct block_device *bdev) | |||
551 | ihold(bdev->bd_inode); | 551 | ihold(bdev->bd_inode); |
552 | return bdev; | 552 | return bdev; |
553 | } | 553 | } |
554 | EXPORT_SYMBOL(bdgrab); | ||
554 | 555 | ||
555 | long nr_blockdev_pages(void) | 556 | long nr_blockdev_pages(void) |
556 | { | 557 | { |
@@ -616,11 +617,9 @@ void bd_forget(struct inode *inode) | |||
616 | struct block_device *bdev = NULL; | 617 | struct block_device *bdev = NULL; |
617 | 618 | ||
618 | spin_lock(&bdev_lock); | 619 | spin_lock(&bdev_lock); |
619 | if (inode->i_bdev) { | 620 | if (!sb_is_blkdev_sb(inode->i_sb)) |
620 | if (!sb_is_blkdev_sb(inode->i_sb)) | 621 | bdev = inode->i_bdev; |
621 | bdev = inode->i_bdev; | 622 | __bd_forget(inode); |
622 | __bd_forget(inode); | ||
623 | } | ||
624 | spin_unlock(&bdev_lock); | 623 | spin_unlock(&bdev_lock); |
625 | 624 | ||
626 | if (bdev) | 625 | if (bdev) |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 451fad96ecd1..ef96381569a4 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -317,6 +317,7 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, | |||
317 | unsigned long src_ptr; | 317 | unsigned long src_ptr; |
318 | unsigned long dst_ptr; | 318 | unsigned long dst_ptr; |
319 | int overwrite_root = 0; | 319 | int overwrite_root = 0; |
320 | bool inode_item = key->type == BTRFS_INODE_ITEM_KEY; | ||
320 | 321 | ||
321 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) | 322 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) |
322 | overwrite_root = 1; | 323 | overwrite_root = 1; |
@@ -326,6 +327,9 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, | |||
326 | 327 | ||
327 | /* look for the key in the destination tree */ | 328 | /* look for the key in the destination tree */ |
328 | ret = btrfs_search_slot(NULL, root, key, path, 0, 0); | 329 | ret = btrfs_search_slot(NULL, root, key, path, 0, 0); |
330 | if (ret < 0) | ||
331 | return ret; | ||
332 | |||
329 | if (ret == 0) { | 333 | if (ret == 0) { |
330 | char *src_copy; | 334 | char *src_copy; |
331 | char *dst_copy; | 335 | char *dst_copy; |
@@ -367,6 +371,30 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, | |||
367 | return 0; | 371 | return 0; |
368 | } | 372 | } |
369 | 373 | ||
374 | /* | ||
375 | * We need to load the old nbytes into the inode so when we | ||
376 | * replay the extents we've logged we get the right nbytes. | ||
377 | */ | ||
378 | if (inode_item) { | ||
379 | struct btrfs_inode_item *item; | ||
380 | u64 nbytes; | ||
381 | |||
382 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | ||
383 | struct btrfs_inode_item); | ||
384 | nbytes = btrfs_inode_nbytes(path->nodes[0], item); | ||
385 | item = btrfs_item_ptr(eb, slot, | ||
386 | struct btrfs_inode_item); | ||
387 | btrfs_set_inode_nbytes(eb, item, nbytes); | ||
388 | } | ||
389 | } else if (inode_item) { | ||
390 | struct btrfs_inode_item *item; | ||
391 | |||
392 | /* | ||
393 | * New inode, set nbytes to 0 so that the nbytes comes out | ||
394 | * properly when we replay the extents. | ||
395 | */ | ||
396 | item = btrfs_item_ptr(eb, slot, struct btrfs_inode_item); | ||
397 | btrfs_set_inode_nbytes(eb, item, 0); | ||
370 | } | 398 | } |
371 | insert: | 399 | insert: |
372 | btrfs_release_path(path); | 400 | btrfs_release_path(path); |
@@ -486,7 +514,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
486 | int found_type; | 514 | int found_type; |
487 | u64 extent_end; | 515 | u64 extent_end; |
488 | u64 start = key->offset; | 516 | u64 start = key->offset; |
489 | u64 saved_nbytes; | 517 | u64 nbytes = 0; |
490 | struct btrfs_file_extent_item *item; | 518 | struct btrfs_file_extent_item *item; |
491 | struct inode *inode = NULL; | 519 | struct inode *inode = NULL; |
492 | unsigned long size; | 520 | unsigned long size; |
@@ -496,10 +524,19 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
496 | found_type = btrfs_file_extent_type(eb, item); | 524 | found_type = btrfs_file_extent_type(eb, item); |
497 | 525 | ||
498 | if (found_type == BTRFS_FILE_EXTENT_REG || | 526 | if (found_type == BTRFS_FILE_EXTENT_REG || |
499 | found_type == BTRFS_FILE_EXTENT_PREALLOC) | 527 | found_type == BTRFS_FILE_EXTENT_PREALLOC) { |
500 | extent_end = start + btrfs_file_extent_num_bytes(eb, item); | 528 | nbytes = btrfs_file_extent_num_bytes(eb, item); |
501 | else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | 529 | extent_end = start + nbytes; |
530 | |||
531 | /* | ||
532 | * We don't add to the inodes nbytes if we are prealloc or a | ||
533 | * hole. | ||
534 | */ | ||
535 | if (btrfs_file_extent_disk_bytenr(eb, item) == 0) | ||
536 | nbytes = 0; | ||
537 | } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { | ||
502 | size = btrfs_file_extent_inline_len(eb, item); | 538 | size = btrfs_file_extent_inline_len(eb, item); |
539 | nbytes = btrfs_file_extent_ram_bytes(eb, item); | ||
503 | extent_end = ALIGN(start + size, root->sectorsize); | 540 | extent_end = ALIGN(start + size, root->sectorsize); |
504 | } else { | 541 | } else { |
505 | ret = 0; | 542 | ret = 0; |
@@ -548,7 +585,6 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
548 | } | 585 | } |
549 | btrfs_release_path(path); | 586 | btrfs_release_path(path); |
550 | 587 | ||
551 | saved_nbytes = inode_get_bytes(inode); | ||
552 | /* drop any overlapping extents */ | 588 | /* drop any overlapping extents */ |
553 | ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1); | 589 | ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1); |
554 | BUG_ON(ret); | 590 | BUG_ON(ret); |
@@ -635,7 +671,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
635 | BUG_ON(ret); | 671 | BUG_ON(ret); |
636 | } | 672 | } |
637 | 673 | ||
638 | inode_set_bytes(inode, saved_nbytes); | 674 | inode_add_bytes(inode, nbytes); |
639 | ret = btrfs_update_inode(trans, root, inode); | 675 | ret = btrfs_update_inode(trans, root, inode); |
640 | out: | 676 | out: |
641 | if (inode) | 677 | if (inode) |
diff --git a/fs/buffer.c b/fs/buffer.c index a15575c0b9ee..bc1fe14aaa3e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -865,8 +865,6 @@ try_again: | |||
865 | 865 | ||
866 | /* Link the buffer to its page */ | 866 | /* Link the buffer to its page */ |
867 | set_bh_page(bh, page, offset); | 867 | set_bh_page(bh, page, offset); |
868 | |||
869 | init_buffer(bh, NULL, NULL); | ||
870 | } | 868 | } |
871 | return head; | 869 | return head; |
872 | /* | 870 | /* |
@@ -2949,7 +2947,7 @@ static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh) | |||
2949 | } | 2947 | } |
2950 | } | 2948 | } |
2951 | 2949 | ||
2952 | int submit_bh(int rw, struct buffer_head * bh) | 2950 | int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags) |
2953 | { | 2951 | { |
2954 | struct bio *bio; | 2952 | struct bio *bio; |
2955 | int ret = 0; | 2953 | int ret = 0; |
@@ -2984,6 +2982,7 @@ int submit_bh(int rw, struct buffer_head * bh) | |||
2984 | 2982 | ||
2985 | bio->bi_end_io = end_bio_bh_io_sync; | 2983 | bio->bi_end_io = end_bio_bh_io_sync; |
2986 | bio->bi_private = bh; | 2984 | bio->bi_private = bh; |
2985 | bio->bi_flags |= bio_flags; | ||
2987 | 2986 | ||
2988 | /* Take care of bh's that straddle the end of the device */ | 2987 | /* Take care of bh's that straddle the end of the device */ |
2989 | guard_bh_eod(rw, bio, bh); | 2988 | guard_bh_eod(rw, bio, bh); |
@@ -3002,6 +3001,12 @@ int submit_bh(int rw, struct buffer_head * bh) | |||
3002 | bio_put(bio); | 3001 | bio_put(bio); |
3003 | return ret; | 3002 | return ret; |
3004 | } | 3003 | } |
3004 | EXPORT_SYMBOL_GPL(_submit_bh); | ||
3005 | |||
3006 | int submit_bh(int rw, struct buffer_head *bh) | ||
3007 | { | ||
3008 | return _submit_bh(rw, bh, 0); | ||
3009 | } | ||
3005 | EXPORT_SYMBOL(submit_bh); | 3010 | EXPORT_SYMBOL(submit_bh); |
3006 | 3011 | ||
3007 | /** | 3012 | /** |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 991c63c6bdd0..21b3a291c327 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1575,14 +1575,24 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1575 | } | 1575 | } |
1576 | break; | 1576 | break; |
1577 | case Opt_blank_pass: | 1577 | case Opt_blank_pass: |
1578 | vol->password = NULL; | ||
1579 | break; | ||
1580 | case Opt_pass: | ||
1581 | /* passwords have to be handled differently | 1578 | /* passwords have to be handled differently |
1582 | * to allow the character used for deliminator | 1579 | * to allow the character used for deliminator |
1583 | * to be passed within them | 1580 | * to be passed within them |
1584 | */ | 1581 | */ |
1585 | 1582 | ||
1583 | /* | ||
1584 | * Check if this is a case where the password | ||
1585 | * starts with a delimiter | ||
1586 | */ | ||
1587 | tmp_end = strchr(data, '='); | ||
1588 | tmp_end++; | ||
1589 | if (!(tmp_end < end && tmp_end[1] == delim)) { | ||
1590 | /* No it is not. Set the password to NULL */ | ||
1591 | vol->password = NULL; | ||
1592 | break; | ||
1593 | } | ||
1594 | /* Yes it is. Drop down to Opt_pass below.*/ | ||
1595 | case Opt_pass: | ||
1586 | /* Obtain the value string */ | 1596 | /* Obtain the value string */ |
1587 | value = strchr(data, '='); | 1597 | value = strchr(data, '='); |
1588 | value++; | 1598 | value++; |
diff --git a/fs/compat.c b/fs/compat.c index d487985dd0ea..5f83ffa42115 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/signal.h> | 44 | #include <linux/signal.h> |
45 | #include <linux/poll.h> | 45 | #include <linux/poll.h> |
46 | #include <linux/mm.h> | 46 | #include <linux/mm.h> |
47 | #include <linux/eventpoll.h> | ||
48 | #include <linux/fs_struct.h> | 47 | #include <linux/fs_struct.h> |
49 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
50 | #include <linux/pagemap.h> | 49 | #include <linux/pagemap.h> |
@@ -1253,26 +1252,6 @@ compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec, | |||
1253 | return compat_sys_pwritev64(fd, vec, vlen, pos); | 1252 | return compat_sys_pwritev64(fd, vec, vlen, pos); |
1254 | } | 1253 | } |
1255 | 1254 | ||
1256 | asmlinkage long | ||
1257 | compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32, | ||
1258 | unsigned int nr_segs, unsigned int flags) | ||
1259 | { | ||
1260 | unsigned i; | ||
1261 | struct iovec __user *iov; | ||
1262 | if (nr_segs > UIO_MAXIOV) | ||
1263 | return -EINVAL; | ||
1264 | iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec)); | ||
1265 | for (i = 0; i < nr_segs; i++) { | ||
1266 | struct compat_iovec v; | ||
1267 | if (get_user(v.iov_base, &iov32[i].iov_base) || | ||
1268 | get_user(v.iov_len, &iov32[i].iov_len) || | ||
1269 | put_user(compat_ptr(v.iov_base), &iov[i].iov_base) || | ||
1270 | put_user(v.iov_len, &iov[i].iov_len)) | ||
1271 | return -EFAULT; | ||
1272 | } | ||
1273 | return sys_vmsplice(fd, iov, nr_segs, flags); | ||
1274 | } | ||
1275 | |||
1276 | /* | 1255 | /* |
1277 | * Exactly like fs/open.c:sys_open(), except that it doesn't set the | 1256 | * Exactly like fs/open.c:sys_open(), except that it doesn't set the |
1278 | * O_LARGEFILE flag. | 1257 | * O_LARGEFILE flag. |
@@ -1658,84 +1637,6 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | |||
1658 | return ret; | 1637 | return ret; |
1659 | } | 1638 | } |
1660 | 1639 | ||
1661 | #ifdef CONFIG_EPOLL | ||
1662 | |||
1663 | asmlinkage long compat_sys_epoll_pwait(int epfd, | ||
1664 | struct compat_epoll_event __user *events, | ||
1665 | int maxevents, int timeout, | ||
1666 | const compat_sigset_t __user *sigmask, | ||
1667 | compat_size_t sigsetsize) | ||
1668 | { | ||
1669 | long err; | ||
1670 | compat_sigset_t csigmask; | ||
1671 | sigset_t ksigmask, sigsaved; | ||
1672 | |||
1673 | /* | ||
1674 | * If the caller wants a certain signal mask to be set during the wait, | ||
1675 | * we apply it here. | ||
1676 | */ | ||
1677 | if (sigmask) { | ||
1678 | if (sigsetsize != sizeof(compat_sigset_t)) | ||
1679 | return -EINVAL; | ||
1680 | if (copy_from_user(&csigmask, sigmask, sizeof(csigmask))) | ||
1681 | return -EFAULT; | ||
1682 | sigset_from_compat(&ksigmask, &csigmask); | ||
1683 | sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); | ||
1684 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | ||
1685 | } | ||
1686 | |||
1687 | err = sys_epoll_wait(epfd, events, maxevents, timeout); | ||
1688 | |||
1689 | /* | ||
1690 | * If we changed the signal mask, we need to restore the original one. | ||
1691 | * In case we've got a signal while waiting, we do not restore the | ||
1692 | * signal mask yet, and we allow do_signal() to deliver the signal on | ||
1693 | * the way back to userspace, before the signal mask is restored. | ||
1694 | */ | ||
1695 | if (sigmask) { | ||
1696 | if (err == -EINTR) { | ||
1697 | memcpy(¤t->saved_sigmask, &sigsaved, | ||
1698 | sizeof(sigsaved)); | ||
1699 | set_restore_sigmask(); | ||
1700 | } else | ||
1701 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | ||
1702 | } | ||
1703 | |||
1704 | return err; | ||
1705 | } | ||
1706 | |||
1707 | #endif /* CONFIG_EPOLL */ | ||
1708 | |||
1709 | #ifdef CONFIG_SIGNALFD | ||
1710 | |||
1711 | asmlinkage long compat_sys_signalfd4(int ufd, | ||
1712 | const compat_sigset_t __user *sigmask, | ||
1713 | compat_size_t sigsetsize, int flags) | ||
1714 | { | ||
1715 | compat_sigset_t ss32; | ||
1716 | sigset_t tmp; | ||
1717 | sigset_t __user *ksigmask; | ||
1718 | |||
1719 | if (sigsetsize != sizeof(compat_sigset_t)) | ||
1720 | return -EINVAL; | ||
1721 | if (copy_from_user(&ss32, sigmask, sizeof(ss32))) | ||
1722 | return -EFAULT; | ||
1723 | sigset_from_compat(&tmp, &ss32); | ||
1724 | ksigmask = compat_alloc_user_space(sizeof(sigset_t)); | ||
1725 | if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t))) | ||
1726 | return -EFAULT; | ||
1727 | |||
1728 | return sys_signalfd4(ufd, ksigmask, sizeof(sigset_t), flags); | ||
1729 | } | ||
1730 | |||
1731 | asmlinkage long compat_sys_signalfd(int ufd, | ||
1732 | const compat_sigset_t __user *sigmask, | ||
1733 | compat_size_t sigsetsize) | ||
1734 | { | ||
1735 | return compat_sys_signalfd4(ufd, sigmask, sigsetsize, 0); | ||
1736 | } | ||
1737 | #endif /* CONFIG_SIGNALFD */ | ||
1738 | |||
1739 | #ifdef CONFIG_FHANDLE | 1640 | #ifdef CONFIG_FHANDLE |
1740 | /* | 1641 | /* |
1741 | * Exactly like fs/open.c:sys_open_by_handle_at(), except that it | 1642 | * Exactly like fs/open.c:sys_open_by_handle_at(), except that it |
@@ -1747,25 +1648,3 @@ COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd, | |||
1747 | return do_handle_open(mountdirfd, handle, flags); | 1648 | return do_handle_open(mountdirfd, handle, flags); |
1748 | } | 1649 | } |
1749 | #endif | 1650 | #endif |
1750 | |||
1751 | #ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE | ||
1752 | asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, | ||
1753 | compat_off_t __user *offset, compat_size_t count) | ||
1754 | { | ||
1755 | loff_t pos; | ||
1756 | off_t off; | ||
1757 | ssize_t ret; | ||
1758 | |||
1759 | if (offset) { | ||
1760 | if (unlikely(get_user(off, offset))) | ||
1761 | return -EFAULT; | ||
1762 | pos = off; | ||
1763 | ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS); | ||
1764 | if (unlikely(put_user(pos, offset))) | ||
1765 | return -EFAULT; | ||
1766 | return ret; | ||
1767 | } | ||
1768 | |||
1769 | return do_sendfile(out_fd, in_fd, NULL, count, 0); | ||
1770 | } | ||
1771 | #endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */ | ||
diff --git a/fs/coredump.c b/fs/coredump.c index c6479658d487..ec306cc9a28a 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -263,7 +263,6 @@ static int zap_process(struct task_struct *start, int exit_code) | |||
263 | struct task_struct *t; | 263 | struct task_struct *t; |
264 | int nr = 0; | 264 | int nr = 0; |
265 | 265 | ||
266 | start->signal->flags = SIGNAL_GROUP_EXIT; | ||
267 | start->signal->group_exit_code = exit_code; | 266 | start->signal->group_exit_code = exit_code; |
268 | start->signal->group_stop_count = 0; | 267 | start->signal->group_stop_count = 0; |
269 | 268 | ||
@@ -280,8 +279,8 @@ static int zap_process(struct task_struct *start, int exit_code) | |||
280 | return nr; | 279 | return nr; |
281 | } | 280 | } |
282 | 281 | ||
283 | static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | 282 | static int zap_threads(struct task_struct *tsk, struct mm_struct *mm, |
284 | struct core_state *core_state, int exit_code) | 283 | struct core_state *core_state, int exit_code) |
285 | { | 284 | { |
286 | struct task_struct *g, *p; | 285 | struct task_struct *g, *p; |
287 | unsigned long flags; | 286 | unsigned long flags; |
@@ -291,11 +290,16 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | |||
291 | if (!signal_group_exit(tsk->signal)) { | 290 | if (!signal_group_exit(tsk->signal)) { |
292 | mm->core_state = core_state; | 291 | mm->core_state = core_state; |
293 | nr = zap_process(tsk, exit_code); | 292 | nr = zap_process(tsk, exit_code); |
293 | tsk->signal->group_exit_task = tsk; | ||
294 | /* ignore all signals except SIGKILL, see prepare_signal() */ | ||
295 | tsk->signal->flags = SIGNAL_GROUP_COREDUMP; | ||
296 | clear_tsk_thread_flag(tsk, TIF_SIGPENDING); | ||
294 | } | 297 | } |
295 | spin_unlock_irq(&tsk->sighand->siglock); | 298 | spin_unlock_irq(&tsk->sighand->siglock); |
296 | if (unlikely(nr < 0)) | 299 | if (unlikely(nr < 0)) |
297 | return nr; | 300 | return nr; |
298 | 301 | ||
302 | tsk->flags = PF_DUMPCORE; | ||
299 | if (atomic_read(&mm->mm_users) == nr + 1) | 303 | if (atomic_read(&mm->mm_users) == nr + 1) |
300 | goto done; | 304 | goto done; |
301 | /* | 305 | /* |
@@ -340,6 +344,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | |||
340 | if (unlikely(p->mm == mm)) { | 344 | if (unlikely(p->mm == mm)) { |
341 | lock_task_sighand(p, &flags); | 345 | lock_task_sighand(p, &flags); |
342 | nr += zap_process(p, exit_code); | 346 | nr += zap_process(p, exit_code); |
347 | p->signal->flags = SIGNAL_GROUP_EXIT; | ||
343 | unlock_task_sighand(p, &flags); | 348 | unlock_task_sighand(p, &flags); |
344 | } | 349 | } |
345 | break; | 350 | break; |
@@ -386,11 +391,18 @@ static int coredump_wait(int exit_code, struct core_state *core_state) | |||
386 | return core_waiters; | 391 | return core_waiters; |
387 | } | 392 | } |
388 | 393 | ||
389 | static void coredump_finish(struct mm_struct *mm) | 394 | static void coredump_finish(struct mm_struct *mm, bool core_dumped) |
390 | { | 395 | { |
391 | struct core_thread *curr, *next; | 396 | struct core_thread *curr, *next; |
392 | struct task_struct *task; | 397 | struct task_struct *task; |
393 | 398 | ||
399 | spin_lock_irq(¤t->sighand->siglock); | ||
400 | if (core_dumped && !__fatal_signal_pending(current)) | ||
401 | current->signal->group_exit_code |= 0x80; | ||
402 | current->signal->group_exit_task = NULL; | ||
403 | current->signal->flags = SIGNAL_GROUP_EXIT; | ||
404 | spin_unlock_irq(¤t->sighand->siglock); | ||
405 | |||
394 | next = mm->core_state->dumper.next; | 406 | next = mm->core_state->dumper.next; |
395 | while ((curr = next) != NULL) { | 407 | while ((curr = next) != NULL) { |
396 | next = curr->next; | 408 | next = curr->next; |
@@ -407,6 +419,17 @@ static void coredump_finish(struct mm_struct *mm) | |||
407 | mm->core_state = NULL; | 419 | mm->core_state = NULL; |
408 | } | 420 | } |
409 | 421 | ||
422 | static bool dump_interrupted(void) | ||
423 | { | ||
424 | /* | ||
425 | * SIGKILL or freezing() interrupt the coredumping. Perhaps we | ||
426 | * can do try_to_freeze() and check __fatal_signal_pending(), | ||
427 | * but then we need to teach dump_write() to restart and clear | ||
428 | * TIF_SIGPENDING. | ||
429 | */ | ||
430 | return signal_pending(current); | ||
431 | } | ||
432 | |||
410 | static void wait_for_dump_helpers(struct file *file) | 433 | static void wait_for_dump_helpers(struct file *file) |
411 | { | 434 | { |
412 | struct pipe_inode_info *pipe; | 435 | struct pipe_inode_info *pipe; |
@@ -416,17 +439,20 @@ static void wait_for_dump_helpers(struct file *file) | |||
416 | pipe_lock(pipe); | 439 | pipe_lock(pipe); |
417 | pipe->readers++; | 440 | pipe->readers++; |
418 | pipe->writers--; | 441 | pipe->writers--; |
442 | wake_up_interruptible_sync(&pipe->wait); | ||
443 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | ||
444 | pipe_unlock(pipe); | ||
419 | 445 | ||
420 | while ((pipe->readers > 1) && (!signal_pending(current))) { | 446 | /* |
421 | wake_up_interruptible_sync(&pipe->wait); | 447 | * We actually want wait_event_freezable() but then we need |
422 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 448 | * to clear TIF_SIGPENDING and improve dump_interrupted(). |
423 | pipe_wait(pipe); | 449 | */ |
424 | } | 450 | wait_event_interruptible(pipe->wait, pipe->readers == 1); |
425 | 451 | ||
452 | pipe_lock(pipe); | ||
426 | pipe->readers--; | 453 | pipe->readers--; |
427 | pipe->writers++; | 454 | pipe->writers++; |
428 | pipe_unlock(pipe); | 455 | pipe_unlock(pipe); |
429 | |||
430 | } | 456 | } |
431 | 457 | ||
432 | /* | 458 | /* |
@@ -471,6 +497,7 @@ void do_coredump(siginfo_t *siginfo) | |||
471 | int ispipe; | 497 | int ispipe; |
472 | struct files_struct *displaced; | 498 | struct files_struct *displaced; |
473 | bool need_nonrelative = false; | 499 | bool need_nonrelative = false; |
500 | bool core_dumped = false; | ||
474 | static atomic_t core_dump_count = ATOMIC_INIT(0); | 501 | static atomic_t core_dump_count = ATOMIC_INIT(0); |
475 | struct coredump_params cprm = { | 502 | struct coredump_params cprm = { |
476 | .siginfo = siginfo, | 503 | .siginfo = siginfo, |
@@ -514,17 +541,12 @@ void do_coredump(siginfo_t *siginfo) | |||
514 | 541 | ||
515 | old_cred = override_creds(cred); | 542 | old_cred = override_creds(cred); |
516 | 543 | ||
517 | /* | ||
518 | * Clear any false indication of pending signals that might | ||
519 | * be seen by the filesystem code called to write the core file. | ||
520 | */ | ||
521 | clear_thread_flag(TIF_SIGPENDING); | ||
522 | |||
523 | ispipe = format_corename(&cn, &cprm); | 544 | ispipe = format_corename(&cn, &cprm); |
524 | 545 | ||
525 | if (ispipe) { | 546 | if (ispipe) { |
526 | int dump_count; | 547 | int dump_count; |
527 | char **helper_argv; | 548 | char **helper_argv; |
549 | struct subprocess_info *sub_info; | ||
528 | 550 | ||
529 | if (ispipe < 0) { | 551 | if (ispipe < 0) { |
530 | printk(KERN_WARNING "format_corename failed\n"); | 552 | printk(KERN_WARNING "format_corename failed\n"); |
@@ -571,15 +593,20 @@ void do_coredump(siginfo_t *siginfo) | |||
571 | goto fail_dropcount; | 593 | goto fail_dropcount; |
572 | } | 594 | } |
573 | 595 | ||
574 | retval = call_usermodehelper_fns(helper_argv[0], helper_argv, | 596 | retval = -ENOMEM; |
575 | NULL, UMH_WAIT_EXEC, umh_pipe_setup, | 597 | sub_info = call_usermodehelper_setup(helper_argv[0], |
576 | NULL, &cprm); | 598 | helper_argv, NULL, GFP_KERNEL, |
599 | umh_pipe_setup, NULL, &cprm); | ||
600 | if (sub_info) | ||
601 | retval = call_usermodehelper_exec(sub_info, | ||
602 | UMH_WAIT_EXEC); | ||
603 | |||
577 | argv_free(helper_argv); | 604 | argv_free(helper_argv); |
578 | if (retval) { | 605 | if (retval) { |
579 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 606 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
580 | cn.corename); | 607 | cn.corename); |
581 | goto close_fail; | 608 | goto close_fail; |
582 | } | 609 | } |
583 | } else { | 610 | } else { |
584 | struct inode *inode; | 611 | struct inode *inode; |
585 | 612 | ||
@@ -629,9 +656,7 @@ void do_coredump(siginfo_t *siginfo) | |||
629 | goto close_fail; | 656 | goto close_fail; |
630 | if (displaced) | 657 | if (displaced) |
631 | put_files_struct(displaced); | 658 | put_files_struct(displaced); |
632 | retval = binfmt->core_dump(&cprm); | 659 | core_dumped = !dump_interrupted() && binfmt->core_dump(&cprm); |
633 | if (retval) | ||
634 | current->signal->group_exit_code |= 0x80; | ||
635 | 660 | ||
636 | if (ispipe && core_pipe_limit) | 661 | if (ispipe && core_pipe_limit) |
637 | wait_for_dump_helpers(cprm.file); | 662 | wait_for_dump_helpers(cprm.file); |
@@ -644,7 +669,7 @@ fail_dropcount: | |||
644 | fail_unlock: | 669 | fail_unlock: |
645 | kfree(cn.corename); | 670 | kfree(cn.corename); |
646 | fail_corename: | 671 | fail_corename: |
647 | coredump_finish(mm); | 672 | coredump_finish(mm, core_dumped); |
648 | revert_creds(old_cred); | 673 | revert_creds(old_cred); |
649 | fail_creds: | 674 | fail_creds: |
650 | put_cred(cred); | 675 | put_cred(cred); |
@@ -659,7 +684,9 @@ fail: | |||
659 | */ | 684 | */ |
660 | int dump_write(struct file *file, const void *addr, int nr) | 685 | int dump_write(struct file *file, const void *addr, int nr) |
661 | { | 686 | { |
662 | return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr; | 687 | return !dump_interrupted() && |
688 | access_ok(VERIFY_READ, addr, nr) && | ||
689 | file->f_op->write(file, addr, nr, &file->f_pos) == nr; | ||
663 | } | 690 | } |
664 | EXPORT_SYMBOL(dump_write); | 691 | EXPORT_SYMBOL(dump_write); |
665 | 692 | ||
@@ -668,7 +695,8 @@ int dump_seek(struct file *file, loff_t off) | |||
668 | int ret = 1; | 695 | int ret = 1; |
669 | 696 | ||
670 | if (file->f_op->llseek && file->f_op->llseek != no_llseek) { | 697 | if (file->f_op->llseek && file->f_op->llseek != no_llseek) { |
671 | if (file->f_op->llseek(file, off, SEEK_CUR) < 0) | 698 | if (dump_interrupted() || |
699 | file->f_op->llseek(file, off, SEEK_CUR) < 0) | ||
672 | return 0; | 700 | return 0; |
673 | } else { | 701 | } else { |
674 | char *buf = (char *)get_zeroed_page(GFP_KERNEL); | 702 | char *buf = (char *)get_zeroed_page(GFP_KERNEL); |
diff --git a/fs/dcache.c b/fs/dcache.c index e8bc3420d63e..e689268046c3 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1230,8 +1230,10 @@ void shrink_dcache_parent(struct dentry * parent) | |||
1230 | LIST_HEAD(dispose); | 1230 | LIST_HEAD(dispose); |
1231 | int found; | 1231 | int found; |
1232 | 1232 | ||
1233 | while ((found = select_parent(parent, &dispose)) != 0) | 1233 | while ((found = select_parent(parent, &dispose)) != 0) { |
1234 | shrink_dentry_list(&dispose); | 1234 | shrink_dentry_list(&dispose); |
1235 | cond_resched(); | ||
1236 | } | ||
1235 | } | 1237 | } |
1236 | EXPORT_SYMBOL(shrink_dcache_parent); | 1238 | EXPORT_SYMBOL(shrink_dcache_parent); |
1237 | 1239 | ||
diff --git a/fs/dcookies.c b/fs/dcookies.c index 17c779967828..ab5954b50267 100644 --- a/fs/dcookies.c +++ b/fs/dcookies.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/dcookies.h> | 25 | #include <linux/dcookies.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/path.h> | 27 | #include <linux/path.h> |
28 | #include <linux/compat.h> | ||
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | 30 | ||
30 | /* The dcookies are allocated from a kmem_cache and | 31 | /* The dcookies are allocated from a kmem_cache and |
@@ -145,7 +146,7 @@ out: | |||
145 | /* And here is where the userspace process can look up the cookie value | 146 | /* And here is where the userspace process can look up the cookie value |
146 | * to retrieve the path. | 147 | * to retrieve the path. |
147 | */ | 148 | */ |
148 | SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) | 149 | SYSCALL_DEFINE3(lookup_dcookie, u64, cookie64, char __user *, buf, size_t, len) |
149 | { | 150 | { |
150 | unsigned long cookie = (unsigned long)cookie64; | 151 | unsigned long cookie = (unsigned long)cookie64; |
151 | int err = -EINVAL; | 152 | int err = -EINVAL; |
@@ -201,12 +202,16 @@ out: | |||
201 | mutex_unlock(&dcookie_mutex); | 202 | mutex_unlock(&dcookie_mutex); |
202 | return err; | 203 | return err; |
203 | } | 204 | } |
204 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | 205 | |
205 | asmlinkage long SyS_lookup_dcookie(u64 cookie64, long buf, long len) | 206 | #ifdef CONFIG_COMPAT |
207 | COMPAT_SYSCALL_DEFINE4(lookup_dcookie, u32, w0, u32, w1, char __user *, buf, size_t, len) | ||
206 | { | 208 | { |
207 | return SYSC_lookup_dcookie(cookie64, (char __user *) buf, (size_t) len); | 209 | #ifdef __BIG_ENDIAN |
210 | return sys_lookup_dcookie(((u64)w0 << 32) | w1, buf, len); | ||
211 | #else | ||
212 | return sys_lookup_dcookie(((u64)w1 << 32) | w0, buf, len); | ||
213 | #endif | ||
208 | } | 214 | } |
209 | SYSCALL_ALIAS(sys_lookup_dcookie, SyS_lookup_dcookie); | ||
210 | #endif | 215 | #endif |
211 | 216 | ||
212 | static int dcookie_init(void) | 217 | static int dcookie_init(void) |
diff --git a/fs/direct-io.c b/fs/direct-io.c index f853263cf74f..cfb816dc6d9f 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -672,12 +672,6 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio, | |||
672 | if (sdio->final_block_in_bio != sdio->cur_page_block || | 672 | if (sdio->final_block_in_bio != sdio->cur_page_block || |
673 | cur_offset != bio_next_offset) | 673 | cur_offset != bio_next_offset) |
674 | dio_bio_submit(dio, sdio); | 674 | dio_bio_submit(dio, sdio); |
675 | /* | ||
676 | * Submit now if the underlying fs is about to perform a | ||
677 | * metadata read | ||
678 | */ | ||
679 | else if (sdio->boundary) | ||
680 | dio_bio_submit(dio, sdio); | ||
681 | } | 675 | } |
682 | 676 | ||
683 | if (sdio->bio == NULL) { | 677 | if (sdio->bio == NULL) { |
@@ -737,16 +731,6 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page, | |||
737 | sdio->cur_page_block + | 731 | sdio->cur_page_block + |
738 | (sdio->cur_page_len >> sdio->blkbits) == blocknr) { | 732 | (sdio->cur_page_len >> sdio->blkbits) == blocknr) { |
739 | sdio->cur_page_len += len; | 733 | sdio->cur_page_len += len; |
740 | |||
741 | /* | ||
742 | * If sdio->boundary then we want to schedule the IO now to | ||
743 | * avoid metadata seeks. | ||
744 | */ | ||
745 | if (sdio->boundary) { | ||
746 | ret = dio_send_cur_page(dio, sdio, map_bh); | ||
747 | page_cache_release(sdio->cur_page); | ||
748 | sdio->cur_page = NULL; | ||
749 | } | ||
750 | goto out; | 734 | goto out; |
751 | } | 735 | } |
752 | 736 | ||
@@ -758,7 +742,7 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page, | |||
758 | page_cache_release(sdio->cur_page); | 742 | page_cache_release(sdio->cur_page); |
759 | sdio->cur_page = NULL; | 743 | sdio->cur_page = NULL; |
760 | if (ret) | 744 | if (ret) |
761 | goto out; | 745 | return ret; |
762 | } | 746 | } |
763 | 747 | ||
764 | page_cache_get(page); /* It is in dio */ | 748 | page_cache_get(page); /* It is in dio */ |
@@ -768,6 +752,16 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page, | |||
768 | sdio->cur_page_block = blocknr; | 752 | sdio->cur_page_block = blocknr; |
769 | sdio->cur_page_fs_offset = sdio->block_in_file << sdio->blkbits; | 753 | sdio->cur_page_fs_offset = sdio->block_in_file << sdio->blkbits; |
770 | out: | 754 | out: |
755 | /* | ||
756 | * If sdio->boundary then we want to schedule the IO now to | ||
757 | * avoid metadata seeks. | ||
758 | */ | ||
759 | if (sdio->boundary) { | ||
760 | ret = dio_send_cur_page(dio, sdio, map_bh); | ||
761 | dio_bio_submit(dio, sdio); | ||
762 | page_cache_release(sdio->cur_page); | ||
763 | sdio->cur_page = NULL; | ||
764 | } | ||
771 | return ret; | 765 | return ret; |
772 | } | 766 | } |
773 | 767 | ||
@@ -969,7 +963,8 @@ do_holes: | |||
969 | this_chunk_bytes = this_chunk_blocks << blkbits; | 963 | this_chunk_bytes = this_chunk_blocks << blkbits; |
970 | BUG_ON(this_chunk_bytes == 0); | 964 | BUG_ON(this_chunk_bytes == 0); |
971 | 965 | ||
972 | sdio->boundary = buffer_boundary(map_bh); | 966 | if (this_chunk_blocks == sdio->blocks_available) |
967 | sdio->boundary = buffer_boundary(map_bh); | ||
973 | ret = submit_page_section(dio, sdio, page, | 968 | ret = submit_page_section(dio, sdio, page, |
974 | offset_in_page, | 969 | offset_in_page, |
975 | this_chunk_bytes, | 970 | this_chunk_bytes, |
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 01fd5c11a7fb..f704458ea5f5 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c | |||
@@ -247,6 +247,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, | |||
247 | struct dlm_ls *ls; | 247 | struct dlm_ls *ls; |
248 | struct plock_op *op; | 248 | struct plock_op *op; |
249 | int rv; | 249 | int rv; |
250 | unsigned char fl_flags = fl->fl_flags; | ||
250 | 251 | ||
251 | ls = dlm_find_lockspace_local(lockspace); | 252 | ls = dlm_find_lockspace_local(lockspace); |
252 | if (!ls) | 253 | if (!ls) |
@@ -258,9 +259,18 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, | |||
258 | goto out; | 259 | goto out; |
259 | } | 260 | } |
260 | 261 | ||
261 | if (posix_lock_file_wait(file, fl) < 0) | 262 | /* cause the vfs unlock to return ENOENT if lock is not found */ |
262 | log_error(ls, "dlm_posix_unlock: vfs unlock error %llx", | 263 | fl->fl_flags |= FL_EXISTS; |
263 | (unsigned long long)number); | 264 | |
265 | rv = posix_lock_file_wait(file, fl); | ||
266 | if (rv == -ENOENT) { | ||
267 | rv = 0; | ||
268 | goto out_free; | ||
269 | } | ||
270 | if (rv < 0) { | ||
271 | log_error(ls, "dlm_posix_unlock: vfs unlock error %d %llx", | ||
272 | rv, (unsigned long long)number); | ||
273 | } | ||
264 | 274 | ||
265 | op->info.optype = DLM_PLOCK_OP_UNLOCK; | 275 | op->info.optype = DLM_PLOCK_OP_UNLOCK; |
266 | op->info.pid = fl->fl_pid; | 276 | op->info.pid = fl->fl_pid; |
@@ -296,9 +306,11 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, | |||
296 | if (rv == -ENOENT) | 306 | if (rv == -ENOENT) |
297 | rv = 0; | 307 | rv = 0; |
298 | 308 | ||
309 | out_free: | ||
299 | kfree(op); | 310 | kfree(op); |
300 | out: | 311 | out: |
301 | dlm_put_lockspace(ls); | 312 | dlm_put_lockspace(ls); |
313 | fl->fl_flags = fl_flags; | ||
302 | return rv; | 314 | return rv; |
303 | } | 315 | } |
304 | EXPORT_SYMBOL_GPL(dlm_posix_unlock); | 316 | EXPORT_SYMBOL_GPL(dlm_posix_unlock); |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 412e6eda25f8..e4141f257495 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -80,13 +80,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
80 | int rc; | 80 | int rc; |
81 | 81 | ||
82 | mutex_lock(&ecryptfs_daemon_hash_mux); | 82 | mutex_lock(&ecryptfs_daemon_hash_mux); |
83 | rc = try_module_get(THIS_MODULE); | ||
84 | if (rc == 0) { | ||
85 | rc = -EIO; | ||
86 | printk(KERN_ERR "%s: Error attempting to increment module use " | ||
87 | "count; rc = [%d]\n", __func__, rc); | ||
88 | goto out_unlock_daemon_list; | ||
89 | } | ||
90 | rc = ecryptfs_find_daemon_by_euid(&daemon); | 83 | rc = ecryptfs_find_daemon_by_euid(&daemon); |
91 | if (!rc) { | 84 | if (!rc) { |
92 | rc = -EINVAL; | 85 | rc = -EINVAL; |
@@ -96,7 +89,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
96 | if (rc) { | 89 | if (rc) { |
97 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " | 90 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " |
98 | "rc = [%d]\n", __func__, rc); | 91 | "rc = [%d]\n", __func__, rc); |
99 | goto out_module_put_unlock_daemon_list; | 92 | goto out_unlock_daemon_list; |
100 | } | 93 | } |
101 | mutex_lock(&daemon->mux); | 94 | mutex_lock(&daemon->mux); |
102 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { | 95 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { |
@@ -108,9 +101,6 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
108 | atomic_inc(&ecryptfs_num_miscdev_opens); | 101 | atomic_inc(&ecryptfs_num_miscdev_opens); |
109 | out_unlock_daemon: | 102 | out_unlock_daemon: |
110 | mutex_unlock(&daemon->mux); | 103 | mutex_unlock(&daemon->mux); |
111 | out_module_put_unlock_daemon_list: | ||
112 | if (rc) | ||
113 | module_put(THIS_MODULE); | ||
114 | out_unlock_daemon_list: | 104 | out_unlock_daemon_list: |
115 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 105 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
116 | return rc; | 106 | return rc; |
@@ -147,7 +137,6 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) | |||
147 | "bug.\n", __func__, rc); | 137 | "bug.\n", __func__, rc); |
148 | BUG(); | 138 | BUG(); |
149 | } | 139 | } |
150 | module_put(THIS_MODULE); | ||
151 | return rc; | 140 | return rc; |
152 | } | 141 | } |
153 | 142 | ||
@@ -471,6 +460,7 @@ out_free: | |||
471 | 460 | ||
472 | 461 | ||
473 | static const struct file_operations ecryptfs_miscdev_fops = { | 462 | static const struct file_operations ecryptfs_miscdev_fops = { |
463 | .owner = THIS_MODULE, | ||
474 | .open = ecryptfs_miscdev_open, | 464 | .open = ecryptfs_miscdev_open, |
475 | .poll = ecryptfs_miscdev_poll, | 465 | .poll = ecryptfs_miscdev_poll, |
476 | .read = ecryptfs_miscdev_read, | 466 | .read = ecryptfs_miscdev_read, |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 9fec1836057a..deecc7294a67 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/atomic.h> | 40 | #include <linux/atomic.h> |
41 | #include <linux/proc_fs.h> | 41 | #include <linux/proc_fs.h> |
42 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
43 | #include <linux/compat.h> | ||
43 | 44 | ||
44 | /* | 45 | /* |
45 | * LOCKING: | 46 | * LOCKING: |
@@ -104,7 +105,7 @@ | |||
104 | struct epoll_filefd { | 105 | struct epoll_filefd { |
105 | struct file *file; | 106 | struct file *file; |
106 | int fd; | 107 | int fd; |
107 | }; | 108 | } __packed; |
108 | 109 | ||
109 | /* | 110 | /* |
110 | * Structure used to track possible nested calls, for too deep recursions | 111 | * Structure used to track possible nested calls, for too deep recursions |
@@ -128,6 +129,8 @@ struct nested_calls { | |||
128 | /* | 129 | /* |
129 | * Each file descriptor added to the eventpoll interface will | 130 | * Each file descriptor added to the eventpoll interface will |
130 | * have an entry of this type linked to the "rbr" RB tree. | 131 | * have an entry of this type linked to the "rbr" RB tree. |
132 | * Avoid increasing the size of this struct, there can be many thousands | ||
133 | * of these on a server and we do not want this to take another cache line. | ||
131 | */ | 134 | */ |
132 | struct epitem { | 135 | struct epitem { |
133 | /* RB tree node used to link this structure to the eventpoll RB tree */ | 136 | /* RB tree node used to link this structure to the eventpoll RB tree */ |
@@ -158,7 +161,7 @@ struct epitem { | |||
158 | struct list_head fllink; | 161 | struct list_head fllink; |
159 | 162 | ||
160 | /* wakeup_source used when EPOLLWAKEUP is set */ | 163 | /* wakeup_source used when EPOLLWAKEUP is set */ |
161 | struct wakeup_source *ws; | 164 | struct wakeup_source __rcu *ws; |
162 | 165 | ||
163 | /* The structure that describe the interested events and the source fd */ | 166 | /* The structure that describe the interested events and the source fd */ |
164 | struct epoll_event event; | 167 | struct epoll_event event; |
@@ -536,6 +539,38 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi) | |||
536 | } | 539 | } |
537 | } | 540 | } |
538 | 541 | ||
542 | /* call only when ep->mtx is held */ | ||
543 | static inline struct wakeup_source *ep_wakeup_source(struct epitem *epi) | ||
544 | { | ||
545 | return rcu_dereference_check(epi->ws, lockdep_is_held(&epi->ep->mtx)); | ||
546 | } | ||
547 | |||
548 | /* call only when ep->mtx is held */ | ||
549 | static inline void ep_pm_stay_awake(struct epitem *epi) | ||
550 | { | ||
551 | struct wakeup_source *ws = ep_wakeup_source(epi); | ||
552 | |||
553 | if (ws) | ||
554 | __pm_stay_awake(ws); | ||
555 | } | ||
556 | |||
557 | static inline bool ep_has_wakeup_source(struct epitem *epi) | ||
558 | { | ||
559 | return rcu_access_pointer(epi->ws) ? true : false; | ||
560 | } | ||
561 | |||
562 | /* call when ep->mtx cannot be held (ep_poll_callback) */ | ||
563 | static inline void ep_pm_stay_awake_rcu(struct epitem *epi) | ||
564 | { | ||
565 | struct wakeup_source *ws; | ||
566 | |||
567 | rcu_read_lock(); | ||
568 | ws = rcu_dereference(epi->ws); | ||
569 | if (ws) | ||
570 | __pm_stay_awake(ws); | ||
571 | rcu_read_unlock(); | ||
572 | } | ||
573 | |||
539 | /** | 574 | /** |
540 | * ep_scan_ready_list - Scans the ready list in a way that makes possible for | 575 | * ep_scan_ready_list - Scans the ready list in a way that makes possible for |
541 | * the scan code, to call f_op->poll(). Also allows for | 576 | * the scan code, to call f_op->poll(). Also allows for |
@@ -599,7 +634,7 @@ static int ep_scan_ready_list(struct eventpoll *ep, | |||
599 | */ | 634 | */ |
600 | if (!ep_is_linked(&epi->rdllink)) { | 635 | if (!ep_is_linked(&epi->rdllink)) { |
601 | list_add_tail(&epi->rdllink, &ep->rdllist); | 636 | list_add_tail(&epi->rdllink, &ep->rdllist); |
602 | __pm_stay_awake(epi->ws); | 637 | ep_pm_stay_awake(epi); |
603 | } | 638 | } |
604 | } | 639 | } |
605 | /* | 640 | /* |
@@ -668,7 +703,7 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) | |||
668 | list_del_init(&epi->rdllink); | 703 | list_del_init(&epi->rdllink); |
669 | spin_unlock_irqrestore(&ep->lock, flags); | 704 | spin_unlock_irqrestore(&ep->lock, flags); |
670 | 705 | ||
671 | wakeup_source_unregister(epi->ws); | 706 | wakeup_source_unregister(ep_wakeup_source(epi)); |
672 | 707 | ||
673 | /* At this point it is safe to free the eventpoll item */ | 708 | /* At this point it is safe to free the eventpoll item */ |
674 | kmem_cache_free(epi_cache, epi); | 709 | kmem_cache_free(epi_cache, epi); |
@@ -711,11 +746,15 @@ static void ep_free(struct eventpoll *ep) | |||
711 | * point we are sure no poll callbacks will be lingering around, and also by | 746 | * point we are sure no poll callbacks will be lingering around, and also by |
712 | * holding "epmutex" we can be sure that no file cleanup code will hit | 747 | * holding "epmutex" we can be sure that no file cleanup code will hit |
713 | * us during this operation. So we can avoid the lock on "ep->lock". | 748 | * us during this operation. So we can avoid the lock on "ep->lock". |
749 | * We do not need to lock ep->mtx, either, we only do it to prevent | ||
750 | * a lockdep warning. | ||
714 | */ | 751 | */ |
752 | mutex_lock(&ep->mtx); | ||
715 | while ((rbp = rb_first(&ep->rbr)) != NULL) { | 753 | while ((rbp = rb_first(&ep->rbr)) != NULL) { |
716 | epi = rb_entry(rbp, struct epitem, rbn); | 754 | epi = rb_entry(rbp, struct epitem, rbn); |
717 | ep_remove(ep, epi); | 755 | ep_remove(ep, epi); |
718 | } | 756 | } |
757 | mutex_unlock(&ep->mtx); | ||
719 | 758 | ||
720 | mutex_unlock(&epmutex); | 759 | mutex_unlock(&epmutex); |
721 | mutex_destroy(&ep->mtx); | 760 | mutex_destroy(&ep->mtx); |
@@ -734,6 +773,13 @@ static int ep_eventpoll_release(struct inode *inode, struct file *file) | |||
734 | return 0; | 773 | return 0; |
735 | } | 774 | } |
736 | 775 | ||
776 | static inline unsigned int ep_item_poll(struct epitem *epi, poll_table *pt) | ||
777 | { | ||
778 | pt->_key = epi->event.events; | ||
779 | |||
780 | return epi->ffd.file->f_op->poll(epi->ffd.file, pt) & epi->event.events; | ||
781 | } | ||
782 | |||
737 | static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, | 783 | static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, |
738 | void *priv) | 784 | void *priv) |
739 | { | 785 | { |
@@ -741,10 +787,9 @@ static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, | |||
741 | poll_table pt; | 787 | poll_table pt; |
742 | 788 | ||
743 | init_poll_funcptr(&pt, NULL); | 789 | init_poll_funcptr(&pt, NULL); |
790 | |||
744 | list_for_each_entry_safe(epi, tmp, head, rdllink) { | 791 | list_for_each_entry_safe(epi, tmp, head, rdllink) { |
745 | pt._key = epi->event.events; | 792 | if (ep_item_poll(epi, &pt)) |
746 | if (epi->ffd.file->f_op->poll(epi->ffd.file, &pt) & | ||
747 | epi->event.events) | ||
748 | return POLLIN | POLLRDNORM; | 793 | return POLLIN | POLLRDNORM; |
749 | else { | 794 | else { |
750 | /* | 795 | /* |
@@ -752,7 +797,7 @@ static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, | |||
752 | * callback, but it's not actually ready, as far as | 797 | * callback, but it's not actually ready, as far as |
753 | * caller requested events goes. We can remove it here. | 798 | * caller requested events goes. We can remove it here. |
754 | */ | 799 | */ |
755 | __pm_relax(epi->ws); | 800 | __pm_relax(ep_wakeup_source(epi)); |
756 | list_del_init(&epi->rdllink); | 801 | list_del_init(&epi->rdllink); |
757 | } | 802 | } |
758 | } | 803 | } |
@@ -984,7 +1029,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k | |||
984 | /* If this file is already in the ready list we exit soon */ | 1029 | /* If this file is already in the ready list we exit soon */ |
985 | if (!ep_is_linked(&epi->rdllink)) { | 1030 | if (!ep_is_linked(&epi->rdllink)) { |
986 | list_add_tail(&epi->rdllink, &ep->rdllist); | 1031 | list_add_tail(&epi->rdllink, &ep->rdllist); |
987 | __pm_stay_awake(epi->ws); | 1032 | ep_pm_stay_awake_rcu(epi); |
988 | } | 1033 | } |
989 | 1034 | ||
990 | /* | 1035 | /* |
@@ -1146,6 +1191,7 @@ static int reverse_path_check(void) | |||
1146 | static int ep_create_wakeup_source(struct epitem *epi) | 1191 | static int ep_create_wakeup_source(struct epitem *epi) |
1147 | { | 1192 | { |
1148 | const char *name; | 1193 | const char *name; |
1194 | struct wakeup_source *ws; | ||
1149 | 1195 | ||
1150 | if (!epi->ep->ws) { | 1196 | if (!epi->ep->ws) { |
1151 | epi->ep->ws = wakeup_source_register("eventpoll"); | 1197 | epi->ep->ws = wakeup_source_register("eventpoll"); |
@@ -1154,17 +1200,29 @@ static int ep_create_wakeup_source(struct epitem *epi) | |||
1154 | } | 1200 | } |
1155 | 1201 | ||
1156 | name = epi->ffd.file->f_path.dentry->d_name.name; | 1202 | name = epi->ffd.file->f_path.dentry->d_name.name; |
1157 | epi->ws = wakeup_source_register(name); | 1203 | ws = wakeup_source_register(name); |
1158 | if (!epi->ws) | 1204 | |
1205 | if (!ws) | ||
1159 | return -ENOMEM; | 1206 | return -ENOMEM; |
1207 | rcu_assign_pointer(epi->ws, ws); | ||
1160 | 1208 | ||
1161 | return 0; | 1209 | return 0; |
1162 | } | 1210 | } |
1163 | 1211 | ||
1164 | static void ep_destroy_wakeup_source(struct epitem *epi) | 1212 | /* rare code path, only used when EPOLL_CTL_MOD removes a wakeup source */ |
1213 | static noinline void ep_destroy_wakeup_source(struct epitem *epi) | ||
1165 | { | 1214 | { |
1166 | wakeup_source_unregister(epi->ws); | 1215 | struct wakeup_source *ws = ep_wakeup_source(epi); |
1167 | epi->ws = NULL; | 1216 | |
1217 | RCU_INIT_POINTER(epi->ws, NULL); | ||
1218 | |||
1219 | /* | ||
1220 | * wait for ep_pm_stay_awake_rcu to finish, synchronize_rcu is | ||
1221 | * used internally by wakeup_source_remove, too (called by | ||
1222 | * wakeup_source_unregister), so we cannot use call_rcu | ||
1223 | */ | ||
1224 | synchronize_rcu(); | ||
1225 | wakeup_source_unregister(ws); | ||
1168 | } | 1226 | } |
1169 | 1227 | ||
1170 | /* | 1228 | /* |
@@ -1199,13 +1257,12 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
1199 | if (error) | 1257 | if (error) |
1200 | goto error_create_wakeup_source; | 1258 | goto error_create_wakeup_source; |
1201 | } else { | 1259 | } else { |
1202 | epi->ws = NULL; | 1260 | RCU_INIT_POINTER(epi->ws, NULL); |
1203 | } | 1261 | } |
1204 | 1262 | ||
1205 | /* Initialize the poll table using the queue callback */ | 1263 | /* Initialize the poll table using the queue callback */ |
1206 | epq.epi = epi; | 1264 | epq.epi = epi; |
1207 | init_poll_funcptr(&epq.pt, ep_ptable_queue_proc); | 1265 | init_poll_funcptr(&epq.pt, ep_ptable_queue_proc); |
1208 | epq.pt._key = event->events; | ||
1209 | 1266 | ||
1210 | /* | 1267 | /* |
1211 | * Attach the item to the poll hooks and get current event bits. | 1268 | * Attach the item to the poll hooks and get current event bits. |
@@ -1214,7 +1271,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
1214 | * this operation completes, the poll callback can start hitting | 1271 | * this operation completes, the poll callback can start hitting |
1215 | * the new item. | 1272 | * the new item. |
1216 | */ | 1273 | */ |
1217 | revents = tfile->f_op->poll(tfile, &epq.pt); | 1274 | revents = ep_item_poll(epi, &epq.pt); |
1218 | 1275 | ||
1219 | /* | 1276 | /* |
1220 | * We have to check if something went wrong during the poll wait queue | 1277 | * We have to check if something went wrong during the poll wait queue |
@@ -1247,7 +1304,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
1247 | /* If the file is already "ready" we drop it inside the ready list */ | 1304 | /* If the file is already "ready" we drop it inside the ready list */ |
1248 | if ((revents & event->events) && !ep_is_linked(&epi->rdllink)) { | 1305 | if ((revents & event->events) && !ep_is_linked(&epi->rdllink)) { |
1249 | list_add_tail(&epi->rdllink, &ep->rdllist); | 1306 | list_add_tail(&epi->rdllink, &ep->rdllist); |
1250 | __pm_stay_awake(epi->ws); | 1307 | ep_pm_stay_awake(epi); |
1251 | 1308 | ||
1252 | /* Notify waiting tasks that events are available */ | 1309 | /* Notify waiting tasks that events are available */ |
1253 | if (waitqueue_active(&ep->wq)) | 1310 | if (waitqueue_active(&ep->wq)) |
@@ -1288,7 +1345,7 @@ error_unregister: | |||
1288 | list_del_init(&epi->rdllink); | 1345 | list_del_init(&epi->rdllink); |
1289 | spin_unlock_irqrestore(&ep->lock, flags); | 1346 | spin_unlock_irqrestore(&ep->lock, flags); |
1290 | 1347 | ||
1291 | wakeup_source_unregister(epi->ws); | 1348 | wakeup_source_unregister(ep_wakeup_source(epi)); |
1292 | 1349 | ||
1293 | error_create_wakeup_source: | 1350 | error_create_wakeup_source: |
1294 | kmem_cache_free(epi_cache, epi); | 1351 | kmem_cache_free(epi_cache, epi); |
@@ -1314,12 +1371,11 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even | |||
1314 | * f_op->poll() call and the new event set registering. | 1371 | * f_op->poll() call and the new event set registering. |
1315 | */ | 1372 | */ |
1316 | epi->event.events = event->events; /* need barrier below */ | 1373 | epi->event.events = event->events; /* need barrier below */ |
1317 | pt._key = event->events; | ||
1318 | epi->event.data = event->data; /* protected by mtx */ | 1374 | epi->event.data = event->data; /* protected by mtx */ |
1319 | if (epi->event.events & EPOLLWAKEUP) { | 1375 | if (epi->event.events & EPOLLWAKEUP) { |
1320 | if (!epi->ws) | 1376 | if (!ep_has_wakeup_source(epi)) |
1321 | ep_create_wakeup_source(epi); | 1377 | ep_create_wakeup_source(epi); |
1322 | } else if (epi->ws) { | 1378 | } else if (ep_has_wakeup_source(epi)) { |
1323 | ep_destroy_wakeup_source(epi); | 1379 | ep_destroy_wakeup_source(epi); |
1324 | } | 1380 | } |
1325 | 1381 | ||
@@ -1347,7 +1403,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even | |||
1347 | * Get current event bits. We can safely use the file* here because | 1403 | * Get current event bits. We can safely use the file* here because |
1348 | * its usage count has been increased by the caller of this function. | 1404 | * its usage count has been increased by the caller of this function. |
1349 | */ | 1405 | */ |
1350 | revents = epi->ffd.file->f_op->poll(epi->ffd.file, &pt); | 1406 | revents = ep_item_poll(epi, &pt); |
1351 | 1407 | ||
1352 | /* | 1408 | /* |
1353 | * If the item is "hot" and it is not registered inside the ready | 1409 | * If the item is "hot" and it is not registered inside the ready |
@@ -1357,7 +1413,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even | |||
1357 | spin_lock_irq(&ep->lock); | 1413 | spin_lock_irq(&ep->lock); |
1358 | if (!ep_is_linked(&epi->rdllink)) { | 1414 | if (!ep_is_linked(&epi->rdllink)) { |
1359 | list_add_tail(&epi->rdllink, &ep->rdllist); | 1415 | list_add_tail(&epi->rdllink, &ep->rdllist); |
1360 | __pm_stay_awake(epi->ws); | 1416 | ep_pm_stay_awake(epi); |
1361 | 1417 | ||
1362 | /* Notify waiting tasks that events are available */ | 1418 | /* Notify waiting tasks that events are available */ |
1363 | if (waitqueue_active(&ep->wq)) | 1419 | if (waitqueue_active(&ep->wq)) |
@@ -1383,6 +1439,7 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head, | |||
1383 | unsigned int revents; | 1439 | unsigned int revents; |
1384 | struct epitem *epi; | 1440 | struct epitem *epi; |
1385 | struct epoll_event __user *uevent; | 1441 | struct epoll_event __user *uevent; |
1442 | struct wakeup_source *ws; | ||
1386 | poll_table pt; | 1443 | poll_table pt; |
1387 | 1444 | ||
1388 | init_poll_funcptr(&pt, NULL); | 1445 | init_poll_funcptr(&pt, NULL); |
@@ -1405,14 +1462,16 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head, | |||
1405 | * instead, but then epi->ws would temporarily be out of sync | 1462 | * instead, but then epi->ws would temporarily be out of sync |
1406 | * with ep_is_linked(). | 1463 | * with ep_is_linked(). |
1407 | */ | 1464 | */ |
1408 | if (epi->ws && epi->ws->active) | 1465 | ws = ep_wakeup_source(epi); |
1409 | __pm_stay_awake(ep->ws); | 1466 | if (ws) { |
1410 | __pm_relax(epi->ws); | 1467 | if (ws->active) |
1468 | __pm_stay_awake(ep->ws); | ||
1469 | __pm_relax(ws); | ||
1470 | } | ||
1471 | |||
1411 | list_del_init(&epi->rdllink); | 1472 | list_del_init(&epi->rdllink); |
1412 | 1473 | ||
1413 | pt._key = epi->event.events; | 1474 | revents = ep_item_poll(epi, &pt); |
1414 | revents = epi->ffd.file->f_op->poll(epi->ffd.file, &pt) & | ||
1415 | epi->event.events; | ||
1416 | 1475 | ||
1417 | /* | 1476 | /* |
1418 | * If the event mask intersect the caller-requested one, | 1477 | * If the event mask intersect the caller-requested one, |
@@ -1424,7 +1483,7 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head, | |||
1424 | if (__put_user(revents, &uevent->events) || | 1483 | if (__put_user(revents, &uevent->events) || |
1425 | __put_user(epi->event.data, &uevent->data)) { | 1484 | __put_user(epi->event.data, &uevent->data)) { |
1426 | list_add(&epi->rdllink, head); | 1485 | list_add(&epi->rdllink, head); |
1427 | __pm_stay_awake(epi->ws); | 1486 | ep_pm_stay_awake(epi); |
1428 | return eventcnt ? eventcnt : -EFAULT; | 1487 | return eventcnt ? eventcnt : -EFAULT; |
1429 | } | 1488 | } |
1430 | eventcnt++; | 1489 | eventcnt++; |
@@ -1444,7 +1503,7 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head, | |||
1444 | * poll callback will queue them in ep->ovflist. | 1503 | * poll callback will queue them in ep->ovflist. |
1445 | */ | 1504 | */ |
1446 | list_add_tail(&epi->rdllink, &ep->rdllist); | 1505 | list_add_tail(&epi->rdllink, &ep->rdllist); |
1447 | __pm_stay_awake(epi->ws); | 1506 | ep_pm_stay_awake(epi); |
1448 | } | 1507 | } |
1449 | } | 1508 | } |
1450 | } | 1509 | } |
@@ -1940,6 +1999,52 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, | |||
1940 | return error; | 1999 | return error; |
1941 | } | 2000 | } |
1942 | 2001 | ||
2002 | #ifdef CONFIG_COMPAT | ||
2003 | COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, | ||
2004 | struct epoll_event __user *, events, | ||
2005 | int, maxevents, int, timeout, | ||
2006 | const compat_sigset_t __user *, sigmask, | ||
2007 | compat_size_t, sigsetsize) | ||
2008 | { | ||
2009 | long err; | ||
2010 | compat_sigset_t csigmask; | ||
2011 | sigset_t ksigmask, sigsaved; | ||
2012 | |||
2013 | /* | ||
2014 | * If the caller wants a certain signal mask to be set during the wait, | ||
2015 | * we apply it here. | ||
2016 | */ | ||
2017 | if (sigmask) { | ||
2018 | if (sigsetsize != sizeof(compat_sigset_t)) | ||
2019 | return -EINVAL; | ||
2020 | if (copy_from_user(&csigmask, sigmask, sizeof(csigmask))) | ||
2021 | return -EFAULT; | ||
2022 | sigset_from_compat(&ksigmask, &csigmask); | ||
2023 | sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); | ||
2024 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | ||
2025 | } | ||
2026 | |||
2027 | err = sys_epoll_wait(epfd, events, maxevents, timeout); | ||
2028 | |||
2029 | /* | ||
2030 | * If we changed the signal mask, we need to restore the original one. | ||
2031 | * In case we've got a signal while waiting, we do not restore the | ||
2032 | * signal mask yet, and we allow do_signal() to deliver the signal on | ||
2033 | * the way back to userspace, before the signal mask is restored. | ||
2034 | */ | ||
2035 | if (sigmask) { | ||
2036 | if (err == -EINTR) { | ||
2037 | memcpy(¤t->saved_sigmask, &sigsaved, | ||
2038 | sizeof(sigsaved)); | ||
2039 | set_restore_sigmask(); | ||
2040 | } else | ||
2041 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | ||
2042 | } | ||
2043 | |||
2044 | return err; | ||
2045 | } | ||
2046 | #endif | ||
2047 | |||
1943 | static int __init eventpoll_init(void) | 2048 | static int __init eventpoll_init(void) |
1944 | { | 2049 | { |
1945 | struct sysinfo si; | 2050 | struct sysinfo si; |
@@ -1964,6 +2069,12 @@ static int __init eventpoll_init(void) | |||
1964 | /* Initialize the structure used to perform file's f_op->poll() calls */ | 2069 | /* Initialize the structure used to perform file's f_op->poll() calls */ |
1965 | ep_nested_calls_init(&poll_readywalk_ncalls); | 2070 | ep_nested_calls_init(&poll_readywalk_ncalls); |
1966 | 2071 | ||
2072 | /* | ||
2073 | * We can have many thousands of epitems, so prevent this from | ||
2074 | * using an extra cache line on 64-bit (and smaller) CPUs | ||
2075 | */ | ||
2076 | BUILD_BUG_ON(sizeof(void *) <= 8 && sizeof(struct epitem) > 128); | ||
2077 | |||
1967 | /* Allocates slab cache used to allocate "struct epitem" items */ | 2078 | /* Allocates slab cache used to allocate "struct epitem" items */ |
1968 | epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), | 2079 | epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), |
1969 | 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); | 2080 | 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); |
@@ -613,7 +613,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
613 | * when the old and new regions overlap clear from new_end. | 613 | * when the old and new regions overlap clear from new_end. |
614 | */ | 614 | */ |
615 | free_pgd_range(&tlb, new_end, old_end, new_end, | 615 | free_pgd_range(&tlb, new_end, old_end, new_end, |
616 | vma->vm_next ? vma->vm_next->vm_start : 0); | 616 | vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING); |
617 | } else { | 617 | } else { |
618 | /* | 618 | /* |
619 | * otherwise, clean from old_start; this is done to not touch | 619 | * otherwise, clean from old_start; this is done to not touch |
@@ -622,7 +622,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
622 | * for the others its just a little faster. | 622 | * for the others its just a little faster. |
623 | */ | 623 | */ |
624 | free_pgd_range(&tlb, old_start, old_end, new_end, | 624 | free_pgd_range(&tlb, old_start, old_end, new_end, |
625 | vma->vm_next ? vma->vm_next->vm_start : 0); | 625 | vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING); |
626 | } | 626 | } |
627 | tlb_finish_mmu(&tlb, new_end, old_end); | 627 | tlb_finish_mmu(&tlb, new_end, old_end); |
628 | 628 | ||
@@ -898,11 +898,13 @@ static int de_thread(struct task_struct *tsk) | |||
898 | 898 | ||
899 | sig->notify_count = -1; /* for exit_notify() */ | 899 | sig->notify_count = -1; /* for exit_notify() */ |
900 | for (;;) { | 900 | for (;;) { |
901 | threadgroup_change_begin(tsk); | ||
901 | write_lock_irq(&tasklist_lock); | 902 | write_lock_irq(&tasklist_lock); |
902 | if (likely(leader->exit_state)) | 903 | if (likely(leader->exit_state)) |
903 | break; | 904 | break; |
904 | __set_current_state(TASK_KILLABLE); | 905 | __set_current_state(TASK_KILLABLE); |
905 | write_unlock_irq(&tasklist_lock); | 906 | write_unlock_irq(&tasklist_lock); |
907 | threadgroup_change_end(tsk); | ||
906 | schedule(); | 908 | schedule(); |
907 | if (unlikely(__fatal_signal_pending(tsk))) | 909 | if (unlikely(__fatal_signal_pending(tsk))) |
908 | goto killed; | 910 | goto killed; |
@@ -960,6 +962,7 @@ static int de_thread(struct task_struct *tsk) | |||
960 | if (unlikely(leader->ptrace)) | 962 | if (unlikely(leader->ptrace)) |
961 | __wake_up_parent(leader, leader->parent); | 963 | __wake_up_parent(leader, leader->parent); |
962 | write_unlock_irq(&tasklist_lock); | 964 | write_unlock_irq(&tasklist_lock); |
965 | threadgroup_change_end(tsk); | ||
963 | 966 | ||
964 | release_task(leader); | 967 | release_task(leader); |
965 | } | 968 | } |
@@ -1027,17 +1030,7 @@ EXPORT_SYMBOL_GPL(get_task_comm); | |||
1027 | void set_task_comm(struct task_struct *tsk, char *buf) | 1030 | void set_task_comm(struct task_struct *tsk, char *buf) |
1028 | { | 1031 | { |
1029 | task_lock(tsk); | 1032 | task_lock(tsk); |
1030 | |||
1031 | trace_task_rename(tsk, buf); | 1033 | trace_task_rename(tsk, buf); |
1032 | |||
1033 | /* | ||
1034 | * Threads may access current->comm without holding | ||
1035 | * the task lock, so write the string carefully. | ||
1036 | * Readers without a lock may see incomplete new | ||
1037 | * names but are safe from non-terminating string reads. | ||
1038 | */ | ||
1039 | memset(tsk->comm, 0, TASK_COMM_LEN); | ||
1040 | wmb(); | ||
1041 | strlcpy(tsk->comm, buf, sizeof(tsk->comm)); | 1034 | strlcpy(tsk->comm, buf, sizeof(tsk->comm)); |
1042 | task_unlock(tsk); | 1035 | task_unlock(tsk); |
1043 | perf_event_comm(tsk); | 1036 | perf_event_comm(tsk); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index fb5120a5505c..3dc48cc8b6eb 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2067,7 +2067,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
2067 | test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal": | 2067 | test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal": |
2068 | test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": | 2068 | test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": |
2069 | "writeback"); | 2069 | "writeback"); |
2070 | sb->s_flags |= MS_SNAP_STABLE; | ||
2071 | 2070 | ||
2072 | return 0; | 2071 | return 0; |
2073 | 2072 | ||
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index cc2213afdcc7..201c8d3b0f86 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -137,7 +137,7 @@ struct extent_info { | |||
137 | rwlock_t ext_lock; /* rwlock for consistency */ | 137 | rwlock_t ext_lock; /* rwlock for consistency */ |
138 | unsigned int fofs; /* start offset in a file */ | 138 | unsigned int fofs; /* start offset in a file */ |
139 | u32 blk_addr; /* start block address of the extent */ | 139 | u32 blk_addr; /* start block address of the extent */ |
140 | unsigned int len; /* lenth of the extent */ | 140 | unsigned int len; /* length of the extent */ |
141 | }; | 141 | }; |
142 | 142 | ||
143 | /* | 143 | /* |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 94b8a0c48453..2e3eb2d4fc30 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
@@ -222,7 +222,7 @@ static unsigned int get_gc_cost(struct f2fs_sb_info *sbi, unsigned int segno, | |||
222 | } | 222 | } |
223 | 223 | ||
224 | /* | 224 | /* |
225 | * This function is called from two pathes. | 225 | * This function is called from two paths. |
226 | * One is garbage collection and the other is SSR segment selection. | 226 | * One is garbage collection and the other is SSR segment selection. |
227 | * When it is called during GC, it just gets a victim segment | 227 | * When it is called during GC, it just gets a victim segment |
228 | * and it does not remove it from dirty seglist. | 228 | * and it does not remove it from dirty seglist. |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index fea6e582a2ed..62e017743af6 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -82,7 +82,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) | |||
82 | 82 | ||
83 | init_once((void *) fi); | 83 | init_once((void *) fi); |
84 | 84 | ||
85 | /* Initilize f2fs-specific inode info */ | 85 | /* Initialize f2fs-specific inode info */ |
86 | fi->vfs_inode.i_version = 1; | 86 | fi->vfs_inode.i_version = 1; |
87 | atomic_set(&fi->dirty_dents, 0); | 87 | atomic_set(&fi->dirty_dents, 0); |
88 | fi->i_current_depth = 1; | 88 | fi->i_current_depth = 1; |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 165012ef363a..7a6f02caf286 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -964,6 +964,29 @@ int fat_scan(struct inode *dir, const unsigned char *name, | |||
964 | } | 964 | } |
965 | EXPORT_SYMBOL_GPL(fat_scan); | 965 | EXPORT_SYMBOL_GPL(fat_scan); |
966 | 966 | ||
967 | /* | ||
968 | * Scans a directory for a given logstart. | ||
969 | * Returns an error code or zero. | ||
970 | */ | ||
971 | int fat_scan_logstart(struct inode *dir, int i_logstart, | ||
972 | struct fat_slot_info *sinfo) | ||
973 | { | ||
974 | struct super_block *sb = dir->i_sb; | ||
975 | |||
976 | sinfo->slot_off = 0; | ||
977 | sinfo->bh = NULL; | ||
978 | while (fat_get_short_entry(dir, &sinfo->slot_off, &sinfo->bh, | ||
979 | &sinfo->de) >= 0) { | ||
980 | if (fat_get_start(MSDOS_SB(sb), sinfo->de) == i_logstart) { | ||
981 | sinfo->slot_off -= sizeof(*sinfo->de); | ||
982 | sinfo->nr_slots = 1; | ||
983 | sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de); | ||
984 | return 0; | ||
985 | } | ||
986 | } | ||
987 | return -ENOENT; | ||
988 | } | ||
989 | |||
967 | static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) | 990 | static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) |
968 | { | 991 | { |
969 | struct super_block *sb = dir->i_sb; | 992 | struct super_block *sb = dir->i_sb; |
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index e9cc3f0d58e2..21664fcf3616 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -23,6 +23,9 @@ | |||
23 | #define FAT_ERRORS_PANIC 2 /* panic on error */ | 23 | #define FAT_ERRORS_PANIC 2 /* panic on error */ |
24 | #define FAT_ERRORS_RO 3 /* remount r/o on error */ | 24 | #define FAT_ERRORS_RO 3 /* remount r/o on error */ |
25 | 25 | ||
26 | #define FAT_NFS_STALE_RW 1 /* NFS RW support, can cause ESTALE */ | ||
27 | #define FAT_NFS_NOSTALE_RO 2 /* NFS RO support, no ESTALE issue */ | ||
28 | |||
26 | struct fat_mount_options { | 29 | struct fat_mount_options { |
27 | kuid_t fs_uid; | 30 | kuid_t fs_uid; |
28 | kgid_t fs_gid; | 31 | kgid_t fs_gid; |
@@ -34,6 +37,7 @@ struct fat_mount_options { | |||
34 | unsigned short shortname; /* flags for shortname display/create rule */ | 37 | unsigned short shortname; /* flags for shortname display/create rule */ |
35 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ | 38 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ |
36 | unsigned char errors; /* On error: continue, panic, remount-ro */ | 39 | unsigned char errors; /* On error: continue, panic, remount-ro */ |
40 | unsigned char nfs; /* NFS support: nostale_ro, stale_rw */ | ||
37 | unsigned short allow_utime;/* permission for setting the [am]time */ | 41 | unsigned short allow_utime;/* permission for setting the [am]time */ |
38 | unsigned quiet:1, /* set = fake successful chmods and chowns */ | 42 | unsigned quiet:1, /* set = fake successful chmods and chowns */ |
39 | showexec:1, /* set = only set x bit for com/exe/bat */ | 43 | showexec:1, /* set = only set x bit for com/exe/bat */ |
@@ -48,8 +52,7 @@ struct fat_mount_options { | |||
48 | usefree:1, /* Use free_clusters for FAT32 */ | 52 | usefree:1, /* Use free_clusters for FAT32 */ |
49 | tz_set:1, /* Filesystem timestamps' offset set */ | 53 | tz_set:1, /* Filesystem timestamps' offset set */ |
50 | rodir:1, /* allow ATTR_RO for directory */ | 54 | rodir:1, /* allow ATTR_RO for directory */ |
51 | discard:1, /* Issue discard requests on deletions */ | 55 | discard:1; /* Issue discard requests on deletions */ |
52 | nfs:1; /* Do extra work needed for NFS export */ | ||
53 | }; | 56 | }; |
54 | 57 | ||
55 | #define FAT_HASH_BITS 8 | 58 | #define FAT_HASH_BITS 8 |
@@ -72,6 +75,7 @@ struct msdos_sb_info { | |||
72 | unsigned long root_cluster; /* first cluster of the root directory */ | 75 | unsigned long root_cluster; /* first cluster of the root directory */ |
73 | unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ | 76 | unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ |
74 | struct mutex fat_lock; | 77 | struct mutex fat_lock; |
78 | struct mutex nfs_build_inode_lock; | ||
75 | struct mutex s_lock; | 79 | struct mutex s_lock; |
76 | unsigned int prev_free; /* previously allocated cluster number */ | 80 | unsigned int prev_free; /* previously allocated cluster number */ |
77 | unsigned int free_clusters; /* -1 if undefined */ | 81 | unsigned int free_clusters; /* -1 if undefined */ |
@@ -215,6 +219,27 @@ static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus) | |||
215 | + sbi->data_start; | 219 | + sbi->data_start; |
216 | } | 220 | } |
217 | 221 | ||
222 | static inline void fat_get_blknr_offset(struct msdos_sb_info *sbi, | ||
223 | loff_t i_pos, sector_t *blknr, int *offset) | ||
224 | { | ||
225 | *blknr = i_pos >> sbi->dir_per_block_bits; | ||
226 | *offset = i_pos & (sbi->dir_per_block - 1); | ||
227 | } | ||
228 | |||
229 | static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi, | ||
230 | struct inode *inode) | ||
231 | { | ||
232 | loff_t i_pos; | ||
233 | #if BITS_PER_LONG == 32 | ||
234 | spin_lock(&sbi->inode_hash_lock); | ||
235 | #endif | ||
236 | i_pos = MSDOS_I(inode)->i_pos; | ||
237 | #if BITS_PER_LONG == 32 | ||
238 | spin_unlock(&sbi->inode_hash_lock); | ||
239 | #endif | ||
240 | return i_pos; | ||
241 | } | ||
242 | |||
218 | static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) | 243 | static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) |
219 | { | 244 | { |
220 | #ifdef __BIG_ENDIAN | 245 | #ifdef __BIG_ENDIAN |
@@ -271,6 +296,8 @@ extern int fat_dir_empty(struct inode *dir); | |||
271 | extern int fat_subdirs(struct inode *dir); | 296 | extern int fat_subdirs(struct inode *dir); |
272 | extern int fat_scan(struct inode *dir, const unsigned char *name, | 297 | extern int fat_scan(struct inode *dir, const unsigned char *name, |
273 | struct fat_slot_info *sinfo); | 298 | struct fat_slot_info *sinfo); |
299 | extern int fat_scan_logstart(struct inode *dir, int i_logstart, | ||
300 | struct fat_slot_info *sinfo); | ||
274 | extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, | 301 | extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, |
275 | struct msdos_dir_entry **de); | 302 | struct msdos_dir_entry **de); |
276 | extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); | 303 | extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); |
@@ -348,6 +375,7 @@ extern struct inode *fat_build_inode(struct super_block *sb, | |||
348 | extern int fat_sync_inode(struct inode *inode); | 375 | extern int fat_sync_inode(struct inode *inode); |
349 | extern int fat_fill_super(struct super_block *sb, void *data, int silent, | 376 | extern int fat_fill_super(struct super_block *sb, void *data, int silent, |
350 | int isvfat, void (*setup)(struct super_block *)); | 377 | int isvfat, void (*setup)(struct super_block *)); |
378 | extern int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de); | ||
351 | 379 | ||
352 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, | 380 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, |
353 | struct inode *i2); | 381 | struct inode *i2); |
@@ -382,12 +410,8 @@ int fat_cache_init(void); | |||
382 | void fat_cache_destroy(void); | 410 | void fat_cache_destroy(void); |
383 | 411 | ||
384 | /* fat/nfs.c */ | 412 | /* fat/nfs.c */ |
385 | struct fid; | 413 | extern const struct export_operations fat_export_ops; |
386 | extern struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, | 414 | extern const struct export_operations fat_export_ops_nostale; |
387 | int fh_len, int fh_type); | ||
388 | extern struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, | ||
389 | int fh_len, int fh_type); | ||
390 | extern struct dentry *fat_get_parent(struct dentry *child_dir); | ||
391 | 415 | ||
392 | /* helper for printk */ | 416 | /* helper for printk */ |
393 | typedef unsigned long long llu; | 417 | typedef unsigned long long llu; |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 3978f8ca1823..b0b632e50ddb 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -306,6 +306,11 @@ int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
306 | struct inode *inode = dentry->d_inode; | 306 | struct inode *inode = dentry->d_inode; |
307 | generic_fillattr(inode, stat); | 307 | generic_fillattr(inode, stat); |
308 | stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; | 308 | stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; |
309 | |||
310 | if (MSDOS_SB(inode->i_sb)->options.nfs == FAT_NFS_NOSTALE_RO) { | ||
311 | /* Use i_pos for ino. This is used as fileid of nfs. */ | ||
312 | stat->ino = fat_i_pos_read(MSDOS_SB(inode->i_sb), inode); | ||
313 | } | ||
309 | return 0; | 314 | return 0; |
310 | } | 315 | } |
311 | EXPORT_SYMBOL_GPL(fat_getattr); | 316 | EXPORT_SYMBOL_GPL(fat_getattr); |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index acf6e479b443..4ff901632b26 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/mpage.h> | 19 | #include <linux/mpage.h> |
20 | #include <linux/buffer_head.h> | 20 | #include <linux/buffer_head.h> |
21 | #include <linux/exportfs.h> | ||
22 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
23 | #include <linux/vfs.h> | 22 | #include <linux/vfs.h> |
24 | #include <linux/parser.h> | 23 | #include <linux/parser.h> |
@@ -385,7 +384,7 @@ static int fat_calc_dir_size(struct inode *inode) | |||
385 | } | 384 | } |
386 | 385 | ||
387 | /* doesn't deal with root inode */ | 386 | /* doesn't deal with root inode */ |
388 | static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) | 387 | int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) |
389 | { | 388 | { |
390 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | 389 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
391 | int error; | 390 | int error; |
@@ -444,12 +443,25 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) | |||
444 | return 0; | 443 | return 0; |
445 | } | 444 | } |
446 | 445 | ||
446 | static inline void fat_lock_build_inode(struct msdos_sb_info *sbi) | ||
447 | { | ||
448 | if (sbi->options.nfs == FAT_NFS_NOSTALE_RO) | ||
449 | mutex_lock(&sbi->nfs_build_inode_lock); | ||
450 | } | ||
451 | |||
452 | static inline void fat_unlock_build_inode(struct msdos_sb_info *sbi) | ||
453 | { | ||
454 | if (sbi->options.nfs == FAT_NFS_NOSTALE_RO) | ||
455 | mutex_unlock(&sbi->nfs_build_inode_lock); | ||
456 | } | ||
457 | |||
447 | struct inode *fat_build_inode(struct super_block *sb, | 458 | struct inode *fat_build_inode(struct super_block *sb, |
448 | struct msdos_dir_entry *de, loff_t i_pos) | 459 | struct msdos_dir_entry *de, loff_t i_pos) |
449 | { | 460 | { |
450 | struct inode *inode; | 461 | struct inode *inode; |
451 | int err; | 462 | int err; |
452 | 463 | ||
464 | fat_lock_build_inode(MSDOS_SB(sb)); | ||
453 | inode = fat_iget(sb, i_pos); | 465 | inode = fat_iget(sb, i_pos); |
454 | if (inode) | 466 | if (inode) |
455 | goto out; | 467 | goto out; |
@@ -469,6 +481,7 @@ struct inode *fat_build_inode(struct super_block *sb, | |||
469 | fat_attach(inode, i_pos); | 481 | fat_attach(inode, i_pos); |
470 | insert_inode_hash(inode); | 482 | insert_inode_hash(inode); |
471 | out: | 483 | out: |
484 | fat_unlock_build_inode(MSDOS_SB(sb)); | ||
472 | return inode; | 485 | return inode; |
473 | } | 486 | } |
474 | 487 | ||
@@ -655,20 +668,6 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
655 | return 0; | 668 | return 0; |
656 | } | 669 | } |
657 | 670 | ||
658 | static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi, | ||
659 | struct inode *inode) | ||
660 | { | ||
661 | loff_t i_pos; | ||
662 | #if BITS_PER_LONG == 32 | ||
663 | spin_lock(&sbi->inode_hash_lock); | ||
664 | #endif | ||
665 | i_pos = MSDOS_I(inode)->i_pos; | ||
666 | #if BITS_PER_LONG == 32 | ||
667 | spin_unlock(&sbi->inode_hash_lock); | ||
668 | #endif | ||
669 | return i_pos; | ||
670 | } | ||
671 | |||
672 | static int __fat_write_inode(struct inode *inode, int wait) | 671 | static int __fat_write_inode(struct inode *inode, int wait) |
673 | { | 672 | { |
674 | struct super_block *sb = inode->i_sb; | 673 | struct super_block *sb = inode->i_sb; |
@@ -676,7 +675,8 @@ static int __fat_write_inode(struct inode *inode, int wait) | |||
676 | struct buffer_head *bh; | 675 | struct buffer_head *bh; |
677 | struct msdos_dir_entry *raw_entry; | 676 | struct msdos_dir_entry *raw_entry; |
678 | loff_t i_pos; | 677 | loff_t i_pos; |
679 | int err; | 678 | sector_t blocknr; |
679 | int err, offset; | ||
680 | 680 | ||
681 | if (inode->i_ino == MSDOS_ROOT_INO) | 681 | if (inode->i_ino == MSDOS_ROOT_INO) |
682 | return 0; | 682 | return 0; |
@@ -686,7 +686,8 @@ retry: | |||
686 | if (!i_pos) | 686 | if (!i_pos) |
687 | return 0; | 687 | return 0; |
688 | 688 | ||
689 | bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits); | 689 | fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset); |
690 | bh = sb_bread(sb, blocknr); | ||
690 | if (!bh) { | 691 | if (!bh) { |
691 | fat_msg(sb, KERN_ERR, "unable to read inode block " | 692 | fat_msg(sb, KERN_ERR, "unable to read inode block " |
692 | "for updating (i_pos %lld)", i_pos); | 693 | "for updating (i_pos %lld)", i_pos); |
@@ -699,8 +700,7 @@ retry: | |||
699 | goto retry; | 700 | goto retry; |
700 | } | 701 | } |
701 | 702 | ||
702 | raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) | 703 | raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset]; |
703 | [i_pos & (sbi->dir_per_block - 1)]; | ||
704 | if (S_ISDIR(inode->i_mode)) | 704 | if (S_ISDIR(inode->i_mode)) |
705 | raw_entry->size = 0; | 705 | raw_entry->size = 0; |
706 | else | 706 | else |
@@ -761,12 +761,6 @@ static const struct super_operations fat_sops = { | |||
761 | .show_options = fat_show_options, | 761 | .show_options = fat_show_options, |
762 | }; | 762 | }; |
763 | 763 | ||
764 | static const struct export_operations fat_export_ops = { | ||
765 | .fh_to_dentry = fat_fh_to_dentry, | ||
766 | .fh_to_parent = fat_fh_to_parent, | ||
767 | .get_parent = fat_get_parent, | ||
768 | }; | ||
769 | |||
770 | static int fat_show_options(struct seq_file *m, struct dentry *root) | 764 | static int fat_show_options(struct seq_file *m, struct dentry *root) |
771 | { | 765 | { |
772 | struct msdos_sb_info *sbi = MSDOS_SB(root->d_sb); | 766 | struct msdos_sb_info *sbi = MSDOS_SB(root->d_sb); |
@@ -814,8 +808,6 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) | |||
814 | seq_puts(m, ",usefree"); | 808 | seq_puts(m, ",usefree"); |
815 | if (opts->quiet) | 809 | if (opts->quiet) |
816 | seq_puts(m, ",quiet"); | 810 | seq_puts(m, ",quiet"); |
817 | if (opts->nfs) | ||
818 | seq_puts(m, ",nfs"); | ||
819 | if (opts->showexec) | 811 | if (opts->showexec) |
820 | seq_puts(m, ",showexec"); | 812 | seq_puts(m, ",showexec"); |
821 | if (opts->sys_immutable) | 813 | if (opts->sys_immutable) |
@@ -849,6 +841,10 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) | |||
849 | seq_puts(m, ",errors=panic"); | 841 | seq_puts(m, ",errors=panic"); |
850 | else | 842 | else |
851 | seq_puts(m, ",errors=remount-ro"); | 843 | seq_puts(m, ",errors=remount-ro"); |
844 | if (opts->nfs == FAT_NFS_NOSTALE_RO) | ||
845 | seq_puts(m, ",nfs=nostale_ro"); | ||
846 | else if (opts->nfs) | ||
847 | seq_puts(m, ",nfs=stale_rw"); | ||
852 | if (opts->discard) | 848 | if (opts->discard) |
853 | seq_puts(m, ",discard"); | 849 | seq_puts(m, ",discard"); |
854 | 850 | ||
@@ -865,7 +861,7 @@ enum { | |||
865 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 861 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, |
866 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, | 862 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, |
867 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, | 863 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, |
868 | Opt_err, | 864 | Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err, |
869 | }; | 865 | }; |
870 | 866 | ||
871 | static const match_table_t fat_tokens = { | 867 | static const match_table_t fat_tokens = { |
@@ -895,7 +891,9 @@ static const match_table_t fat_tokens = { | |||
895 | {Opt_err_panic, "errors=panic"}, | 891 | {Opt_err_panic, "errors=panic"}, |
896 | {Opt_err_ro, "errors=remount-ro"}, | 892 | {Opt_err_ro, "errors=remount-ro"}, |
897 | {Opt_discard, "discard"}, | 893 | {Opt_discard, "discard"}, |
898 | {Opt_nfs, "nfs"}, | 894 | {Opt_nfs_stale_rw, "nfs"}, |
895 | {Opt_nfs_stale_rw, "nfs=stale_rw"}, | ||
896 | {Opt_nfs_nostale_ro, "nfs=nostale_ro"}, | ||
899 | {Opt_obsolete, "conv=binary"}, | 897 | {Opt_obsolete, "conv=binary"}, |
900 | {Opt_obsolete, "conv=text"}, | 898 | {Opt_obsolete, "conv=text"}, |
901 | {Opt_obsolete, "conv=auto"}, | 899 | {Opt_obsolete, "conv=auto"}, |
@@ -1092,6 +1090,12 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
1092 | case Opt_err_ro: | 1090 | case Opt_err_ro: |
1093 | opts->errors = FAT_ERRORS_RO; | 1091 | opts->errors = FAT_ERRORS_RO; |
1094 | break; | 1092 | break; |
1093 | case Opt_nfs_stale_rw: | ||
1094 | opts->nfs = FAT_NFS_STALE_RW; | ||
1095 | break; | ||
1096 | case Opt_nfs_nostale_ro: | ||
1097 | opts->nfs = FAT_NFS_NOSTALE_RO; | ||
1098 | break; | ||
1095 | 1099 | ||
1096 | /* msdos specific */ | 1100 | /* msdos specific */ |
1097 | case Opt_dots: | 1101 | case Opt_dots: |
@@ -1150,9 +1154,6 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
1150 | case Opt_discard: | 1154 | case Opt_discard: |
1151 | opts->discard = 1; | 1155 | opts->discard = 1; |
1152 | break; | 1156 | break; |
1153 | case Opt_nfs: | ||
1154 | opts->nfs = 1; | ||
1155 | break; | ||
1156 | 1157 | ||
1157 | /* obsolete mount options */ | 1158 | /* obsolete mount options */ |
1158 | case Opt_obsolete: | 1159 | case Opt_obsolete: |
@@ -1183,6 +1184,10 @@ out: | |||
1183 | opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); | 1184 | opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); |
1184 | if (opts->unicode_xlate) | 1185 | if (opts->unicode_xlate) |
1185 | opts->utf8 = 0; | 1186 | opts->utf8 = 0; |
1187 | if (opts->nfs == FAT_NFS_NOSTALE_RO) { | ||
1188 | sb->s_flags |= MS_RDONLY; | ||
1189 | sb->s_export_op = &fat_export_ops_nostale; | ||
1190 | } | ||
1186 | 1191 | ||
1187 | return 0; | 1192 | return 0; |
1188 | } | 1193 | } |
@@ -1193,7 +1198,7 @@ static int fat_read_root(struct inode *inode) | |||
1193 | struct msdos_sb_info *sbi = MSDOS_SB(sb); | 1198 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
1194 | int error; | 1199 | int error; |
1195 | 1200 | ||
1196 | MSDOS_I(inode)->i_pos = 0; | 1201 | MSDOS_I(inode)->i_pos = MSDOS_ROOT_INO; |
1197 | inode->i_uid = sbi->options.fs_uid; | 1202 | inode->i_uid = sbi->options.fs_uid; |
1198 | inode->i_gid = sbi->options.fs_gid; | 1203 | inode->i_gid = sbi->options.fs_gid; |
1199 | inode->i_version++; | 1204 | inode->i_version++; |
@@ -1256,6 +1261,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1256 | sb->s_magic = MSDOS_SUPER_MAGIC; | 1261 | sb->s_magic = MSDOS_SUPER_MAGIC; |
1257 | sb->s_op = &fat_sops; | 1262 | sb->s_op = &fat_sops; |
1258 | sb->s_export_op = &fat_export_ops; | 1263 | sb->s_export_op = &fat_export_ops; |
1264 | mutex_init(&sbi->nfs_build_inode_lock); | ||
1259 | ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, | 1265 | ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, |
1260 | DEFAULT_RATELIMIT_BURST); | 1266 | DEFAULT_RATELIMIT_BURST); |
1261 | 1267 | ||
diff --git a/fs/fat/nfs.c b/fs/fat/nfs.c index 499c10438ca2..93e14933dcb6 100644 --- a/fs/fat/nfs.c +++ b/fs/fat/nfs.c | |||
@@ -14,6 +14,18 @@ | |||
14 | #include <linux/exportfs.h> | 14 | #include <linux/exportfs.h> |
15 | #include "fat.h" | 15 | #include "fat.h" |
16 | 16 | ||
17 | struct fat_fid { | ||
18 | u32 i_gen; | ||
19 | u32 i_pos_low; | ||
20 | u16 i_pos_hi; | ||
21 | u16 parent_i_pos_hi; | ||
22 | u32 parent_i_pos_low; | ||
23 | u32 parent_i_gen; | ||
24 | }; | ||
25 | |||
26 | #define FAT_FID_SIZE_WITHOUT_PARENT 3 | ||
27 | #define FAT_FID_SIZE_WITH_PARENT (sizeof(struct fat_fid)/sizeof(u32)) | ||
28 | |||
17 | /** | 29 | /** |
18 | * Look up a directory inode given its starting cluster. | 30 | * Look up a directory inode given its starting cluster. |
19 | */ | 31 | */ |
@@ -38,63 +50,252 @@ static struct inode *fat_dget(struct super_block *sb, int i_logstart) | |||
38 | return inode; | 50 | return inode; |
39 | } | 51 | } |
40 | 52 | ||
41 | static struct inode *fat_nfs_get_inode(struct super_block *sb, | 53 | static struct inode *fat_ilookup(struct super_block *sb, u64 ino, loff_t i_pos) |
42 | u64 ino, u32 generation) | ||
43 | { | 54 | { |
44 | struct inode *inode; | 55 | if (MSDOS_SB(sb)->options.nfs == FAT_NFS_NOSTALE_RO) |
56 | return fat_iget(sb, i_pos); | ||
45 | 57 | ||
46 | if ((ino < MSDOS_ROOT_INO) || (ino == MSDOS_FSINFO_INO)) | 58 | else { |
47 | return NULL; | 59 | if ((ino < MSDOS_ROOT_INO) || (ino == MSDOS_FSINFO_INO)) |
60 | return NULL; | ||
61 | return ilookup(sb, ino); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | static struct inode *__fat_nfs_get_inode(struct super_block *sb, | ||
66 | u64 ino, u32 generation, loff_t i_pos) | ||
67 | { | ||
68 | struct inode *inode = fat_ilookup(sb, ino, i_pos); | ||
48 | 69 | ||
49 | inode = ilookup(sb, ino); | ||
50 | if (inode && generation && (inode->i_generation != generation)) { | 70 | if (inode && generation && (inode->i_generation != generation)) { |
51 | iput(inode); | 71 | iput(inode); |
52 | inode = NULL; | 72 | inode = NULL; |
53 | } | 73 | } |
74 | if (inode == NULL && MSDOS_SB(sb)->options.nfs == FAT_NFS_NOSTALE_RO) { | ||
75 | struct buffer_head *bh = NULL; | ||
76 | struct msdos_dir_entry *de ; | ||
77 | sector_t blocknr; | ||
78 | int offset; | ||
79 | fat_get_blknr_offset(MSDOS_SB(sb), i_pos, &blocknr, &offset); | ||
80 | bh = sb_bread(sb, blocknr); | ||
81 | if (!bh) { | ||
82 | fat_msg(sb, KERN_ERR, | ||
83 | "unable to read block(%llu) for building NFS inode", | ||
84 | (llu)blocknr); | ||
85 | return inode; | ||
86 | } | ||
87 | de = (struct msdos_dir_entry *)bh->b_data; | ||
88 | /* If a file is deleted on server and client is not updated | ||
89 | * yet, we must not build the inode upon a lookup call. | ||
90 | */ | ||
91 | if (IS_FREE(de[offset].name)) | ||
92 | inode = NULL; | ||
93 | else | ||
94 | inode = fat_build_inode(sb, &de[offset], i_pos); | ||
95 | brelse(bh); | ||
96 | } | ||
54 | 97 | ||
55 | return inode; | 98 | return inode; |
56 | } | 99 | } |
57 | 100 | ||
101 | static struct inode *fat_nfs_get_inode(struct super_block *sb, | ||
102 | u64 ino, u32 generation) | ||
103 | { | ||
104 | |||
105 | return __fat_nfs_get_inode(sb, ino, generation, 0); | ||
106 | } | ||
107 | |||
108 | static int | ||
109 | fat_encode_fh_nostale(struct inode *inode, __u32 *fh, int *lenp, | ||
110 | struct inode *parent) | ||
111 | { | ||
112 | int len = *lenp; | ||
113 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | ||
114 | struct fat_fid *fid = (struct fat_fid *) fh; | ||
115 | loff_t i_pos; | ||
116 | int type = FILEID_FAT_WITHOUT_PARENT; | ||
117 | |||
118 | if (parent) { | ||
119 | if (len < FAT_FID_SIZE_WITH_PARENT) { | ||
120 | *lenp = FAT_FID_SIZE_WITH_PARENT; | ||
121 | return FILEID_INVALID; | ||
122 | } | ||
123 | } else { | ||
124 | if (len < FAT_FID_SIZE_WITHOUT_PARENT) { | ||
125 | *lenp = FAT_FID_SIZE_WITHOUT_PARENT; | ||
126 | return FILEID_INVALID; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | i_pos = fat_i_pos_read(sbi, inode); | ||
131 | *lenp = FAT_FID_SIZE_WITHOUT_PARENT; | ||
132 | fid->i_gen = inode->i_generation; | ||
133 | fid->i_pos_low = i_pos & 0xFFFFFFFF; | ||
134 | fid->i_pos_hi = (i_pos >> 32) & 0xFFFF; | ||
135 | if (parent) { | ||
136 | i_pos = fat_i_pos_read(sbi, parent); | ||
137 | fid->parent_i_pos_hi = (i_pos >> 32) & 0xFFFF; | ||
138 | fid->parent_i_pos_low = i_pos & 0xFFFFFFFF; | ||
139 | fid->parent_i_gen = parent->i_generation; | ||
140 | type = FILEID_FAT_WITH_PARENT; | ||
141 | *lenp = FAT_FID_SIZE_WITH_PARENT; | ||
142 | } | ||
143 | |||
144 | return type; | ||
145 | } | ||
146 | |||
58 | /** | 147 | /** |
59 | * Map a NFS file handle to a corresponding dentry. | 148 | * Map a NFS file handle to a corresponding dentry. |
60 | * The dentry may or may not be connected to the filesystem root. | 149 | * The dentry may or may not be connected to the filesystem root. |
61 | */ | 150 | */ |
62 | struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, | 151 | static struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, |
63 | int fh_len, int fh_type) | 152 | int fh_len, int fh_type) |
64 | { | 153 | { |
65 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, | 154 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, |
66 | fat_nfs_get_inode); | 155 | fat_nfs_get_inode); |
67 | } | 156 | } |
68 | 157 | ||
158 | static struct dentry *fat_fh_to_dentry_nostale(struct super_block *sb, | ||
159 | struct fid *fh, int fh_len, | ||
160 | int fh_type) | ||
161 | { | ||
162 | struct inode *inode = NULL; | ||
163 | struct fat_fid *fid = (struct fat_fid *)fh; | ||
164 | loff_t i_pos; | ||
165 | |||
166 | switch (fh_type) { | ||
167 | case FILEID_FAT_WITHOUT_PARENT: | ||
168 | if (fh_len < FAT_FID_SIZE_WITHOUT_PARENT) | ||
169 | return NULL; | ||
170 | break; | ||
171 | case FILEID_FAT_WITH_PARENT: | ||
172 | if (fh_len < FAT_FID_SIZE_WITH_PARENT) | ||
173 | return NULL; | ||
174 | break; | ||
175 | default: | ||
176 | return NULL; | ||
177 | } | ||
178 | i_pos = fid->i_pos_hi; | ||
179 | i_pos = (i_pos << 32) | (fid->i_pos_low); | ||
180 | inode = __fat_nfs_get_inode(sb, 0, fid->i_gen, i_pos); | ||
181 | |||
182 | return d_obtain_alias(inode); | ||
183 | } | ||
184 | |||
69 | /* | 185 | /* |
70 | * Find the parent for a file specified by NFS handle. | 186 | * Find the parent for a file specified by NFS handle. |
71 | * This requires that the handle contain the i_ino of the parent. | 187 | * This requires that the handle contain the i_ino of the parent. |
72 | */ | 188 | */ |
73 | struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, | 189 | static struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, |
74 | int fh_len, int fh_type) | 190 | int fh_len, int fh_type) |
75 | { | 191 | { |
76 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, | 192 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, |
77 | fat_nfs_get_inode); | 193 | fat_nfs_get_inode); |
78 | } | 194 | } |
79 | 195 | ||
196 | static struct dentry *fat_fh_to_parent_nostale(struct super_block *sb, | ||
197 | struct fid *fh, int fh_len, | ||
198 | int fh_type) | ||
199 | { | ||
200 | struct inode *inode = NULL; | ||
201 | struct fat_fid *fid = (struct fat_fid *)fh; | ||
202 | loff_t i_pos; | ||
203 | |||
204 | if (fh_len < FAT_FID_SIZE_WITH_PARENT) | ||
205 | return NULL; | ||
206 | |||
207 | switch (fh_type) { | ||
208 | case FILEID_FAT_WITH_PARENT: | ||
209 | i_pos = fid->parent_i_pos_hi; | ||
210 | i_pos = (i_pos << 32) | (fid->parent_i_pos_low); | ||
211 | inode = __fat_nfs_get_inode(sb, 0, fid->parent_i_gen, i_pos); | ||
212 | break; | ||
213 | } | ||
214 | |||
215 | return d_obtain_alias(inode); | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Rebuild the parent for a directory that is not connected | ||
220 | * to the filesystem root | ||
221 | */ | ||
222 | static | ||
223 | struct inode *fat_rebuild_parent(struct super_block *sb, int parent_logstart) | ||
224 | { | ||
225 | int search_clus, clus_to_match; | ||
226 | struct msdos_dir_entry *de; | ||
227 | struct inode *parent = NULL; | ||
228 | struct inode *dummy_grand_parent = NULL; | ||
229 | struct fat_slot_info sinfo; | ||
230 | struct msdos_sb_info *sbi = MSDOS_SB(sb); | ||
231 | sector_t blknr = fat_clus_to_blknr(sbi, parent_logstart); | ||
232 | struct buffer_head *parent_bh = sb_bread(sb, blknr); | ||
233 | if (!parent_bh) { | ||
234 | fat_msg(sb, KERN_ERR, | ||
235 | "unable to read cluster of parent directory"); | ||
236 | return NULL; | ||
237 | } | ||
238 | |||
239 | de = (struct msdos_dir_entry *) parent_bh->b_data; | ||
240 | clus_to_match = fat_get_start(sbi, &de[0]); | ||
241 | search_clus = fat_get_start(sbi, &de[1]); | ||
242 | |||
243 | dummy_grand_parent = fat_dget(sb, search_clus); | ||
244 | if (!dummy_grand_parent) { | ||
245 | dummy_grand_parent = new_inode(sb); | ||
246 | if (!dummy_grand_parent) { | ||
247 | brelse(parent_bh); | ||
248 | return parent; | ||
249 | } | ||
250 | |||
251 | dummy_grand_parent->i_ino = iunique(sb, MSDOS_ROOT_INO); | ||
252 | fat_fill_inode(dummy_grand_parent, &de[1]); | ||
253 | MSDOS_I(dummy_grand_parent)->i_pos = -1; | ||
254 | } | ||
255 | |||
256 | if (!fat_scan_logstart(dummy_grand_parent, clus_to_match, &sinfo)) | ||
257 | parent = fat_build_inode(sb, sinfo.de, sinfo.i_pos); | ||
258 | |||
259 | brelse(parent_bh); | ||
260 | iput(dummy_grand_parent); | ||
261 | |||
262 | return parent; | ||
263 | } | ||
264 | |||
80 | /* | 265 | /* |
81 | * Find the parent for a directory that is not currently connected to | 266 | * Find the parent for a directory that is not currently connected to |
82 | * the filesystem root. | 267 | * the filesystem root. |
83 | * | 268 | * |
84 | * On entry, the caller holds child_dir->d_inode->i_mutex. | 269 | * On entry, the caller holds child_dir->d_inode->i_mutex. |
85 | */ | 270 | */ |
86 | struct dentry *fat_get_parent(struct dentry *child_dir) | 271 | static struct dentry *fat_get_parent(struct dentry *child_dir) |
87 | { | 272 | { |
88 | struct super_block *sb = child_dir->d_sb; | 273 | struct super_block *sb = child_dir->d_sb; |
89 | struct buffer_head *bh = NULL; | 274 | struct buffer_head *bh = NULL; |
90 | struct msdos_dir_entry *de; | 275 | struct msdos_dir_entry *de; |
91 | struct inode *parent_inode = NULL; | 276 | struct inode *parent_inode = NULL; |
277 | struct msdos_sb_info *sbi = MSDOS_SB(sb); | ||
92 | 278 | ||
93 | if (!fat_get_dotdot_entry(child_dir->d_inode, &bh, &de)) { | 279 | if (!fat_get_dotdot_entry(child_dir->d_inode, &bh, &de)) { |
94 | int parent_logstart = fat_get_start(MSDOS_SB(sb), de); | 280 | int parent_logstart = fat_get_start(sbi, de); |
95 | parent_inode = fat_dget(sb, parent_logstart); | 281 | parent_inode = fat_dget(sb, parent_logstart); |
282 | if (!parent_inode && sbi->options.nfs == FAT_NFS_NOSTALE_RO) | ||
283 | parent_inode = fat_rebuild_parent(sb, parent_logstart); | ||
96 | } | 284 | } |
97 | brelse(bh); | 285 | brelse(bh); |
98 | 286 | ||
99 | return d_obtain_alias(parent_inode); | 287 | return d_obtain_alias(parent_inode); |
100 | } | 288 | } |
289 | |||
290 | const struct export_operations fat_export_ops = { | ||
291 | .fh_to_dentry = fat_fh_to_dentry, | ||
292 | .fh_to_parent = fat_fh_to_parent, | ||
293 | .get_parent = fat_get_parent, | ||
294 | }; | ||
295 | |||
296 | const struct export_operations fat_export_ops_nostale = { | ||
297 | .encode_fh = fat_encode_fh_nostale, | ||
298 | .fh_to_dentry = fat_fh_to_dentry_nostale, | ||
299 | .fh_to_parent = fat_fh_to_parent_nostale, | ||
300 | .get_parent = fat_get_parent, | ||
301 | }; | ||
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 21f46fb3a101..798d4458a4d3 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -1028,6 +1028,7 @@ int bdi_writeback_thread(void *data) | |||
1028 | struct backing_dev_info *bdi = wb->bdi; | 1028 | struct backing_dev_info *bdi = wb->bdi; |
1029 | long pages_written; | 1029 | long pages_written; |
1030 | 1030 | ||
1031 | set_worker_desc("flush-%s", dev_name(bdi->dev)); | ||
1031 | current->flags |= PF_SWAPWRITE; | 1032 | current->flags |= PF_SWAPWRITE; |
1032 | set_freezable(); | 1033 | set_freezable(); |
1033 | wb->last_active = jiffies; | 1034 | wb->last_active = jiffies; |
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 8179e8bc4a3d..40d13c70ef51 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c | |||
@@ -287,5 +287,5 @@ const struct file_operations fscache_stats_fops = { | |||
287 | .open = fscache_stats_open, | 287 | .open = fscache_stats_open, |
288 | .read = seq_read, | 288 | .read = seq_read, |
289 | .llseek = seq_lseek, | 289 | .llseek = seq_lseek, |
290 | .release = seq_release, | 290 | .release = single_release, |
291 | }; | 291 | }; |
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 24f414f0ce61..9883694f1e7c 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -1055,7 +1055,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1055 | if (atomic_read(&bh->b_count)) | 1055 | if (atomic_read(&bh->b_count)) |
1056 | goto cannot_release; | 1056 | goto cannot_release; |
1057 | bd = bh->b_private; | 1057 | bd = bh->b_private; |
1058 | if (bd && bd->bd_ail) | 1058 | if (bd && bd->bd_tr) |
1059 | goto cannot_release; | 1059 | goto cannot_release; |
1060 | if (buffer_pinned(bh) || buffer_dirty(bh)) | 1060 | if (buffer_pinned(bh) || buffer_dirty(bh)) |
1061 | goto not_possible; | 1061 | goto not_possible; |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 5e83657f046e..1dc9a13ce6bb 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -787,7 +787,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
787 | goto out_rlist; | 787 | goto out_rlist; |
788 | 788 | ||
789 | if (gfs2_rs_active(ip->i_res)) /* needs to be done with the rgrp glock held */ | 789 | if (gfs2_rs_active(ip->i_res)) /* needs to be done with the rgrp glock held */ |
790 | gfs2_rs_deltree(ip, ip->i_res); | 790 | gfs2_rs_deltree(ip->i_res); |
791 | 791 | ||
792 | error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + | 792 | error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + |
793 | RES_INDIRECT + RES_STATFS + RES_QUOTA, | 793 | RES_INDIRECT + RES_STATFS + RES_QUOTA, |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 019f45e45097..d79c2dadc536 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -923,8 +923,11 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
923 | cmd = F_SETLK; | 923 | cmd = F_SETLK; |
924 | fl->fl_type = F_UNLCK; | 924 | fl->fl_type = F_UNLCK; |
925 | } | 925 | } |
926 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | 926 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { |
927 | if (fl->fl_type == F_UNLCK) | ||
928 | posix_lock_file_wait(file, fl); | ||
927 | return -EIO; | 929 | return -EIO; |
930 | } | ||
928 | if (IS_GETLK(cmd)) | 931 | if (IS_GETLK(cmd)) |
929 | return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); | 932 | return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); |
930 | else if (fl->fl_type == F_UNLCK) | 933 | else if (fl->fl_type == F_UNLCK) |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index cf3515546739..9435384562a2 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -912,7 +912,7 @@ int gfs2_glock_wait(struct gfs2_holder *gh) | |||
912 | */ | 912 | */ |
913 | 913 | ||
914 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, | 914 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, |
915 | unsigned long delay) | 915 | unsigned long delay, bool remote) |
916 | { | 916 | { |
917 | int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE; | 917 | int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE; |
918 | 918 | ||
@@ -925,8 +925,8 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state, | |||
925 | gl->gl_demote_state = LM_ST_UNLOCKED; | 925 | gl->gl_demote_state = LM_ST_UNLOCKED; |
926 | } | 926 | } |
927 | if (gl->gl_ops->go_callback) | 927 | if (gl->gl_ops->go_callback) |
928 | gl->gl_ops->go_callback(gl); | 928 | gl->gl_ops->go_callback(gl, remote); |
929 | trace_gfs2_demote_rq(gl); | 929 | trace_gfs2_demote_rq(gl, remote); |
930 | } | 930 | } |
931 | 931 | ||
932 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) | 932 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) |
@@ -1017,11 +1017,11 @@ do_cancel: | |||
1017 | return; | 1017 | return; |
1018 | 1018 | ||
1019 | trap_recursive: | 1019 | trap_recursive: |
1020 | print_symbol(KERN_ERR "original: %s\n", gh2->gh_ip); | 1020 | printk(KERN_ERR "original: %pSR\n", (void *)gh2->gh_ip); |
1021 | printk(KERN_ERR "pid: %d\n", pid_nr(gh2->gh_owner_pid)); | 1021 | printk(KERN_ERR "pid: %d\n", pid_nr(gh2->gh_owner_pid)); |
1022 | printk(KERN_ERR "lock type: %d req lock state : %d\n", | 1022 | printk(KERN_ERR "lock type: %d req lock state : %d\n", |
1023 | gh2->gh_gl->gl_name.ln_type, gh2->gh_state); | 1023 | gh2->gh_gl->gl_name.ln_type, gh2->gh_state); |
1024 | print_symbol(KERN_ERR "new: %s\n", gh->gh_ip); | 1024 | printk(KERN_ERR "new: %pSR\n", (void *)gh->gh_ip); |
1025 | printk(KERN_ERR "pid: %d\n", pid_nr(gh->gh_owner_pid)); | 1025 | printk(KERN_ERR "pid: %d\n", pid_nr(gh->gh_owner_pid)); |
1026 | printk(KERN_ERR "lock type: %d req lock state : %d\n", | 1026 | printk(KERN_ERR "lock type: %d req lock state : %d\n", |
1027 | gh->gh_gl->gl_name.ln_type, gh->gh_state); | 1027 | gh->gh_gl->gl_name.ln_type, gh->gh_state); |
@@ -1091,7 +1091,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1091 | 1091 | ||
1092 | spin_lock(&gl->gl_spin); | 1092 | spin_lock(&gl->gl_spin); |
1093 | if (gh->gh_flags & GL_NOCACHE) | 1093 | if (gh->gh_flags & GL_NOCACHE) |
1094 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1094 | handle_callback(gl, LM_ST_UNLOCKED, 0, false); |
1095 | 1095 | ||
1096 | list_del_init(&gh->gh_list); | 1096 | list_del_init(&gh->gh_list); |
1097 | if (find_first_holder(gl) == NULL) { | 1097 | if (find_first_holder(gl) == NULL) { |
@@ -1279,19 +1279,6 @@ void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs) | |||
1279 | gfs2_glock_dq(&ghs[num_gh]); | 1279 | gfs2_glock_dq(&ghs[num_gh]); |
1280 | } | 1280 | } |
1281 | 1281 | ||
1282 | /** | ||
1283 | * gfs2_glock_dq_uninit_m - release multiple glocks | ||
1284 | * @num_gh: the number of structures | ||
1285 | * @ghs: an array of struct gfs2_holder structures | ||
1286 | * | ||
1287 | */ | ||
1288 | |||
1289 | void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs) | ||
1290 | { | ||
1291 | while (num_gh--) | ||
1292 | gfs2_glock_dq_uninit(&ghs[num_gh]); | ||
1293 | } | ||
1294 | |||
1295 | void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) | 1282 | void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) |
1296 | { | 1283 | { |
1297 | unsigned long delay = 0; | 1284 | unsigned long delay = 0; |
@@ -1309,7 +1296,7 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) | |||
1309 | } | 1296 | } |
1310 | 1297 | ||
1311 | spin_lock(&gl->gl_spin); | 1298 | spin_lock(&gl->gl_spin); |
1312 | handle_callback(gl, state, delay); | 1299 | handle_callback(gl, state, delay, true); |
1313 | spin_unlock(&gl->gl_spin); | 1300 | spin_unlock(&gl->gl_spin); |
1314 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | 1301 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) |
1315 | gfs2_glock_put(gl); | 1302 | gfs2_glock_put(gl); |
@@ -1422,7 +1409,7 @@ __acquires(&lru_lock) | |||
1422 | spin_unlock(&lru_lock); | 1409 | spin_unlock(&lru_lock); |
1423 | spin_lock(&gl->gl_spin); | 1410 | spin_lock(&gl->gl_spin); |
1424 | if (demote_ok(gl)) | 1411 | if (demote_ok(gl)) |
1425 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1412 | handle_callback(gl, LM_ST_UNLOCKED, 0, false); |
1426 | WARN_ON(!test_and_clear_bit(GLF_LOCK, &gl->gl_flags)); | 1413 | WARN_ON(!test_and_clear_bit(GLF_LOCK, &gl->gl_flags)); |
1427 | smp_mb__after_clear_bit(); | 1414 | smp_mb__after_clear_bit(); |
1428 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1415 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
@@ -1547,7 +1534,7 @@ static void clear_glock(struct gfs2_glock *gl) | |||
1547 | 1534 | ||
1548 | spin_lock(&gl->gl_spin); | 1535 | spin_lock(&gl->gl_spin); |
1549 | if (gl->gl_state != LM_ST_UNLOCKED) | 1536 | if (gl->gl_state != LM_ST_UNLOCKED) |
1550 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1537 | handle_callback(gl, LM_ST_UNLOCKED, 0, false); |
1551 | spin_unlock(&gl->gl_spin); | 1538 | spin_unlock(&gl->gl_spin); |
1552 | gfs2_glock_hold(gl); | 1539 | gfs2_glock_hold(gl); |
1553 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1540 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
@@ -1590,6 +1577,7 @@ static void dump_glock_func(struct gfs2_glock *gl) | |||
1590 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) | 1577 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) |
1591 | { | 1578 | { |
1592 | set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags); | 1579 | set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags); |
1580 | flush_workqueue(glock_workqueue); | ||
1593 | glock_hash_walk(clear_glock, sdp); | 1581 | glock_hash_walk(clear_glock, sdp); |
1594 | flush_workqueue(glock_workqueue); | 1582 | flush_workqueue(glock_workqueue); |
1595 | wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0); | 1583 | wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0); |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index fd580b7861d5..69f66e3d22bf 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -201,7 +201,6 @@ extern int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, | |||
201 | struct gfs2_holder *gh); | 201 | struct gfs2_holder *gh); |
202 | extern int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); | 202 | extern int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); |
203 | extern void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); | 203 | extern void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); |
204 | extern void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs); | ||
205 | extern int gfs2_dump_glock(struct seq_file *seq, const struct gfs2_glock *gl); | 204 | extern int gfs2_dump_glock(struct seq_file *seq, const struct gfs2_glock *gl); |
206 | #define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { gfs2_dump_glock(NULL, gl); BUG(); } } while(0) | 205 | #define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { gfs2_dump_glock(NULL, gl); BUG(); } } while(0) |
207 | extern __printf(2, 3) | 206 | extern __printf(2, 3) |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 444b6503ebc4..c66e99c97571 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -515,12 +515,12 @@ static int trans_go_demote_ok(const struct gfs2_glock *gl) | |||
515 | * | 515 | * |
516 | * gl_spin lock is held while calling this | 516 | * gl_spin lock is held while calling this |
517 | */ | 517 | */ |
518 | static void iopen_go_callback(struct gfs2_glock *gl) | 518 | static void iopen_go_callback(struct gfs2_glock *gl, bool remote) |
519 | { | 519 | { |
520 | struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object; | 520 | struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object; |
521 | struct gfs2_sbd *sdp = gl->gl_sbd; | 521 | struct gfs2_sbd *sdp = gl->gl_sbd; |
522 | 522 | ||
523 | if (sdp->sd_vfs->s_flags & MS_RDONLY) | 523 | if (!remote || (sdp->sd_vfs->s_flags & MS_RDONLY)) |
524 | return; | 524 | return; |
525 | 525 | ||
526 | if (gl->gl_demote_state == LM_ST_UNLOCKED && | 526 | if (gl->gl_demote_state == LM_ST_UNLOCKED && |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 156e42ec84ea..26aabd7caba7 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -31,7 +31,6 @@ struct gfs2_holder; | |||
31 | struct gfs2_glock; | 31 | struct gfs2_glock; |
32 | struct gfs2_quota_data; | 32 | struct gfs2_quota_data; |
33 | struct gfs2_trans; | 33 | struct gfs2_trans; |
34 | struct gfs2_ail; | ||
35 | struct gfs2_jdesc; | 34 | struct gfs2_jdesc; |
36 | struct gfs2_sbd; | 35 | struct gfs2_sbd; |
37 | struct lm_lockops; | 36 | struct lm_lockops; |
@@ -53,7 +52,7 @@ struct gfs2_log_header_host { | |||
53 | 52 | ||
54 | struct gfs2_log_operations { | 53 | struct gfs2_log_operations { |
55 | void (*lo_before_commit) (struct gfs2_sbd *sdp); | 54 | void (*lo_before_commit) (struct gfs2_sbd *sdp); |
56 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); | 55 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_trans *tr); |
57 | void (*lo_before_scan) (struct gfs2_jdesc *jd, | 56 | void (*lo_before_scan) (struct gfs2_jdesc *jd, |
58 | struct gfs2_log_header_host *head, int pass); | 57 | struct gfs2_log_header_host *head, int pass); |
59 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, | 58 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, |
@@ -139,7 +138,7 @@ struct gfs2_bufdata { | |||
139 | struct list_head bd_list; | 138 | struct list_head bd_list; |
140 | const struct gfs2_log_operations *bd_ops; | 139 | const struct gfs2_log_operations *bd_ops; |
141 | 140 | ||
142 | struct gfs2_ail *bd_ail; | 141 | struct gfs2_trans *bd_tr; |
143 | struct list_head bd_ail_st_list; | 142 | struct list_head bd_ail_st_list; |
144 | struct list_head bd_ail_gl_list; | 143 | struct list_head bd_ail_gl_list; |
145 | }; | 144 | }; |
@@ -211,7 +210,7 @@ struct gfs2_glock_operations { | |||
211 | int (*go_lock) (struct gfs2_holder *gh); | 210 | int (*go_lock) (struct gfs2_holder *gh); |
212 | void (*go_unlock) (struct gfs2_holder *gh); | 211 | void (*go_unlock) (struct gfs2_holder *gh); |
213 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); | 212 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); |
214 | void (*go_callback) (struct gfs2_glock *gl); | 213 | void (*go_callback)(struct gfs2_glock *gl, bool remote); |
215 | const int go_type; | 214 | const int go_type; |
216 | const unsigned long go_flags; | 215 | const unsigned long go_flags; |
217 | #define GLOF_ASPACE 1 | 216 | #define GLOF_ASPACE 1 |
@@ -433,6 +432,7 @@ struct gfs2_trans { | |||
433 | struct gfs2_holder tr_t_gh; | 432 | struct gfs2_holder tr_t_gh; |
434 | 433 | ||
435 | int tr_touched; | 434 | int tr_touched; |
435 | int tr_attached; | ||
436 | 436 | ||
437 | unsigned int tr_num_buf_new; | 437 | unsigned int tr_num_buf_new; |
438 | unsigned int tr_num_databuf_new; | 438 | unsigned int tr_num_databuf_new; |
@@ -440,14 +440,12 @@ struct gfs2_trans { | |||
440 | unsigned int tr_num_databuf_rm; | 440 | unsigned int tr_num_databuf_rm; |
441 | unsigned int tr_num_revoke; | 441 | unsigned int tr_num_revoke; |
442 | unsigned int tr_num_revoke_rm; | 442 | unsigned int tr_num_revoke_rm; |
443 | }; | ||
444 | 443 | ||
445 | struct gfs2_ail { | 444 | struct list_head tr_list; |
446 | struct list_head ai_list; | ||
447 | 445 | ||
448 | unsigned int ai_first; | 446 | unsigned int tr_first; |
449 | struct list_head ai_ail1_list; | 447 | struct list_head tr_ail1_list; |
450 | struct list_head ai_ail2_list; | 448 | struct list_head tr_ail2_list; |
451 | }; | 449 | }; |
452 | 450 | ||
453 | struct gfs2_journal_extent { | 451 | struct gfs2_journal_extent { |
@@ -588,6 +586,7 @@ struct lm_lockstruct { | |||
588 | struct dlm_lksb ls_control_lksb; /* control_lock */ | 586 | struct dlm_lksb ls_control_lksb; /* control_lock */ |
589 | char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */ | 587 | char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */ |
590 | struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */ | 588 | struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */ |
589 | char *ls_lvb_bits; | ||
591 | 590 | ||
592 | spinlock_t ls_recover_spin; /* protects following fields */ | 591 | spinlock_t ls_recover_spin; /* protects following fields */ |
593 | unsigned long ls_recover_flags; /* DFL_ */ | 592 | unsigned long ls_recover_flags; /* DFL_ */ |
@@ -709,6 +708,7 @@ struct gfs2_sbd { | |||
709 | 708 | ||
710 | spinlock_t sd_log_lock; | 709 | spinlock_t sd_log_lock; |
711 | 710 | ||
711 | struct gfs2_trans *sd_log_tr; | ||
712 | unsigned int sd_log_blks_reserved; | 712 | unsigned int sd_log_blks_reserved; |
713 | unsigned int sd_log_commited_buf; | 713 | unsigned int sd_log_commited_buf; |
714 | unsigned int sd_log_commited_databuf; | 714 | unsigned int sd_log_commited_databuf; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index cc00bd1d1f87..8833a4f264e3 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -392,11 +392,15 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags) | |||
392 | int error; | 392 | int error; |
393 | int dblocks = 1; | 393 | int dblocks = 1; |
394 | 394 | ||
395 | error = gfs2_inplace_reserve(ip, RES_DINODE, flags); | 395 | error = gfs2_quota_lock_check(ip); |
396 | if (error) | 396 | if (error) |
397 | goto out; | 397 | goto out; |
398 | 398 | ||
399 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0); | 399 | error = gfs2_inplace_reserve(ip, RES_DINODE, flags); |
400 | if (error) | ||
401 | goto out_quota; | ||
402 | |||
403 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 0); | ||
400 | if (error) | 404 | if (error) |
401 | goto out_ipreserv; | 405 | goto out_ipreserv; |
402 | 406 | ||
@@ -409,6 +413,8 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags) | |||
409 | 413 | ||
410 | out_ipreserv: | 414 | out_ipreserv: |
411 | gfs2_inplace_release(ip); | 415 | gfs2_inplace_release(ip); |
416 | out_quota: | ||
417 | gfs2_quota_unlock(ip); | ||
412 | out: | 418 | out: |
413 | return error; | 419 | return error; |
414 | } | 420 | } |
@@ -440,59 +446,27 @@ static void gfs2_init_dir(struct buffer_head *dibh, | |||
440 | */ | 446 | */ |
441 | 447 | ||
442 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | 448 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, |
443 | const char *symname, struct buffer_head **bhp) | 449 | const char *symname) |
444 | { | 450 | { |
445 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
446 | struct gfs2_dinode *di; | 451 | struct gfs2_dinode *di; |
447 | struct buffer_head *dibh; | 452 | struct buffer_head *dibh; |
448 | struct timespec tv = CURRENT_TIME; | ||
449 | 453 | ||
450 | dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr); | 454 | dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr); |
451 | gfs2_trans_add_meta(ip->i_gl, dibh); | 455 | gfs2_trans_add_meta(ip->i_gl, dibh); |
452 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); | ||
453 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | ||
454 | di = (struct gfs2_dinode *)dibh->b_data; | 456 | di = (struct gfs2_dinode *)dibh->b_data; |
457 | gfs2_dinode_out(ip, di); | ||
455 | 458 | ||
456 | di->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | ||
457 | di->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | ||
458 | di->di_mode = cpu_to_be32(ip->i_inode.i_mode); | ||
459 | di->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode)); | ||
460 | di->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode)); | ||
461 | di->di_nlink = 0; | ||
462 | di->di_size = cpu_to_be64(ip->i_inode.i_size); | ||
463 | di->di_blocks = cpu_to_be64(1); | ||
464 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); | ||
465 | di->di_major = cpu_to_be32(MAJOR(ip->i_inode.i_rdev)); | 459 | di->di_major = cpu_to_be32(MAJOR(ip->i_inode.i_rdev)); |
466 | di->di_minor = cpu_to_be32(MINOR(ip->i_inode.i_rdev)); | 460 | di->di_minor = cpu_to_be32(MINOR(ip->i_inode.i_rdev)); |
467 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_no_addr); | ||
468 | di->di_generation = cpu_to_be64(ip->i_generation); | ||
469 | di->di_flags = 0; | ||
470 | di->__pad1 = 0; | 461 | di->__pad1 = 0; |
471 | di->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) ? GFS2_FORMAT_DE : 0); | ||
472 | di->di_height = 0; | ||
473 | di->__pad2 = 0; | 462 | di->__pad2 = 0; |
474 | di->__pad3 = 0; | 463 | di->__pad3 = 0; |
475 | di->di_depth = 0; | ||
476 | di->di_entries = 0; | ||
477 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 464 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
478 | di->di_eattr = 0; | ||
479 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); | ||
480 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); | ||
481 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | ||
482 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 465 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
466 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | ||
483 | 467 | ||
484 | switch(ip->i_inode.i_mode & S_IFMT) { | 468 | switch(ip->i_inode.i_mode & S_IFMT) { |
485 | case S_IFREG: | ||
486 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
487 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
488 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
489 | break; | ||
490 | case S_IFDIR: | 469 | case S_IFDIR: |
491 | di->di_flags |= cpu_to_be32(dip->i_diskflags & | ||
492 | GFS2_DIF_INHERIT_JDATA); | ||
493 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
494 | di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)); | ||
495 | di->di_entries = cpu_to_be32(2); | ||
496 | gfs2_init_dir(dibh, dip); | 470 | gfs2_init_dir(dibh, dip); |
497 | break; | 471 | break; |
498 | case S_IFLNK: | 472 | case S_IFLNK: |
@@ -501,63 +475,17 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
501 | } | 475 | } |
502 | 476 | ||
503 | set_buffer_uptodate(dibh); | 477 | set_buffer_uptodate(dibh); |
504 | 478 | brelse(dibh); | |
505 | *bhp = dibh; | ||
506 | } | ||
507 | |||
508 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | ||
509 | const char *symname, struct buffer_head **bhp) | ||
510 | { | ||
511 | struct inode *inode = &ip->i_inode; | ||
512 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
513 | int error; | ||
514 | |||
515 | error = gfs2_rindex_update(sdp); | ||
516 | if (error) | ||
517 | return error; | ||
518 | |||
519 | error = gfs2_quota_lock(dip, inode->i_uid, inode->i_gid); | ||
520 | if (error) | ||
521 | return error; | ||
522 | |||
523 | error = gfs2_quota_check(dip, inode->i_uid, inode->i_gid); | ||
524 | if (error) | ||
525 | goto out_quota; | ||
526 | |||
527 | error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0); | ||
528 | if (error) | ||
529 | goto out_quota; | ||
530 | |||
531 | init_dinode(dip, ip, symname, bhp); | ||
532 | gfs2_quota_change(dip, +1, inode->i_uid, inode->i_gid); | ||
533 | gfs2_trans_end(sdp); | ||
534 | |||
535 | out_quota: | ||
536 | gfs2_quota_unlock(dip); | ||
537 | return error; | ||
538 | } | 479 | } |
539 | 480 | ||
540 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | 481 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, |
541 | struct gfs2_inode *ip) | 482 | struct gfs2_inode *ip, int arq) |
542 | { | 483 | { |
543 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 484 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
544 | int alloc_required; | ||
545 | struct buffer_head *dibh; | ||
546 | int error; | 485 | int error; |
547 | 486 | ||
548 | error = gfs2_rindex_update(sdp); | 487 | if (arq) { |
549 | if (error) | 488 | error = gfs2_quota_lock_check(dip); |
550 | return error; | ||
551 | |||
552 | error = gfs2_quota_lock(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); | ||
553 | if (error) | ||
554 | goto fail; | ||
555 | |||
556 | error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); | ||
557 | if (alloc_required < 0) | ||
558 | goto fail_quota_locks; | ||
559 | if (alloc_required) { | ||
560 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); | ||
561 | if (error) | 489 | if (error) |
562 | goto fail_quota_locks; | 490 | goto fail_quota_locks; |
563 | 491 | ||
@@ -581,26 +509,12 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
581 | if (error) | 509 | if (error) |
582 | goto fail_end_trans; | 510 | goto fail_end_trans; |
583 | 511 | ||
584 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
585 | if (error) | ||
586 | goto fail_end_trans; | ||
587 | set_nlink(&ip->i_inode, S_ISDIR(ip->i_inode.i_mode) ? 2 : 1); | ||
588 | gfs2_trans_add_meta(ip->i_gl, dibh); | ||
589 | gfs2_dinode_out(ip, dibh->b_data); | ||
590 | brelse(dibh); | ||
591 | return 0; | ||
592 | |||
593 | fail_end_trans: | 512 | fail_end_trans: |
594 | gfs2_trans_end(sdp); | 513 | gfs2_trans_end(sdp); |
595 | |||
596 | fail_ipreserv: | 514 | fail_ipreserv: |
597 | if (alloc_required) | 515 | gfs2_inplace_release(dip); |
598 | gfs2_inplace_release(dip); | ||
599 | |||
600 | fail_quota_locks: | 516 | fail_quota_locks: |
601 | gfs2_quota_unlock(dip); | 517 | gfs2_quota_unlock(dip); |
602 | |||
603 | fail: | ||
604 | return error; | 518 | return error; |
605 | } | 519 | } |
606 | 520 | ||
@@ -650,8 +564,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
650 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 564 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
651 | struct gfs2_glock *io_gl; | 565 | struct gfs2_glock *io_gl; |
652 | int error; | 566 | int error; |
653 | struct buffer_head *bh = NULL; | ||
654 | u32 aflags = 0; | 567 | u32 aflags = 0; |
568 | int arq; | ||
655 | 569 | ||
656 | if (!name->len || name->len > GFS2_FNAMESIZE) | 570 | if (!name->len || name->len > GFS2_FNAMESIZE) |
657 | return -ENAMETOOLONG; | 571 | return -ENAMETOOLONG; |
@@ -660,6 +574,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
660 | if (error) | 574 | if (error) |
661 | return error; | 575 | return error; |
662 | 576 | ||
577 | error = gfs2_rindex_update(sdp); | ||
578 | if (error) | ||
579 | return error; | ||
580 | |||
663 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 581 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
664 | if (error) | 582 | if (error) |
665 | goto fail; | 583 | goto fail; |
@@ -674,22 +592,48 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
674 | if (error) | 592 | if (error) |
675 | goto fail_gunlock; | 593 | goto fail_gunlock; |
676 | 594 | ||
595 | arq = error = gfs2_diradd_alloc_required(dir, name); | ||
596 | if (error < 0) | ||
597 | goto fail_gunlock; | ||
598 | |||
677 | inode = new_inode(sdp->sd_vfs); | 599 | inode = new_inode(sdp->sd_vfs); |
678 | if (!inode) { | 600 | error = -ENOMEM; |
679 | gfs2_glock_dq_uninit(ghs); | 601 | if (!inode) |
680 | return -ENOMEM; | 602 | goto fail_gunlock; |
681 | } | 603 | |
682 | ip = GFS2_I(inode); | 604 | ip = GFS2_I(inode); |
683 | error = gfs2_rs_alloc(ip); | 605 | error = gfs2_rs_alloc(ip); |
684 | if (error) | 606 | if (error) |
685 | goto fail_free_inode; | 607 | goto fail_free_inode; |
686 | 608 | ||
687 | set_bit(GIF_INVALID, &ip->i_flags); | ||
688 | inode->i_mode = mode; | 609 | inode->i_mode = mode; |
610 | set_nlink(inode, S_ISDIR(mode) ? 2 : 1); | ||
689 | inode->i_rdev = dev; | 611 | inode->i_rdev = dev; |
690 | inode->i_size = size; | 612 | inode->i_size = size; |
613 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
614 | gfs2_set_inode_blocks(inode, 1); | ||
691 | munge_mode_uid_gid(dip, inode); | 615 | munge_mode_uid_gid(dip, inode); |
692 | ip->i_goal = dip->i_goal; | 616 | ip->i_goal = dip->i_goal; |
617 | ip->i_diskflags = 0; | ||
618 | ip->i_eattr = 0; | ||
619 | ip->i_height = 0; | ||
620 | ip->i_depth = 0; | ||
621 | ip->i_entries = 0; | ||
622 | |||
623 | switch(mode & S_IFMT) { | ||
624 | case S_IFREG: | ||
625 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
626 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
627 | ip->i_diskflags |= GFS2_DIF_JDATA; | ||
628 | gfs2_set_aops(inode); | ||
629 | break; | ||
630 | case S_IFDIR: | ||
631 | ip->i_diskflags |= (dip->i_diskflags & GFS2_DIF_INHERIT_JDATA); | ||
632 | ip->i_diskflags |= GFS2_DIF_JDATA; | ||
633 | ip->i_entries = 2; | ||
634 | break; | ||
635 | } | ||
636 | gfs2_set_inode_flags(inode); | ||
693 | 637 | ||
694 | if ((GFS2_I(sdp->sd_root_dir->d_inode) == dip) || | 638 | if ((GFS2_I(sdp->sd_root_dir->d_inode) == dip) || |
695 | (dip->i_diskflags & GFS2_DIF_TOPDIR)) | 639 | (dip->i_diskflags & GFS2_DIF_TOPDIR)) |
@@ -708,10 +652,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
708 | if (error) | 652 | if (error) |
709 | goto fail_free_inode; | 653 | goto fail_free_inode; |
710 | 654 | ||
711 | error = make_dinode(dip, ip, symname, &bh); | 655 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
712 | if (error) | 656 | if (error) |
713 | goto fail_gunlock2; | 657 | goto fail_gunlock2; |
714 | 658 | ||
659 | init_dinode(dip, ip, symname); | ||
660 | gfs2_trans_end(sdp); | ||
661 | |||
715 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 662 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
716 | if (error) | 663 | if (error) |
717 | goto fail_gunlock2; | 664 | goto fail_gunlock2; |
@@ -725,10 +672,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
725 | gfs2_set_iop(inode); | 672 | gfs2_set_iop(inode); |
726 | insert_inode_hash(inode); | 673 | insert_inode_hash(inode); |
727 | 674 | ||
728 | error = gfs2_inode_refresh(ip); | ||
729 | if (error) | ||
730 | goto fail_gunlock3; | ||
731 | |||
732 | error = gfs2_acl_create(dip, inode); | 675 | error = gfs2_acl_create(dip, inode); |
733 | if (error) | 676 | if (error) |
734 | goto fail_gunlock3; | 677 | goto fail_gunlock3; |
@@ -737,18 +680,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
737 | if (error) | 680 | if (error) |
738 | goto fail_gunlock3; | 681 | goto fail_gunlock3; |
739 | 682 | ||
740 | error = link_dinode(dip, name, ip); | 683 | error = link_dinode(dip, name, ip, arq); |
741 | if (error) | 684 | if (error) |
742 | goto fail_gunlock3; | 685 | goto fail_gunlock3; |
743 | 686 | ||
744 | if (bh) | ||
745 | brelse(bh); | ||
746 | |||
747 | gfs2_trans_end(sdp); | ||
748 | gfs2_inplace_release(dip); | ||
749 | gfs2_quota_unlock(dip); | ||
750 | mark_inode_dirty(inode); | 687 | mark_inode_dirty(inode); |
751 | gfs2_glock_dq_uninit_m(2, ghs); | 688 | gfs2_glock_dq_uninit(ghs); |
689 | gfs2_glock_dq_uninit(ghs + 1); | ||
752 | d_instantiate(dentry, inode); | 690 | d_instantiate(dentry, inode); |
753 | return 0; | 691 | return 0; |
754 | 692 | ||
@@ -769,12 +707,12 @@ fail_free_inode: | |||
769 | fail_gunlock: | 707 | fail_gunlock: |
770 | gfs2_glock_dq_uninit(ghs); | 708 | gfs2_glock_dq_uninit(ghs); |
771 | if (inode && !IS_ERR(inode)) { | 709 | if (inode && !IS_ERR(inode)) { |
710 | clear_nlink(inode); | ||
711 | mark_inode_dirty(inode); | ||
772 | set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags); | 712 | set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags); |
773 | iput(inode); | 713 | iput(inode); |
774 | } | 714 | } |
775 | fail: | 715 | fail: |
776 | if (bh) | ||
777 | brelse(bh); | ||
778 | return error; | 716 | return error; |
779 | } | 717 | } |
780 | 718 | ||
@@ -1151,7 +1089,9 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
1151 | 1089 | ||
1152 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 1090 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
1153 | { | 1091 | { |
1154 | return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0, 0); | 1092 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
1093 | unsigned dsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | ||
1094 | return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, dsize, 0); | ||
1155 | } | 1095 | } |
1156 | 1096 | ||
1157 | /** | 1097 | /** |
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 9802de0f85e6..c8423d6de6c3 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c | |||
@@ -483,12 +483,8 @@ static void control_lvb_write(struct lm_lockstruct *ls, uint32_t lvb_gen, | |||
483 | 483 | ||
484 | static int all_jid_bits_clear(char *lvb) | 484 | static int all_jid_bits_clear(char *lvb) |
485 | { | 485 | { |
486 | int i; | 486 | return !memchr_inv(lvb + JID_BITMAP_OFFSET, 0, |
487 | for (i = JID_BITMAP_OFFSET; i < GDLM_LVB_SIZE; i++) { | 487 | GDLM_LVB_SIZE - JID_BITMAP_OFFSET); |
488 | if (lvb[i]) | ||
489 | return 0; | ||
490 | } | ||
491 | return 1; | ||
492 | } | 488 | } |
493 | 489 | ||
494 | static void sync_wait_cb(void *arg) | 490 | static void sync_wait_cb(void *arg) |
@@ -580,7 +576,6 @@ static void gfs2_control_func(struct work_struct *work) | |||
580 | { | 576 | { |
581 | struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work); | 577 | struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work); |
582 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 578 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
583 | char lvb_bits[GDLM_LVB_SIZE]; | ||
584 | uint32_t block_gen, start_gen, lvb_gen, flags; | 579 | uint32_t block_gen, start_gen, lvb_gen, flags; |
585 | int recover_set = 0; | 580 | int recover_set = 0; |
586 | int write_lvb = 0; | 581 | int write_lvb = 0; |
@@ -634,7 +629,7 @@ static void gfs2_control_func(struct work_struct *work) | |||
634 | return; | 629 | return; |
635 | } | 630 | } |
636 | 631 | ||
637 | control_lvb_read(ls, &lvb_gen, lvb_bits); | 632 | control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); |
638 | 633 | ||
639 | spin_lock(&ls->ls_recover_spin); | 634 | spin_lock(&ls->ls_recover_spin); |
640 | if (block_gen != ls->ls_recover_block || | 635 | if (block_gen != ls->ls_recover_block || |
@@ -664,10 +659,10 @@ static void gfs2_control_func(struct work_struct *work) | |||
664 | 659 | ||
665 | ls->ls_recover_result[i] = 0; | 660 | ls->ls_recover_result[i] = 0; |
666 | 661 | ||
667 | if (!test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) | 662 | if (!test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) |
668 | continue; | 663 | continue; |
669 | 664 | ||
670 | __clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); | 665 | __clear_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); |
671 | write_lvb = 1; | 666 | write_lvb = 1; |
672 | } | 667 | } |
673 | } | 668 | } |
@@ -691,7 +686,7 @@ static void gfs2_control_func(struct work_struct *work) | |||
691 | continue; | 686 | continue; |
692 | if (ls->ls_recover_submit[i] < start_gen) { | 687 | if (ls->ls_recover_submit[i] < start_gen) { |
693 | ls->ls_recover_submit[i] = 0; | 688 | ls->ls_recover_submit[i] = 0; |
694 | __set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); | 689 | __set_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); |
695 | } | 690 | } |
696 | } | 691 | } |
697 | /* even if there are no bits to set, we need to write the | 692 | /* even if there are no bits to set, we need to write the |
@@ -705,7 +700,7 @@ static void gfs2_control_func(struct work_struct *work) | |||
705 | spin_unlock(&ls->ls_recover_spin); | 700 | spin_unlock(&ls->ls_recover_spin); |
706 | 701 | ||
707 | if (write_lvb) { | 702 | if (write_lvb) { |
708 | control_lvb_write(ls, start_gen, lvb_bits); | 703 | control_lvb_write(ls, start_gen, ls->ls_lvb_bits); |
709 | flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK; | 704 | flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK; |
710 | } else { | 705 | } else { |
711 | flags = DLM_LKF_CONVERT; | 706 | flags = DLM_LKF_CONVERT; |
@@ -725,7 +720,7 @@ static void gfs2_control_func(struct work_struct *work) | |||
725 | */ | 720 | */ |
726 | 721 | ||
727 | for (i = 0; i < recover_size; i++) { | 722 | for (i = 0; i < recover_size; i++) { |
728 | if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) { | 723 | if (test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) { |
729 | fs_info(sdp, "recover generation %u jid %d\n", | 724 | fs_info(sdp, "recover generation %u jid %d\n", |
730 | start_gen, i); | 725 | start_gen, i); |
731 | gfs2_recover_set(sdp, i); | 726 | gfs2_recover_set(sdp, i); |
@@ -758,7 +753,6 @@ static void gfs2_control_func(struct work_struct *work) | |||
758 | static int control_mount(struct gfs2_sbd *sdp) | 753 | static int control_mount(struct gfs2_sbd *sdp) |
759 | { | 754 | { |
760 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 755 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
761 | char lvb_bits[GDLM_LVB_SIZE]; | ||
762 | uint32_t start_gen, block_gen, mount_gen, lvb_gen; | 756 | uint32_t start_gen, block_gen, mount_gen, lvb_gen; |
763 | int mounted_mode; | 757 | int mounted_mode; |
764 | int retries = 0; | 758 | int retries = 0; |
@@ -857,7 +851,7 @@ locks_done: | |||
857 | * lvb_gen will be non-zero. | 851 | * lvb_gen will be non-zero. |
858 | */ | 852 | */ |
859 | 853 | ||
860 | control_lvb_read(ls, &lvb_gen, lvb_bits); | 854 | control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); |
861 | 855 | ||
862 | if (lvb_gen == 0xFFFFFFFF) { | 856 | if (lvb_gen == 0xFFFFFFFF) { |
863 | /* special value to force mount attempts to fail */ | 857 | /* special value to force mount attempts to fail */ |
@@ -887,7 +881,7 @@ locks_done: | |||
887 | * and all lvb bits to be clear (no pending journal recoveries.) | 881 | * and all lvb bits to be clear (no pending journal recoveries.) |
888 | */ | 882 | */ |
889 | 883 | ||
890 | if (!all_jid_bits_clear(lvb_bits)) { | 884 | if (!all_jid_bits_clear(ls->ls_lvb_bits)) { |
891 | /* journals need recovery, wait until all are clear */ | 885 | /* journals need recovery, wait until all are clear */ |
892 | fs_info(sdp, "control_mount wait for journal recovery\n"); | 886 | fs_info(sdp, "control_mount wait for journal recovery\n"); |
893 | goto restart; | 887 | goto restart; |
@@ -949,7 +943,6 @@ static int dlm_recovery_wait(void *word) | |||
949 | static int control_first_done(struct gfs2_sbd *sdp) | 943 | static int control_first_done(struct gfs2_sbd *sdp) |
950 | { | 944 | { |
951 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 945 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
952 | char lvb_bits[GDLM_LVB_SIZE]; | ||
953 | uint32_t start_gen, block_gen; | 946 | uint32_t start_gen, block_gen; |
954 | int error; | 947 | int error; |
955 | 948 | ||
@@ -991,8 +984,8 @@ restart: | |||
991 | memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t)); | 984 | memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t)); |
992 | spin_unlock(&ls->ls_recover_spin); | 985 | spin_unlock(&ls->ls_recover_spin); |
993 | 986 | ||
994 | memset(lvb_bits, 0, sizeof(lvb_bits)); | 987 | memset(ls->ls_lvb_bits, 0, GDLM_LVB_SIZE); |
995 | control_lvb_write(ls, start_gen, lvb_bits); | 988 | control_lvb_write(ls, start_gen, ls->ls_lvb_bits); |
996 | 989 | ||
997 | error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT); | 990 | error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT); |
998 | if (error) | 991 | if (error) |
@@ -1022,6 +1015,12 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, | |||
1022 | uint32_t old_size, new_size; | 1015 | uint32_t old_size, new_size; |
1023 | int i, max_jid; | 1016 | int i, max_jid; |
1024 | 1017 | ||
1018 | if (!ls->ls_lvb_bits) { | ||
1019 | ls->ls_lvb_bits = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); | ||
1020 | if (!ls->ls_lvb_bits) | ||
1021 | return -ENOMEM; | ||
1022 | } | ||
1023 | |||
1025 | max_jid = 0; | 1024 | max_jid = 0; |
1026 | for (i = 0; i < num_slots; i++) { | 1025 | for (i = 0; i < num_slots; i++) { |
1027 | if (max_jid < slots[i].slot - 1) | 1026 | if (max_jid < slots[i].slot - 1) |
@@ -1057,6 +1056,7 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, | |||
1057 | 1056 | ||
1058 | static void free_recover_size(struct lm_lockstruct *ls) | 1057 | static void free_recover_size(struct lm_lockstruct *ls) |
1059 | { | 1058 | { |
1059 | kfree(ls->ls_lvb_bits); | ||
1060 | kfree(ls->ls_recover_submit); | 1060 | kfree(ls->ls_recover_submit); |
1061 | kfree(ls->ls_recover_result); | 1061 | kfree(ls->ls_recover_result); |
1062 | ls->ls_recover_submit = NULL; | 1062 | ls->ls_recover_submit = NULL; |
@@ -1205,6 +1205,7 @@ static int gdlm_mount(struct gfs2_sbd *sdp, const char *table) | |||
1205 | ls->ls_recover_size = 0; | 1205 | ls->ls_recover_size = 0; |
1206 | ls->ls_recover_submit = NULL; | 1206 | ls->ls_recover_submit = NULL; |
1207 | ls->ls_recover_result = NULL; | 1207 | ls->ls_recover_result = NULL; |
1208 | ls->ls_lvb_bits = NULL; | ||
1208 | 1209 | ||
1209 | error = set_recover_size(sdp, NULL, 0); | 1210 | error = set_recover_size(sdp, NULL, 0); |
1210 | if (error) | 1211 | if (error) |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 9a2ca8be7647..b404f4853034 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -73,7 +73,7 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | |||
73 | 73 | ||
74 | void gfs2_remove_from_ail(struct gfs2_bufdata *bd) | 74 | void gfs2_remove_from_ail(struct gfs2_bufdata *bd) |
75 | { | 75 | { |
76 | bd->bd_ail = NULL; | 76 | bd->bd_tr = NULL; |
77 | list_del_init(&bd->bd_ail_st_list); | 77 | list_del_init(&bd->bd_ail_st_list); |
78 | list_del_init(&bd->bd_ail_gl_list); | 78 | list_del_init(&bd->bd_ail_gl_list); |
79 | atomic_dec(&bd->bd_gl->gl_ail_count); | 79 | atomic_dec(&bd->bd_gl->gl_ail_count); |
@@ -90,7 +90,7 @@ void gfs2_remove_from_ail(struct gfs2_bufdata *bd) | |||
90 | 90 | ||
91 | static int gfs2_ail1_start_one(struct gfs2_sbd *sdp, | 91 | static int gfs2_ail1_start_one(struct gfs2_sbd *sdp, |
92 | struct writeback_control *wbc, | 92 | struct writeback_control *wbc, |
93 | struct gfs2_ail *ai) | 93 | struct gfs2_trans *tr) |
94 | __releases(&sdp->sd_ail_lock) | 94 | __releases(&sdp->sd_ail_lock) |
95 | __acquires(&sdp->sd_ail_lock) | 95 | __acquires(&sdp->sd_ail_lock) |
96 | { | 96 | { |
@@ -99,15 +99,15 @@ __acquires(&sdp->sd_ail_lock) | |||
99 | struct gfs2_bufdata *bd, *s; | 99 | struct gfs2_bufdata *bd, *s; |
100 | struct buffer_head *bh; | 100 | struct buffer_head *bh; |
101 | 101 | ||
102 | list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list, bd_ail_st_list) { | 102 | list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) { |
103 | bh = bd->bd_bh; | 103 | bh = bd->bd_bh; |
104 | 104 | ||
105 | gfs2_assert(sdp, bd->bd_ail == ai); | 105 | gfs2_assert(sdp, bd->bd_tr == tr); |
106 | 106 | ||
107 | if (!buffer_busy(bh)) { | 107 | if (!buffer_busy(bh)) { |
108 | if (!buffer_uptodate(bh)) | 108 | if (!buffer_uptodate(bh)) |
109 | gfs2_io_error_bh(sdp, bh); | 109 | gfs2_io_error_bh(sdp, bh); |
110 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); | 110 | list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); |
111 | continue; | 111 | continue; |
112 | } | 112 | } |
113 | 113 | ||
@@ -116,7 +116,7 @@ __acquires(&sdp->sd_ail_lock) | |||
116 | if (gl == bd->bd_gl) | 116 | if (gl == bd->bd_gl) |
117 | continue; | 117 | continue; |
118 | gl = bd->bd_gl; | 118 | gl = bd->bd_gl; |
119 | list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list); | 119 | list_move(&bd->bd_ail_st_list, &tr->tr_ail1_list); |
120 | mapping = bh->b_page->mapping; | 120 | mapping = bh->b_page->mapping; |
121 | if (!mapping) | 121 | if (!mapping) |
122 | continue; | 122 | continue; |
@@ -144,15 +144,15 @@ __acquires(&sdp->sd_ail_lock) | |||
144 | void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) | 144 | void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) |
145 | { | 145 | { |
146 | struct list_head *head = &sdp->sd_ail1_list; | 146 | struct list_head *head = &sdp->sd_ail1_list; |
147 | struct gfs2_ail *ai; | 147 | struct gfs2_trans *tr; |
148 | 148 | ||
149 | trace_gfs2_ail_flush(sdp, wbc, 1); | 149 | trace_gfs2_ail_flush(sdp, wbc, 1); |
150 | spin_lock(&sdp->sd_ail_lock); | 150 | spin_lock(&sdp->sd_ail_lock); |
151 | restart: | 151 | restart: |
152 | list_for_each_entry_reverse(ai, head, ai_list) { | 152 | list_for_each_entry_reverse(tr, head, tr_list) { |
153 | if (wbc->nr_to_write <= 0) | 153 | if (wbc->nr_to_write <= 0) |
154 | break; | 154 | break; |
155 | if (gfs2_ail1_start_one(sdp, wbc, ai)) | 155 | if (gfs2_ail1_start_one(sdp, wbc, tr)) |
156 | goto restart; | 156 | goto restart; |
157 | } | 157 | } |
158 | spin_unlock(&sdp->sd_ail_lock); | 158 | spin_unlock(&sdp->sd_ail_lock); |
@@ -183,20 +183,20 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp) | |||
183 | * | 183 | * |
184 | */ | 184 | */ |
185 | 185 | ||
186 | static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 186 | static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
187 | { | 187 | { |
188 | struct gfs2_bufdata *bd, *s; | 188 | struct gfs2_bufdata *bd, *s; |
189 | struct buffer_head *bh; | 189 | struct buffer_head *bh; |
190 | 190 | ||
191 | list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list, | 191 | list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, |
192 | bd_ail_st_list) { | 192 | bd_ail_st_list) { |
193 | bh = bd->bd_bh; | 193 | bh = bd->bd_bh; |
194 | gfs2_assert(sdp, bd->bd_ail == ai); | 194 | gfs2_assert(sdp, bd->bd_tr == tr); |
195 | if (buffer_busy(bh)) | 195 | if (buffer_busy(bh)) |
196 | continue; | 196 | continue; |
197 | if (!buffer_uptodate(bh)) | 197 | if (!buffer_uptodate(bh)) |
198 | gfs2_io_error_bh(sdp, bh); | 198 | gfs2_io_error_bh(sdp, bh); |
199 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); | 199 | list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); |
200 | } | 200 | } |
201 | 201 | ||
202 | } | 202 | } |
@@ -210,14 +210,14 @@ static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
210 | 210 | ||
211 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp) | 211 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp) |
212 | { | 212 | { |
213 | struct gfs2_ail *ai, *s; | 213 | struct gfs2_trans *tr, *s; |
214 | int ret; | 214 | int ret; |
215 | 215 | ||
216 | spin_lock(&sdp->sd_ail_lock); | 216 | spin_lock(&sdp->sd_ail_lock); |
217 | list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) { | 217 | list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) { |
218 | gfs2_ail1_empty_one(sdp, ai); | 218 | gfs2_ail1_empty_one(sdp, tr); |
219 | if (list_empty(&ai->ai_ail1_list)) | 219 | if (list_empty(&tr->tr_ail1_list)) |
220 | list_move(&ai->ai_list, &sdp->sd_ail2_list); | 220 | list_move(&tr->tr_list, &sdp->sd_ail2_list); |
221 | else | 221 | else |
222 | break; | 222 | break; |
223 | } | 223 | } |
@@ -229,13 +229,13 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp) | |||
229 | 229 | ||
230 | static void gfs2_ail1_wait(struct gfs2_sbd *sdp) | 230 | static void gfs2_ail1_wait(struct gfs2_sbd *sdp) |
231 | { | 231 | { |
232 | struct gfs2_ail *ai; | 232 | struct gfs2_trans *tr; |
233 | struct gfs2_bufdata *bd; | 233 | struct gfs2_bufdata *bd; |
234 | struct buffer_head *bh; | 234 | struct buffer_head *bh; |
235 | 235 | ||
236 | spin_lock(&sdp->sd_ail_lock); | 236 | spin_lock(&sdp->sd_ail_lock); |
237 | list_for_each_entry_reverse(ai, &sdp->sd_ail1_list, ai_list) { | 237 | list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) { |
238 | list_for_each_entry(bd, &ai->ai_ail1_list, bd_ail_st_list) { | 238 | list_for_each_entry(bd, &tr->tr_ail1_list, bd_ail_st_list) { |
239 | bh = bd->bd_bh; | 239 | bh = bd->bd_bh; |
240 | if (!buffer_locked(bh)) | 240 | if (!buffer_locked(bh)) |
241 | continue; | 241 | continue; |
@@ -256,40 +256,40 @@ static void gfs2_ail1_wait(struct gfs2_sbd *sdp) | |||
256 | * | 256 | * |
257 | */ | 257 | */ |
258 | 258 | ||
259 | static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 259 | static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
260 | { | 260 | { |
261 | struct list_head *head = &ai->ai_ail2_list; | 261 | struct list_head *head = &tr->tr_ail2_list; |
262 | struct gfs2_bufdata *bd; | 262 | struct gfs2_bufdata *bd; |
263 | 263 | ||
264 | while (!list_empty(head)) { | 264 | while (!list_empty(head)) { |
265 | bd = list_entry(head->prev, struct gfs2_bufdata, | 265 | bd = list_entry(head->prev, struct gfs2_bufdata, |
266 | bd_ail_st_list); | 266 | bd_ail_st_list); |
267 | gfs2_assert(sdp, bd->bd_ail == ai); | 267 | gfs2_assert(sdp, bd->bd_tr == tr); |
268 | gfs2_remove_from_ail(bd); | 268 | gfs2_remove_from_ail(bd); |
269 | } | 269 | } |
270 | } | 270 | } |
271 | 271 | ||
272 | static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | 272 | static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) |
273 | { | 273 | { |
274 | struct gfs2_ail *ai, *safe; | 274 | struct gfs2_trans *tr, *safe; |
275 | unsigned int old_tail = sdp->sd_log_tail; | 275 | unsigned int old_tail = sdp->sd_log_tail; |
276 | int wrap = (new_tail < old_tail); | 276 | int wrap = (new_tail < old_tail); |
277 | int a, b, rm; | 277 | int a, b, rm; |
278 | 278 | ||
279 | spin_lock(&sdp->sd_ail_lock); | 279 | spin_lock(&sdp->sd_ail_lock); |
280 | 280 | ||
281 | list_for_each_entry_safe(ai, safe, &sdp->sd_ail2_list, ai_list) { | 281 | list_for_each_entry_safe(tr, safe, &sdp->sd_ail2_list, tr_list) { |
282 | a = (old_tail <= ai->ai_first); | 282 | a = (old_tail <= tr->tr_first); |
283 | b = (ai->ai_first < new_tail); | 283 | b = (tr->tr_first < new_tail); |
284 | rm = (wrap) ? (a || b) : (a && b); | 284 | rm = (wrap) ? (a || b) : (a && b); |
285 | if (!rm) | 285 | if (!rm) |
286 | continue; | 286 | continue; |
287 | 287 | ||
288 | gfs2_ail2_empty_one(sdp, ai); | 288 | gfs2_ail2_empty_one(sdp, tr); |
289 | list_del(&ai->ai_list); | 289 | list_del(&tr->tr_list); |
290 | gfs2_assert_warn(sdp, list_empty(&ai->ai_ail1_list)); | 290 | gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); |
291 | gfs2_assert_warn(sdp, list_empty(&ai->ai_ail2_list)); | 291 | gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); |
292 | kfree(ai); | 292 | kfree(tr); |
293 | } | 293 | } |
294 | 294 | ||
295 | spin_unlock(&sdp->sd_ail_lock); | 295 | spin_unlock(&sdp->sd_ail_lock); |
@@ -435,7 +435,7 @@ static unsigned int calc_reserved(struct gfs2_sbd *sdp) | |||
435 | 435 | ||
436 | static unsigned int current_tail(struct gfs2_sbd *sdp) | 436 | static unsigned int current_tail(struct gfs2_sbd *sdp) |
437 | { | 437 | { |
438 | struct gfs2_ail *ai; | 438 | struct gfs2_trans *tr; |
439 | unsigned int tail; | 439 | unsigned int tail; |
440 | 440 | ||
441 | spin_lock(&sdp->sd_ail_lock); | 441 | spin_lock(&sdp->sd_ail_lock); |
@@ -443,8 +443,9 @@ static unsigned int current_tail(struct gfs2_sbd *sdp) | |||
443 | if (list_empty(&sdp->sd_ail1_list)) { | 443 | if (list_empty(&sdp->sd_ail1_list)) { |
444 | tail = sdp->sd_log_head; | 444 | tail = sdp->sd_log_head; |
445 | } else { | 445 | } else { |
446 | ai = list_entry(sdp->sd_ail1_list.prev, struct gfs2_ail, ai_list); | 446 | tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans, |
447 | tail = ai->ai_first; | 447 | tr_list); |
448 | tail = tr->tr_first; | ||
448 | } | 449 | } |
449 | 450 | ||
450 | spin_unlock(&sdp->sd_ail_lock); | 451 | spin_unlock(&sdp->sd_ail_lock); |
@@ -600,7 +601,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) | |||
600 | 601 | ||
601 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | 602 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) |
602 | { | 603 | { |
603 | struct gfs2_ail *ai; | 604 | struct gfs2_trans *tr; |
604 | 605 | ||
605 | down_write(&sdp->sd_log_flush_lock); | 606 | down_write(&sdp->sd_log_flush_lock); |
606 | 607 | ||
@@ -611,9 +612,12 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
611 | } | 612 | } |
612 | trace_gfs2_log_flush(sdp, 1); | 613 | trace_gfs2_log_flush(sdp, 1); |
613 | 614 | ||
614 | ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL); | 615 | tr = sdp->sd_log_tr; |
615 | INIT_LIST_HEAD(&ai->ai_ail1_list); | 616 | if (tr) { |
616 | INIT_LIST_HEAD(&ai->ai_ail2_list); | 617 | sdp->sd_log_tr = NULL; |
618 | INIT_LIST_HEAD(&tr->tr_ail1_list); | ||
619 | INIT_LIST_HEAD(&tr->tr_ail2_list); | ||
620 | } | ||
617 | 621 | ||
618 | if (sdp->sd_log_num_buf != sdp->sd_log_commited_buf) { | 622 | if (sdp->sd_log_num_buf != sdp->sd_log_commited_buf) { |
619 | printk(KERN_INFO "GFS2: log buf %u %u\n", sdp->sd_log_num_buf, | 623 | printk(KERN_INFO "GFS2: log buf %u %u\n", sdp->sd_log_num_buf, |
@@ -630,7 +634,8 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
630 | 634 | ||
631 | sdp->sd_log_flush_head = sdp->sd_log_head; | 635 | sdp->sd_log_flush_head = sdp->sd_log_head; |
632 | sdp->sd_log_flush_wrapped = 0; | 636 | sdp->sd_log_flush_wrapped = 0; |
633 | ai->ai_first = sdp->sd_log_flush_head; | 637 | if (tr) |
638 | tr->tr_first = sdp->sd_log_flush_head; | ||
634 | 639 | ||
635 | gfs2_ordered_write(sdp); | 640 | gfs2_ordered_write(sdp); |
636 | lops_before_commit(sdp); | 641 | lops_before_commit(sdp); |
@@ -643,7 +648,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
643 | trace_gfs2_log_blocks(sdp, -1); | 648 | trace_gfs2_log_blocks(sdp, -1); |
644 | log_write_header(sdp, 0); | 649 | log_write_header(sdp, 0); |
645 | } | 650 | } |
646 | lops_after_commit(sdp, ai); | 651 | lops_after_commit(sdp, tr); |
647 | 652 | ||
648 | gfs2_log_lock(sdp); | 653 | gfs2_log_lock(sdp); |
649 | sdp->sd_log_head = sdp->sd_log_flush_head; | 654 | sdp->sd_log_head = sdp->sd_log_flush_head; |
@@ -653,16 +658,16 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
653 | sdp->sd_log_commited_revoke = 0; | 658 | sdp->sd_log_commited_revoke = 0; |
654 | 659 | ||
655 | spin_lock(&sdp->sd_ail_lock); | 660 | spin_lock(&sdp->sd_ail_lock); |
656 | if (!list_empty(&ai->ai_ail1_list)) { | 661 | if (tr && !list_empty(&tr->tr_ail1_list)) { |
657 | list_add(&ai->ai_list, &sdp->sd_ail1_list); | 662 | list_add(&tr->tr_list, &sdp->sd_ail1_list); |
658 | ai = NULL; | 663 | tr = NULL; |
659 | } | 664 | } |
660 | spin_unlock(&sdp->sd_ail_lock); | 665 | spin_unlock(&sdp->sd_ail_lock); |
661 | gfs2_log_unlock(sdp); | 666 | gfs2_log_unlock(sdp); |
662 | trace_gfs2_log_flush(sdp, 0); | 667 | trace_gfs2_log_flush(sdp, 0); |
663 | up_write(&sdp->sd_log_flush_lock); | 668 | up_write(&sdp->sd_log_flush_lock); |
664 | 669 | ||
665 | kfree(ai); | 670 | kfree(tr); |
666 | } | 671 | } |
667 | 672 | ||
668 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | 673 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
@@ -687,6 +692,12 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
687 | sdp->sd_jdesc->jd_blocks); | 692 | sdp->sd_jdesc->jd_blocks); |
688 | sdp->sd_log_blks_reserved = reserved; | 693 | sdp->sd_log_blks_reserved = reserved; |
689 | 694 | ||
695 | if (sdp->sd_log_tr == NULL && | ||
696 | (tr->tr_num_buf_new || tr->tr_num_databuf_new)) { | ||
697 | gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl); | ||
698 | sdp->sd_log_tr = tr; | ||
699 | tr->tr_attached = 1; | ||
700 | } | ||
690 | gfs2_log_unlock(sdp); | 701 | gfs2_log_unlock(sdp); |
691 | } | 702 | } |
692 | 703 | ||
@@ -708,7 +719,6 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
708 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | 719 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
709 | { | 720 | { |
710 | log_refund(sdp, tr); | 721 | log_refund(sdp, tr); |
711 | up_read(&sdp->sd_log_flush_lock); | ||
712 | 722 | ||
713 | if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) || | 723 | if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) || |
714 | ((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) > | 724 | ((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) > |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index a5055977a214..7318abf9d0fb 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -53,8 +53,8 @@ void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
53 | * to in-place disk block, remove it from the AIL. | 53 | * to in-place disk block, remove it from the AIL. |
54 | */ | 54 | */ |
55 | spin_lock(&sdp->sd_ail_lock); | 55 | spin_lock(&sdp->sd_ail_lock); |
56 | if (bd->bd_ail) | 56 | if (bd->bd_tr) |
57 | list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list); | 57 | list_move(&bd->bd_ail_st_list, &bd->bd_tr->tr_ail2_list); |
58 | spin_unlock(&sdp->sd_ail_lock); | 58 | spin_unlock(&sdp->sd_ail_lock); |
59 | get_bh(bh); | 59 | get_bh(bh); |
60 | atomic_inc(&sdp->sd_log_pinned); | 60 | atomic_inc(&sdp->sd_log_pinned); |
@@ -94,7 +94,7 @@ static void maybe_release_space(struct gfs2_bufdata *bd) | |||
94 | */ | 94 | */ |
95 | 95 | ||
96 | static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | 96 | static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, |
97 | struct gfs2_ail *ai) | 97 | struct gfs2_trans *tr) |
98 | { | 98 | { |
99 | struct gfs2_bufdata *bd = bh->b_private; | 99 | struct gfs2_bufdata *bd = bh->b_private; |
100 | 100 | ||
@@ -109,7 +109,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
109 | maybe_release_space(bd); | 109 | maybe_release_space(bd); |
110 | 110 | ||
111 | spin_lock(&sdp->sd_ail_lock); | 111 | spin_lock(&sdp->sd_ail_lock); |
112 | if (bd->bd_ail) { | 112 | if (bd->bd_tr) { |
113 | list_del(&bd->bd_ail_st_list); | 113 | list_del(&bd->bd_ail_st_list); |
114 | brelse(bh); | 114 | brelse(bh); |
115 | } else { | 115 | } else { |
@@ -117,8 +117,8 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
117 | list_add(&bd->bd_ail_gl_list, &gl->gl_ail_list); | 117 | list_add(&bd->bd_ail_gl_list, &gl->gl_ail_list); |
118 | atomic_inc(&gl->gl_ail_count); | 118 | atomic_inc(&gl->gl_ail_count); |
119 | } | 119 | } |
120 | bd->bd_ail = ai; | 120 | bd->bd_tr = tr; |
121 | list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list); | 121 | list_add(&bd->bd_ail_st_list, &tr->tr_ail1_list); |
122 | spin_unlock(&sdp->sd_ail_lock); | 122 | spin_unlock(&sdp->sd_ail_lock); |
123 | 123 | ||
124 | clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); | 124 | clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); |
@@ -480,17 +480,22 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
480 | &sdp->sd_log_le_buf, 0); | 480 | &sdp->sd_log_le_buf, 0); |
481 | } | 481 | } |
482 | 482 | ||
483 | static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 483 | static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
484 | { | 484 | { |
485 | struct list_head *head = &sdp->sd_log_le_buf; | 485 | struct list_head *head = &sdp->sd_log_le_buf; |
486 | struct gfs2_bufdata *bd; | 486 | struct gfs2_bufdata *bd; |
487 | 487 | ||
488 | if (tr == NULL) { | ||
489 | gfs2_assert(sdp, list_empty(head)); | ||
490 | return; | ||
491 | } | ||
492 | |||
488 | while (!list_empty(head)) { | 493 | while (!list_empty(head)) { |
489 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); | 494 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); |
490 | list_del_init(&bd->bd_list); | 495 | list_del_init(&bd->bd_list); |
491 | sdp->sd_log_num_buf--; | 496 | sdp->sd_log_num_buf--; |
492 | 497 | ||
493 | gfs2_unpin(sdp, bd->bd_bh, ai); | 498 | gfs2_unpin(sdp, bd->bd_bh, tr); |
494 | } | 499 | } |
495 | gfs2_assert_warn(sdp, !sdp->sd_log_num_buf); | 500 | gfs2_assert_warn(sdp, !sdp->sd_log_num_buf); |
496 | } | 501 | } |
@@ -613,7 +618,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
613 | gfs2_log_write_page(sdp, page); | 618 | gfs2_log_write_page(sdp, page); |
614 | } | 619 | } |
615 | 620 | ||
616 | static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 621 | static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
617 | { | 622 | { |
618 | struct list_head *head = &sdp->sd_log_le_revoke; | 623 | struct list_head *head = &sdp->sd_log_le_revoke; |
619 | struct gfs2_bufdata *bd; | 624 | struct gfs2_bufdata *bd; |
@@ -791,16 +796,21 @@ static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass) | |||
791 | jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks); | 796 | jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks); |
792 | } | 797 | } |
793 | 798 | ||
794 | static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 799 | static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
795 | { | 800 | { |
796 | struct list_head *head = &sdp->sd_log_le_databuf; | 801 | struct list_head *head = &sdp->sd_log_le_databuf; |
797 | struct gfs2_bufdata *bd; | 802 | struct gfs2_bufdata *bd; |
798 | 803 | ||
804 | if (tr == NULL) { | ||
805 | gfs2_assert(sdp, list_empty(head)); | ||
806 | return; | ||
807 | } | ||
808 | |||
799 | while (!list_empty(head)) { | 809 | while (!list_empty(head)) { |
800 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); | 810 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); |
801 | list_del_init(&bd->bd_list); | 811 | list_del_init(&bd->bd_list); |
802 | sdp->sd_log_num_databuf--; | 812 | sdp->sd_log_num_databuf--; |
803 | gfs2_unpin(sdp, bd->bd_bh, ai); | 813 | gfs2_unpin(sdp, bd->bd_bh, tr); |
804 | } | 814 | } |
805 | gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf); | 815 | gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf); |
806 | } | 816 | } |
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index ba77b7da8325..87e062e05c92 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h | |||
@@ -55,12 +55,13 @@ static inline void lops_before_commit(struct gfs2_sbd *sdp) | |||
55 | gfs2_log_ops[x]->lo_before_commit(sdp); | 55 | gfs2_log_ops[x]->lo_before_commit(sdp); |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline void lops_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 58 | static inline void lops_after_commit(struct gfs2_sbd *sdp, |
59 | struct gfs2_trans *tr) | ||
59 | { | 60 | { |
60 | int x; | 61 | int x; |
61 | for (x = 0; gfs2_log_ops[x]; x++) | 62 | for (x = 0; gfs2_log_ops[x]; x++) |
62 | if (gfs2_log_ops[x]->lo_after_commit) | 63 | if (gfs2_log_ops[x]->lo_after_commit) |
63 | gfs2_log_ops[x]->lo_after_commit(sdp, ai); | 64 | gfs2_log_ops[x]->lo_after_commit(sdp, tr); |
64 | } | 65 | } |
65 | 66 | ||
66 | static inline void lops_before_scan(struct gfs2_jdesc *jd, | 67 | static inline void lops_before_scan(struct gfs2_jdesc *jd, |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index b059bbb5059e..1a89afb68472 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -295,7 +295,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int | |||
295 | } | 295 | } |
296 | if (bd) { | 296 | if (bd) { |
297 | spin_lock(&sdp->sd_ail_lock); | 297 | spin_lock(&sdp->sd_ail_lock); |
298 | if (bd->bd_ail) { | 298 | if (bd->bd_tr) { |
299 | gfs2_remove_from_ail(bd); | 299 | gfs2_remove_from_ail(bd); |
300 | bh->b_private = NULL; | 300 | bh->b_private = NULL; |
301 | bd->bd_bh = NULL; | 301 | bd->bd_bh = NULL; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index d1f51fd73f86..0c5a575b513e 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -576,7 +576,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) | |||
576 | RB_CLEAR_NODE(&ip->i_res->rs_node); | 576 | RB_CLEAR_NODE(&ip->i_res->rs_node); |
577 | out: | 577 | out: |
578 | up_write(&ip->i_rw_mutex); | 578 | up_write(&ip->i_rw_mutex); |
579 | return 0; | 579 | return error; |
580 | } | 580 | } |
581 | 581 | ||
582 | static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) | 582 | static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) |
@@ -592,7 +592,7 @@ static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) | |||
592 | * @rs: The reservation to remove | 592 | * @rs: The reservation to remove |
593 | * | 593 | * |
594 | */ | 594 | */ |
595 | static void __rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs) | 595 | static void __rs_deltree(struct gfs2_blkreserv *rs) |
596 | { | 596 | { |
597 | struct gfs2_rgrpd *rgd; | 597 | struct gfs2_rgrpd *rgd; |
598 | 598 | ||
@@ -605,7 +605,7 @@ static void __rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs) | |||
605 | RB_CLEAR_NODE(&rs->rs_node); | 605 | RB_CLEAR_NODE(&rs->rs_node); |
606 | 606 | ||
607 | if (rs->rs_free) { | 607 | if (rs->rs_free) { |
608 | /* return reserved blocks to the rgrp and the ip */ | 608 | /* return reserved blocks to the rgrp */ |
609 | BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free); | 609 | BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free); |
610 | rs->rs_rbm.rgd->rd_reserved -= rs->rs_free; | 610 | rs->rs_rbm.rgd->rd_reserved -= rs->rs_free; |
611 | rs->rs_free = 0; | 611 | rs->rs_free = 0; |
@@ -619,14 +619,14 @@ static void __rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs) | |||
619 | * @rs: The reservation to remove | 619 | * @rs: The reservation to remove |
620 | * | 620 | * |
621 | */ | 621 | */ |
622 | void gfs2_rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs) | 622 | void gfs2_rs_deltree(struct gfs2_blkreserv *rs) |
623 | { | 623 | { |
624 | struct gfs2_rgrpd *rgd; | 624 | struct gfs2_rgrpd *rgd; |
625 | 625 | ||
626 | rgd = rs->rs_rbm.rgd; | 626 | rgd = rs->rs_rbm.rgd; |
627 | if (rgd) { | 627 | if (rgd) { |
628 | spin_lock(&rgd->rd_rsspin); | 628 | spin_lock(&rgd->rd_rsspin); |
629 | __rs_deltree(ip, rs); | 629 | __rs_deltree(rs); |
630 | spin_unlock(&rgd->rd_rsspin); | 630 | spin_unlock(&rgd->rd_rsspin); |
631 | } | 631 | } |
632 | } | 632 | } |
@@ -640,7 +640,7 @@ void gfs2_rs_delete(struct gfs2_inode *ip) | |||
640 | { | 640 | { |
641 | down_write(&ip->i_rw_mutex); | 641 | down_write(&ip->i_rw_mutex); |
642 | if (ip->i_res) { | 642 | if (ip->i_res) { |
643 | gfs2_rs_deltree(ip, ip->i_res); | 643 | gfs2_rs_deltree(ip->i_res); |
644 | BUG_ON(ip->i_res->rs_free); | 644 | BUG_ON(ip->i_res->rs_free); |
645 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); | 645 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); |
646 | ip->i_res = NULL; | 646 | ip->i_res = NULL; |
@@ -664,7 +664,7 @@ static void return_all_reservations(struct gfs2_rgrpd *rgd) | |||
664 | spin_lock(&rgd->rd_rsspin); | 664 | spin_lock(&rgd->rd_rsspin); |
665 | while ((n = rb_first(&rgd->rd_rstree))) { | 665 | while ((n = rb_first(&rgd->rd_rstree))) { |
666 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); | 666 | rs = rb_entry(n, struct gfs2_blkreserv, rs_node); |
667 | __rs_deltree(NULL, rs); | 667 | __rs_deltree(rs); |
668 | } | 668 | } |
669 | spin_unlock(&rgd->rd_rsspin); | 669 | spin_unlock(&rgd->rd_rsspin); |
670 | } | 670 | } |
@@ -1181,12 +1181,9 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
1181 | const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed) | 1181 | const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed) |
1182 | { | 1182 | { |
1183 | struct super_block *sb = sdp->sd_vfs; | 1183 | struct super_block *sb = sdp->sd_vfs; |
1184 | struct block_device *bdev = sb->s_bdev; | ||
1185 | const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / | ||
1186 | bdev_logical_block_size(sb->s_bdev); | ||
1187 | u64 blk; | 1184 | u64 blk; |
1188 | sector_t start = 0; | 1185 | sector_t start = 0; |
1189 | sector_t nr_sects = 0; | 1186 | sector_t nr_blks = 0; |
1190 | int rv; | 1187 | int rv; |
1191 | unsigned int x; | 1188 | unsigned int x; |
1192 | u32 trimmed = 0; | 1189 | u32 trimmed = 0; |
@@ -1206,35 +1203,34 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
1206 | if (diff == 0) | 1203 | if (diff == 0) |
1207 | continue; | 1204 | continue; |
1208 | blk = offset + ((bi->bi_start + x) * GFS2_NBBY); | 1205 | blk = offset + ((bi->bi_start + x) * GFS2_NBBY); |
1209 | blk *= sects_per_blk; /* convert to sectors */ | ||
1210 | while(diff) { | 1206 | while(diff) { |
1211 | if (diff & 1) { | 1207 | if (diff & 1) { |
1212 | if (nr_sects == 0) | 1208 | if (nr_blks == 0) |
1213 | goto start_new_extent; | 1209 | goto start_new_extent; |
1214 | if ((start + nr_sects) != blk) { | 1210 | if ((start + nr_blks) != blk) { |
1215 | if (nr_sects >= minlen) { | 1211 | if (nr_blks >= minlen) { |
1216 | rv = blkdev_issue_discard(bdev, | 1212 | rv = sb_issue_discard(sb, |
1217 | start, nr_sects, | 1213 | start, nr_blks, |
1218 | GFP_NOFS, 0); | 1214 | GFP_NOFS, 0); |
1219 | if (rv) | 1215 | if (rv) |
1220 | goto fail; | 1216 | goto fail; |
1221 | trimmed += nr_sects; | 1217 | trimmed += nr_blks; |
1222 | } | 1218 | } |
1223 | nr_sects = 0; | 1219 | nr_blks = 0; |
1224 | start_new_extent: | 1220 | start_new_extent: |
1225 | start = blk; | 1221 | start = blk; |
1226 | } | 1222 | } |
1227 | nr_sects += sects_per_blk; | 1223 | nr_blks++; |
1228 | } | 1224 | } |
1229 | diff >>= 2; | 1225 | diff >>= 2; |
1230 | blk += sects_per_blk; | 1226 | blk++; |
1231 | } | 1227 | } |
1232 | } | 1228 | } |
1233 | if (nr_sects >= minlen) { | 1229 | if (nr_blks >= minlen) { |
1234 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); | 1230 | rv = sb_issue_discard(sb, start, nr_blks, GFP_NOFS, 0); |
1235 | if (rv) | 1231 | if (rv) |
1236 | goto fail; | 1232 | goto fail; |
1237 | trimmed += nr_sects; | 1233 | trimmed += nr_blks; |
1238 | } | 1234 | } |
1239 | if (ptrimmed) | 1235 | if (ptrimmed) |
1240 | *ptrimmed = trimmed; | 1236 | *ptrimmed = trimmed; |
@@ -1878,7 +1874,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags) | |||
1878 | 1874 | ||
1879 | /* Drop reservation, if we couldn't use reserved rgrp */ | 1875 | /* Drop reservation, if we couldn't use reserved rgrp */ |
1880 | if (gfs2_rs_active(rs)) | 1876 | if (gfs2_rs_active(rs)) |
1881 | gfs2_rs_deltree(ip, rs); | 1877 | gfs2_rs_deltree(rs); |
1882 | check_rgrp: | 1878 | check_rgrp: |
1883 | /* Check for unlinked inodes which can be reclaimed */ | 1879 | /* Check for unlinked inodes which can be reclaimed */ |
1884 | if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) | 1880 | if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) |
@@ -2091,7 +2087,7 @@ static void gfs2_adjust_reservation(struct gfs2_inode *ip, | |||
2091 | if (rs->rs_free && !ret) | 2087 | if (rs->rs_free && !ret) |
2092 | goto out; | 2088 | goto out; |
2093 | } | 2089 | } |
2094 | __rs_deltree(ip, rs); | 2090 | __rs_deltree(rs); |
2095 | } | 2091 | } |
2096 | out: | 2092 | out: |
2097 | spin_unlock(&rgd->rd_rsspin); | 2093 | spin_unlock(&rgd->rd_rsspin); |
@@ -2184,13 +2180,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
2184 | if (dinode) | 2180 | if (dinode) |
2185 | gfs2_trans_add_unrevoke(sdp, block, 1); | 2181 | gfs2_trans_add_unrevoke(sdp, block, 1); |
2186 | 2182 | ||
2187 | /* | 2183 | gfs2_quota_change(ip, *nblocks, ip->i_inode.i_uid, ip->i_inode.i_gid); |
2188 | * This needs reviewing to see why we cannot do the quota change | ||
2189 | * at this point in the dinode case. | ||
2190 | */ | ||
2191 | if (ndata) | ||
2192 | gfs2_quota_change(ip, ndata, ip->i_inode.i_uid, | ||
2193 | ip->i_inode.i_gid); | ||
2194 | 2184 | ||
2195 | rbm.rgd->rd_free_clone -= *nblocks; | 2185 | rbm.rgd->rd_free_clone -= *nblocks; |
2196 | trace_gfs2_block_alloc(ip, rbm.rgd, block, *nblocks, | 2186 | trace_gfs2_block_alloc(ip, rbm.rgd, block, *nblocks, |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index 842185853f6b..5b3f4a896e6c 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -47,7 +47,7 @@ extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, | |||
47 | bool dinode, u64 *generation); | 47 | bool dinode, u64 *generation); |
48 | 48 | ||
49 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); | 49 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); |
50 | extern void gfs2_rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs); | 50 | extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); |
51 | extern void gfs2_rs_delete(struct gfs2_inode *ip); | 51 | extern void gfs2_rs_delete(struct gfs2_inode *ip); |
52 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); | 52 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); |
53 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 53 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index cab77b8ba84f..917c8e1eb4ae 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -1512,7 +1512,7 @@ out_truncate: | |||
1512 | out_unlock: | 1512 | out_unlock: |
1513 | /* Error path for case 1 */ | 1513 | /* Error path for case 1 */ |
1514 | if (gfs2_rs_active(ip->i_res)) | 1514 | if (gfs2_rs_active(ip->i_res)) |
1515 | gfs2_rs_deltree(ip, ip->i_res); | 1515 | gfs2_rs_deltree(ip->i_res); |
1516 | 1516 | ||
1517 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) | 1517 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) |
1518 | gfs2_glock_dq(&ip->i_iopen_gh); | 1518 | gfs2_glock_dq(&ip->i_iopen_gh); |
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index 2ee13e841e9f..20c007d747ab 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h | |||
@@ -159,9 +159,9 @@ TRACE_EVENT(gfs2_glock_put, | |||
159 | /* Callback (local or remote) requesting lock demotion */ | 159 | /* Callback (local or remote) requesting lock demotion */ |
160 | TRACE_EVENT(gfs2_demote_rq, | 160 | TRACE_EVENT(gfs2_demote_rq, |
161 | 161 | ||
162 | TP_PROTO(const struct gfs2_glock *gl), | 162 | TP_PROTO(const struct gfs2_glock *gl, bool remote), |
163 | 163 | ||
164 | TP_ARGS(gl), | 164 | TP_ARGS(gl, remote), |
165 | 165 | ||
166 | TP_STRUCT__entry( | 166 | TP_STRUCT__entry( |
167 | __field( dev_t, dev ) | 167 | __field( dev_t, dev ) |
@@ -170,6 +170,7 @@ TRACE_EVENT(gfs2_demote_rq, | |||
170 | __field( u8, cur_state ) | 170 | __field( u8, cur_state ) |
171 | __field( u8, dmt_state ) | 171 | __field( u8, dmt_state ) |
172 | __field( unsigned long, flags ) | 172 | __field( unsigned long, flags ) |
173 | __field( bool, remote ) | ||
173 | ), | 174 | ), |
174 | 175 | ||
175 | TP_fast_assign( | 176 | TP_fast_assign( |
@@ -179,14 +180,16 @@ TRACE_EVENT(gfs2_demote_rq, | |||
179 | __entry->cur_state = glock_trace_state(gl->gl_state); | 180 | __entry->cur_state = glock_trace_state(gl->gl_state); |
180 | __entry->dmt_state = glock_trace_state(gl->gl_demote_state); | 181 | __entry->dmt_state = glock_trace_state(gl->gl_demote_state); |
181 | __entry->flags = gl->gl_flags | (gl->gl_object ? (1UL<<GLF_OBJECT) : 0); | 182 | __entry->flags = gl->gl_flags | (gl->gl_object ? (1UL<<GLF_OBJECT) : 0); |
183 | __entry->remote = remote; | ||
182 | ), | 184 | ), |
183 | 185 | ||
184 | TP_printk("%u,%u glock %d:%lld demote %s to %s flags:%s", | 186 | TP_printk("%u,%u glock %d:%lld demote %s to %s flags:%s %s", |
185 | MAJOR(__entry->dev), MINOR(__entry->dev), __entry->gltype, | 187 | MAJOR(__entry->dev), MINOR(__entry->dev), __entry->gltype, |
186 | (unsigned long long)__entry->glnum, | 188 | (unsigned long long)__entry->glnum, |
187 | glock_trace_name(__entry->cur_state), | 189 | glock_trace_name(__entry->cur_state), |
188 | glock_trace_name(__entry->dmt_state), | 190 | glock_trace_name(__entry->dmt_state), |
189 | show_glock_flags(__entry->flags)) | 191 | show_glock_flags(__entry->flags), |
192 | __entry->remote ? "remote" : "local") | ||
190 | 193 | ||
191 | ); | 194 | ); |
192 | 195 | ||
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 88162fae27a5..7374907742a8 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c | |||
@@ -96,7 +96,8 @@ static void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) | |||
96 | 96 | ||
97 | static void gfs2_print_trans(const struct gfs2_trans *tr) | 97 | static void gfs2_print_trans(const struct gfs2_trans *tr) |
98 | { | 98 | { |
99 | print_symbol(KERN_WARNING "GFS2: Transaction created at: %s\n", tr->tr_ip); | 99 | printk(KERN_WARNING "GFS2: Transaction created at: %pSR\n", |
100 | (void *)tr->tr_ip); | ||
100 | printk(KERN_WARNING "GFS2: blocks=%u revokes=%u reserved=%u touched=%d\n", | 101 | printk(KERN_WARNING "GFS2: blocks=%u revokes=%u reserved=%u touched=%d\n", |
101 | tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, tr->tr_touched); | 102 | tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, tr->tr_touched); |
102 | printk(KERN_WARNING "GFS2: Buf %u/%u Databuf %u/%u Revoke %u/%u\n", | 103 | printk(KERN_WARNING "GFS2: Buf %u/%u Databuf %u/%u Revoke %u/%u\n", |
@@ -135,8 +136,10 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) | |||
135 | if (tr->tr_t_gh.gh_gl) { | 136 | if (tr->tr_t_gh.gh_gl) { |
136 | gfs2_glock_dq(&tr->tr_t_gh); | 137 | gfs2_glock_dq(&tr->tr_t_gh); |
137 | gfs2_holder_uninit(&tr->tr_t_gh); | 138 | gfs2_holder_uninit(&tr->tr_t_gh); |
138 | kfree(tr); | 139 | if (!tr->tr_attached) |
140 | kfree(tr); | ||
139 | } | 141 | } |
142 | up_read(&sdp->sd_log_flush_lock); | ||
140 | 143 | ||
141 | if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) | 144 | if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) |
142 | gfs2_log_flush(sdp, NULL); | 145 | gfs2_log_flush(sdp, NULL); |
diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c index 571abe97b42a..de69d8a24f6d 100644 --- a/fs/hfs/bfind.c +++ b/fs/hfs/bfind.c | |||
@@ -22,7 +22,8 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd) | |||
22 | return -ENOMEM; | 22 | return -ENOMEM; |
23 | fd->search_key = ptr; | 23 | fd->search_key = ptr; |
24 | fd->key = ptr + tree->max_key_len + 2; | 24 | fd->key = ptr + tree->max_key_len + 2; |
25 | dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", tree->cnid, __builtin_return_address(0)); | 25 | hfs_dbg(BNODE_REFS, "find_init: %d (%p)\n", |
26 | tree->cnid, __builtin_return_address(0)); | ||
26 | mutex_lock(&tree->tree_lock); | 27 | mutex_lock(&tree->tree_lock); |
27 | return 0; | 28 | return 0; |
28 | } | 29 | } |
@@ -31,7 +32,8 @@ void hfs_find_exit(struct hfs_find_data *fd) | |||
31 | { | 32 | { |
32 | hfs_bnode_put(fd->bnode); | 33 | hfs_bnode_put(fd->bnode); |
33 | kfree(fd->search_key); | 34 | kfree(fd->search_key); |
34 | dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", fd->tree->cnid, __builtin_return_address(0)); | 35 | hfs_dbg(BNODE_REFS, "find_exit: %d (%p)\n", |
36 | fd->tree->cnid, __builtin_return_address(0)); | ||
35 | mutex_unlock(&fd->tree->tree_lock); | 37 | mutex_unlock(&fd->tree->tree_lock); |
36 | fd->tree = NULL; | 38 | fd->tree = NULL; |
37 | } | 39 | } |
@@ -135,8 +137,8 @@ int hfs_brec_find(struct hfs_find_data *fd) | |||
135 | return res; | 137 | return res; |
136 | 138 | ||
137 | invalid: | 139 | invalid: |
138 | printk(KERN_ERR "hfs: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n", | 140 | pr_err("inconsistency in B*Tree (%d,%d,%d,%u,%u)\n", |
139 | height, bnode->height, bnode->type, nidx, parent); | 141 | height, bnode->height, bnode->type, nidx, parent); |
140 | res = -EIO; | 142 | res = -EIO; |
141 | release: | 143 | release: |
142 | hfs_bnode_put(bnode); | 144 | hfs_bnode_put(bnode); |
diff --git a/fs/hfs/bitmap.c b/fs/hfs/bitmap.c index c6e97366e8ac..28307bc9ec1e 100644 --- a/fs/hfs/bitmap.c +++ b/fs/hfs/bitmap.c | |||
@@ -158,7 +158,7 @@ u32 hfs_vbm_search_free(struct super_block *sb, u32 goal, u32 *num_bits) | |||
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
161 | dprint(DBG_BITMAP, "alloc_bits: %u,%u\n", pos, *num_bits); | 161 | hfs_dbg(BITMAP, "alloc_bits: %u,%u\n", pos, *num_bits); |
162 | HFS_SB(sb)->free_ablocks -= *num_bits; | 162 | HFS_SB(sb)->free_ablocks -= *num_bits; |
163 | hfs_bitmap_dirty(sb); | 163 | hfs_bitmap_dirty(sb); |
164 | out: | 164 | out: |
@@ -200,7 +200,7 @@ int hfs_clear_vbm_bits(struct super_block *sb, u16 start, u16 count) | |||
200 | if (!count) | 200 | if (!count) |
201 | return 0; | 201 | return 0; |
202 | 202 | ||
203 | dprint(DBG_BITMAP, "clear_bits: %u,%u\n", start, count); | 203 | hfs_dbg(BITMAP, "clear_bits: %u,%u\n", start, count); |
204 | /* are all of the bits in range? */ | 204 | /* are all of the bits in range? */ |
205 | if ((start + count) > HFS_SB(sb)->fs_ablocks) | 205 | if ((start + count) > HFS_SB(sb)->fs_ablocks) |
206 | return -2; | 206 | return -2; |
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index cdb41a1f6a64..f3b1a15ccd59 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c | |||
@@ -100,7 +100,7 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, | |||
100 | struct hfs_btree *tree; | 100 | struct hfs_btree *tree; |
101 | struct page *src_page, *dst_page; | 101 | struct page *src_page, *dst_page; |
102 | 102 | ||
103 | dprint(DBG_BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); | 103 | hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); |
104 | if (!len) | 104 | if (!len) |
105 | return; | 105 | return; |
106 | tree = src_node->tree; | 106 | tree = src_node->tree; |
@@ -120,7 +120,7 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) | |||
120 | struct page *page; | 120 | struct page *page; |
121 | void *ptr; | 121 | void *ptr; |
122 | 122 | ||
123 | dprint(DBG_BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); | 123 | hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); |
124 | if (!len) | 124 | if (!len) |
125 | return; | 125 | return; |
126 | src += node->page_offset; | 126 | src += node->page_offset; |
@@ -138,16 +138,16 @@ void hfs_bnode_dump(struct hfs_bnode *node) | |||
138 | __be32 cnid; | 138 | __be32 cnid; |
139 | int i, off, key_off; | 139 | int i, off, key_off; |
140 | 140 | ||
141 | dprint(DBG_BNODE_MOD, "bnode: %d\n", node->this); | 141 | hfs_dbg(BNODE_MOD, "bnode: %d\n", node->this); |
142 | hfs_bnode_read(node, &desc, 0, sizeof(desc)); | 142 | hfs_bnode_read(node, &desc, 0, sizeof(desc)); |
143 | dprint(DBG_BNODE_MOD, "%d, %d, %d, %d, %d\n", | 143 | hfs_dbg(BNODE_MOD, "%d, %d, %d, %d, %d\n", |
144 | be32_to_cpu(desc.next), be32_to_cpu(desc.prev), | 144 | be32_to_cpu(desc.next), be32_to_cpu(desc.prev), |
145 | desc.type, desc.height, be16_to_cpu(desc.num_recs)); | 145 | desc.type, desc.height, be16_to_cpu(desc.num_recs)); |
146 | 146 | ||
147 | off = node->tree->node_size - 2; | 147 | off = node->tree->node_size - 2; |
148 | for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) { | 148 | for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) { |
149 | key_off = hfs_bnode_read_u16(node, off); | 149 | key_off = hfs_bnode_read_u16(node, off); |
150 | dprint(DBG_BNODE_MOD, " %d", key_off); | 150 | hfs_dbg_cont(BNODE_MOD, " %d", key_off); |
151 | if (i && node->type == HFS_NODE_INDEX) { | 151 | if (i && node->type == HFS_NODE_INDEX) { |
152 | int tmp; | 152 | int tmp; |
153 | 153 | ||
@@ -155,17 +155,18 @@ void hfs_bnode_dump(struct hfs_bnode *node) | |||
155 | tmp = (hfs_bnode_read_u8(node, key_off) | 1) + 1; | 155 | tmp = (hfs_bnode_read_u8(node, key_off) | 1) + 1; |
156 | else | 156 | else |
157 | tmp = node->tree->max_key_len + 1; | 157 | tmp = node->tree->max_key_len + 1; |
158 | dprint(DBG_BNODE_MOD, " (%d,%d", tmp, hfs_bnode_read_u8(node, key_off)); | 158 | hfs_dbg_cont(BNODE_MOD, " (%d,%d", |
159 | tmp, hfs_bnode_read_u8(node, key_off)); | ||
159 | hfs_bnode_read(node, &cnid, key_off + tmp, 4); | 160 | hfs_bnode_read(node, &cnid, key_off + tmp, 4); |
160 | dprint(DBG_BNODE_MOD, ",%d)", be32_to_cpu(cnid)); | 161 | hfs_dbg_cont(BNODE_MOD, ",%d)", be32_to_cpu(cnid)); |
161 | } else if (i && node->type == HFS_NODE_LEAF) { | 162 | } else if (i && node->type == HFS_NODE_LEAF) { |
162 | int tmp; | 163 | int tmp; |
163 | 164 | ||
164 | tmp = hfs_bnode_read_u8(node, key_off); | 165 | tmp = hfs_bnode_read_u8(node, key_off); |
165 | dprint(DBG_BNODE_MOD, " (%d)", tmp); | 166 | hfs_dbg_cont(BNODE_MOD, " (%d)", tmp); |
166 | } | 167 | } |
167 | } | 168 | } |
168 | dprint(DBG_BNODE_MOD, "\n"); | 169 | hfs_dbg_cont(BNODE_MOD, "\n"); |
169 | } | 170 | } |
170 | 171 | ||
171 | void hfs_bnode_unlink(struct hfs_bnode *node) | 172 | void hfs_bnode_unlink(struct hfs_bnode *node) |
@@ -220,7 +221,7 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid) | |||
220 | struct hfs_bnode *node; | 221 | struct hfs_bnode *node; |
221 | 222 | ||
222 | if (cnid >= tree->node_count) { | 223 | if (cnid >= tree->node_count) { |
223 | printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid); | 224 | pr_err("request for non-existent node %d in B*Tree\n", cnid); |
224 | return NULL; | 225 | return NULL; |
225 | } | 226 | } |
226 | 227 | ||
@@ -243,7 +244,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | |||
243 | loff_t off; | 244 | loff_t off; |
244 | 245 | ||
245 | if (cnid >= tree->node_count) { | 246 | if (cnid >= tree->node_count) { |
246 | printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid); | 247 | pr_err("request for non-existent node %d in B*Tree\n", cnid); |
247 | return NULL; | 248 | return NULL; |
248 | } | 249 | } |
249 | 250 | ||
@@ -257,8 +258,8 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | |||
257 | node->this = cnid; | 258 | node->this = cnid; |
258 | set_bit(HFS_BNODE_NEW, &node->flags); | 259 | set_bit(HFS_BNODE_NEW, &node->flags); |
259 | atomic_set(&node->refcnt, 1); | 260 | atomic_set(&node->refcnt, 1); |
260 | dprint(DBG_BNODE_REFS, "new_node(%d:%d): 1\n", | 261 | hfs_dbg(BNODE_REFS, "new_node(%d:%d): 1\n", |
261 | node->tree->cnid, node->this); | 262 | node->tree->cnid, node->this); |
262 | init_waitqueue_head(&node->lock_wq); | 263 | init_waitqueue_head(&node->lock_wq); |
263 | spin_lock(&tree->hash_lock); | 264 | spin_lock(&tree->hash_lock); |
264 | node2 = hfs_bnode_findhash(tree, cnid); | 265 | node2 = hfs_bnode_findhash(tree, cnid); |
@@ -301,7 +302,7 @@ void hfs_bnode_unhash(struct hfs_bnode *node) | |||
301 | { | 302 | { |
302 | struct hfs_bnode **p; | 303 | struct hfs_bnode **p; |
303 | 304 | ||
304 | dprint(DBG_BNODE_REFS, "remove_node(%d:%d): %d\n", | 305 | hfs_dbg(BNODE_REFS, "remove_node(%d:%d): %d\n", |
305 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); | 306 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); |
306 | for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; | 307 | for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; |
307 | *p && *p != node; p = &(*p)->next_hash) | 308 | *p && *p != node; p = &(*p)->next_hash) |
@@ -443,8 +444,9 @@ void hfs_bnode_get(struct hfs_bnode *node) | |||
443 | { | 444 | { |
444 | if (node) { | 445 | if (node) { |
445 | atomic_inc(&node->refcnt); | 446 | atomic_inc(&node->refcnt); |
446 | dprint(DBG_BNODE_REFS, "get_node(%d:%d): %d\n", | 447 | hfs_dbg(BNODE_REFS, "get_node(%d:%d): %d\n", |
447 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); | 448 | node->tree->cnid, node->this, |
449 | atomic_read(&node->refcnt)); | ||
448 | } | 450 | } |
449 | } | 451 | } |
450 | 452 | ||
@@ -455,8 +457,9 @@ void hfs_bnode_put(struct hfs_bnode *node) | |||
455 | struct hfs_btree *tree = node->tree; | 457 | struct hfs_btree *tree = node->tree; |
456 | int i; | 458 | int i; |
457 | 459 | ||
458 | dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n", | 460 | hfs_dbg(BNODE_REFS, "put_node(%d:%d): %d\n", |
459 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); | 461 | node->tree->cnid, node->this, |
462 | atomic_read(&node->refcnt)); | ||
460 | BUG_ON(!atomic_read(&node->refcnt)); | 463 | BUG_ON(!atomic_read(&node->refcnt)); |
461 | if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock)) | 464 | if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock)) |
462 | return; | 465 | return; |
diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 92fb358ce824..9f4ee7f52026 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c | |||
@@ -47,15 +47,13 @@ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec) | |||
47 | if (node->tree->attributes & HFS_TREE_BIGKEYS) { | 47 | if (node->tree->attributes & HFS_TREE_BIGKEYS) { |
48 | retval = hfs_bnode_read_u16(node, recoff) + 2; | 48 | retval = hfs_bnode_read_u16(node, recoff) + 2; |
49 | if (retval > node->tree->max_key_len + 2) { | 49 | if (retval > node->tree->max_key_len + 2) { |
50 | printk(KERN_ERR "hfs: keylen %d too large\n", | 50 | pr_err("keylen %d too large\n", retval); |
51 | retval); | ||
52 | retval = 0; | 51 | retval = 0; |
53 | } | 52 | } |
54 | } else { | 53 | } else { |
55 | retval = (hfs_bnode_read_u8(node, recoff) | 1) + 1; | 54 | retval = (hfs_bnode_read_u8(node, recoff) | 1) + 1; |
56 | if (retval > node->tree->max_key_len + 1) { | 55 | if (retval > node->tree->max_key_len + 1) { |
57 | printk(KERN_ERR "hfs: keylen %d too large\n", | 56 | pr_err("keylen %d too large\n", retval); |
58 | retval); | ||
59 | retval = 0; | 57 | retval = 0; |
60 | } | 58 | } |
61 | } | 59 | } |
@@ -94,7 +92,8 @@ again: | |||
94 | end_rec_off = tree->node_size - (node->num_recs + 1) * 2; | 92 | end_rec_off = tree->node_size - (node->num_recs + 1) * 2; |
95 | end_off = hfs_bnode_read_u16(node, end_rec_off); | 93 | end_off = hfs_bnode_read_u16(node, end_rec_off); |
96 | end_rec_off -= 2; | 94 | end_rec_off -= 2; |
97 | dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", rec, size, end_off, end_rec_off); | 95 | hfs_dbg(BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", |
96 | rec, size, end_off, end_rec_off); | ||
98 | if (size > end_rec_off - end_off) { | 97 | if (size > end_rec_off - end_off) { |
99 | if (new_node) | 98 | if (new_node) |
100 | panic("not enough room!\n"); | 99 | panic("not enough room!\n"); |
@@ -190,7 +189,8 @@ again: | |||
190 | mark_inode_dirty(tree->inode); | 189 | mark_inode_dirty(tree->inode); |
191 | } | 190 | } |
192 | hfs_bnode_dump(node); | 191 | hfs_bnode_dump(node); |
193 | dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n", fd->record, fd->keylength + fd->entrylength); | 192 | hfs_dbg(BNODE_MOD, "remove_rec: %d, %d\n", |
193 | fd->record, fd->keylength + fd->entrylength); | ||
194 | if (!--node->num_recs) { | 194 | if (!--node->num_recs) { |
195 | hfs_bnode_unlink(node); | 195 | hfs_bnode_unlink(node); |
196 | if (!node->parent) | 196 | if (!node->parent) |
@@ -240,7 +240,7 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) | |||
240 | if (IS_ERR(new_node)) | 240 | if (IS_ERR(new_node)) |
241 | return new_node; | 241 | return new_node; |
242 | hfs_bnode_get(node); | 242 | hfs_bnode_get(node); |
243 | dprint(DBG_BNODE_MOD, "split_nodes: %d - %d - %d\n", | 243 | hfs_dbg(BNODE_MOD, "split_nodes: %d - %d - %d\n", |
244 | node->this, new_node->this, node->next); | 244 | node->this, new_node->this, node->next); |
245 | new_node->next = node->next; | 245 | new_node->next = node->next; |
246 | new_node->prev = node->this; | 246 | new_node->prev = node->this; |
@@ -374,7 +374,8 @@ again: | |||
374 | newkeylen = (hfs_bnode_read_u8(node, 14) | 1) + 1; | 374 | newkeylen = (hfs_bnode_read_u8(node, 14) | 1) + 1; |
375 | else | 375 | else |
376 | fd->keylength = newkeylen = tree->max_key_len + 1; | 376 | fd->keylength = newkeylen = tree->max_key_len + 1; |
377 | dprint(DBG_BNODE_MOD, "update_rec: %d, %d, %d\n", rec, fd->keylength, newkeylen); | 377 | hfs_dbg(BNODE_MOD, "update_rec: %d, %d, %d\n", |
378 | rec, fd->keylength, newkeylen); | ||
378 | 379 | ||
379 | rec_off = tree->node_size - (rec + 2) * 2; | 380 | rec_off = tree->node_size - (rec + 2) * 2; |
380 | end_rec_off = tree->node_size - (parent->num_recs + 1) * 2; | 381 | end_rec_off = tree->node_size - (parent->num_recs + 1) * 2; |
@@ -385,7 +386,7 @@ again: | |||
385 | end_off = hfs_bnode_read_u16(parent, end_rec_off); | 386 | end_off = hfs_bnode_read_u16(parent, end_rec_off); |
386 | if (end_rec_off - end_off < diff) { | 387 | if (end_rec_off - end_off < diff) { |
387 | 388 | ||
388 | printk(KERN_DEBUG "hfs: splitting index node...\n"); | 389 | printk(KERN_DEBUG "splitting index node...\n"); |
389 | fd->bnode = parent; | 390 | fd->bnode = parent; |
390 | new_node = hfs_bnode_split(fd); | 391 | new_node = hfs_bnode_split(fd); |
391 | if (IS_ERR(new_node)) | 392 | if (IS_ERR(new_node)) |
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 1cbdeea1db44..1ab19e660e69 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c | |||
@@ -48,7 +48,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
48 | mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); | 48 | mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); |
49 | if (HFS_I(tree->inode)->alloc_blocks > | 49 | if (HFS_I(tree->inode)->alloc_blocks > |
50 | HFS_I(tree->inode)->first_blocks) { | 50 | HFS_I(tree->inode)->first_blocks) { |
51 | printk(KERN_ERR "hfs: invalid btree extent records\n"); | 51 | pr_err("invalid btree extent records\n"); |
52 | unlock_new_inode(tree->inode); | 52 | unlock_new_inode(tree->inode); |
53 | goto free_inode; | 53 | goto free_inode; |
54 | } | 54 | } |
@@ -60,8 +60,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
60 | mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); | 60 | mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); |
61 | 61 | ||
62 | if (!HFS_I(tree->inode)->first_blocks) { | 62 | if (!HFS_I(tree->inode)->first_blocks) { |
63 | printk(KERN_ERR "hfs: invalid btree extent records " | 63 | pr_err("invalid btree extent records (0 size)\n"); |
64 | "(0 size).\n"); | ||
65 | unlock_new_inode(tree->inode); | 64 | unlock_new_inode(tree->inode); |
66 | goto free_inode; | 65 | goto free_inode; |
67 | } | 66 | } |
@@ -100,15 +99,15 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
100 | switch (id) { | 99 | switch (id) { |
101 | case HFS_EXT_CNID: | 100 | case HFS_EXT_CNID: |
102 | if (tree->max_key_len != HFS_MAX_EXT_KEYLEN) { | 101 | if (tree->max_key_len != HFS_MAX_EXT_KEYLEN) { |
103 | printk(KERN_ERR "hfs: invalid extent max_key_len %d\n", | 102 | pr_err("invalid extent max_key_len %d\n", |
104 | tree->max_key_len); | 103 | tree->max_key_len); |
105 | goto fail_page; | 104 | goto fail_page; |
106 | } | 105 | } |
107 | break; | 106 | break; |
108 | case HFS_CAT_CNID: | 107 | case HFS_CAT_CNID: |
109 | if (tree->max_key_len != HFS_MAX_CAT_KEYLEN) { | 108 | if (tree->max_key_len != HFS_MAX_CAT_KEYLEN) { |
110 | printk(KERN_ERR "hfs: invalid catalog max_key_len %d\n", | 109 | pr_err("invalid catalog max_key_len %d\n", |
111 | tree->max_key_len); | 110 | tree->max_key_len); |
112 | goto fail_page; | 111 | goto fail_page; |
113 | } | 112 | } |
114 | break; | 113 | break; |
@@ -146,8 +145,9 @@ void hfs_btree_close(struct hfs_btree *tree) | |||
146 | while ((node = tree->node_hash[i])) { | 145 | while ((node = tree->node_hash[i])) { |
147 | tree->node_hash[i] = node->next_hash; | 146 | tree->node_hash[i] = node->next_hash; |
148 | if (atomic_read(&node->refcnt)) | 147 | if (atomic_read(&node->refcnt)) |
149 | printk(KERN_ERR "hfs: node %d:%d still has %d user(s)!\n", | 148 | pr_err("node %d:%d still has %d user(s)!\n", |
150 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); | 149 | node->tree->cnid, node->this, |
150 | atomic_read(&node->refcnt)); | ||
151 | hfs_bnode_free(node); | 151 | hfs_bnode_free(node); |
152 | tree->node_hash_cnt--; | 152 | tree->node_hash_cnt--; |
153 | } | 153 | } |
@@ -290,7 +290,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) | |||
290 | kunmap(*pagep); | 290 | kunmap(*pagep); |
291 | nidx = node->next; | 291 | nidx = node->next; |
292 | if (!nidx) { | 292 | if (!nidx) { |
293 | printk(KERN_DEBUG "hfs: create new bmap node...\n"); | 293 | printk(KERN_DEBUG "create new bmap node...\n"); |
294 | next_node = hfs_bmap_new_bmap(node, idx); | 294 | next_node = hfs_bmap_new_bmap(node, idx); |
295 | } else | 295 | } else |
296 | next_node = hfs_bnode_find(tree, nidx); | 296 | next_node = hfs_bnode_find(tree, nidx); |
@@ -316,7 +316,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
316 | u32 nidx; | 316 | u32 nidx; |
317 | u8 *data, byte, m; | 317 | u8 *data, byte, m; |
318 | 318 | ||
319 | dprint(DBG_BNODE_MOD, "btree_free_node: %u\n", node->this); | 319 | hfs_dbg(BNODE_MOD, "btree_free_node: %u\n", node->this); |
320 | tree = node->tree; | 320 | tree = node->tree; |
321 | nidx = node->this; | 321 | nidx = node->this; |
322 | node = hfs_bnode_find(tree, 0); | 322 | node = hfs_bnode_find(tree, 0); |
@@ -331,7 +331,8 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
331 | hfs_bnode_put(node); | 331 | hfs_bnode_put(node); |
332 | if (!i) { | 332 | if (!i) { |
333 | /* panic */; | 333 | /* panic */; |
334 | printk(KERN_CRIT "hfs: unable to free bnode %u. bmap not found!\n", node->this); | 334 | pr_crit("unable to free bnode %u. bmap not found!\n", |
335 | node->this); | ||
335 | return; | 336 | return; |
336 | } | 337 | } |
337 | node = hfs_bnode_find(tree, i); | 338 | node = hfs_bnode_find(tree, i); |
@@ -339,7 +340,8 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
339 | return; | 340 | return; |
340 | if (node->type != HFS_NODE_MAP) { | 341 | if (node->type != HFS_NODE_MAP) { |
341 | /* panic */; | 342 | /* panic */; |
342 | printk(KERN_CRIT "hfs: invalid bmap found! (%u,%d)\n", node->this, node->type); | 343 | pr_crit("invalid bmap found! (%u,%d)\n", |
344 | node->this, node->type); | ||
343 | hfs_bnode_put(node); | 345 | hfs_bnode_put(node); |
344 | return; | 346 | return; |
345 | } | 347 | } |
@@ -352,7 +354,8 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
352 | m = 1 << (~nidx & 7); | 354 | m = 1 << (~nidx & 7); |
353 | byte = data[off]; | 355 | byte = data[off]; |
354 | if (!(byte & m)) { | 356 | if (!(byte & m)) { |
355 | printk(KERN_CRIT "hfs: trying to free free bnode %u(%d)\n", node->this, node->type); | 357 | pr_crit("trying to free free bnode %u(%d)\n", |
358 | node->this, node->type); | ||
356 | kunmap(page); | 359 | kunmap(page); |
357 | hfs_bnode_put(node); | 360 | hfs_bnode_put(node); |
358 | return; | 361 | return; |
diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c index 424b0337f524..ff0316b925a5 100644 --- a/fs/hfs/catalog.c +++ b/fs/hfs/catalog.c | |||
@@ -87,12 +87,15 @@ int hfs_cat_create(u32 cnid, struct inode *dir, struct qstr *str, struct inode * | |||
87 | int entry_size; | 87 | int entry_size; |
88 | int err; | 88 | int err; |
89 | 89 | ||
90 | dprint(DBG_CAT_MOD, "create_cat: %s,%u(%d)\n", str->name, cnid, inode->i_nlink); | 90 | hfs_dbg(CAT_MOD, "create_cat: %s,%u(%d)\n", |
91 | str->name, cnid, inode->i_nlink); | ||
91 | if (dir->i_size >= HFS_MAX_VALENCE) | 92 | if (dir->i_size >= HFS_MAX_VALENCE) |
92 | return -ENOSPC; | 93 | return -ENOSPC; |
93 | 94 | ||
94 | sb = dir->i_sb; | 95 | sb = dir->i_sb; |
95 | hfs_find_init(HFS_SB(sb)->cat_tree, &fd); | 96 | err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); |
97 | if (err) | ||
98 | return err; | ||
96 | 99 | ||
97 | hfs_cat_build_key(sb, fd.search_key, cnid, NULL); | 100 | hfs_cat_build_key(sb, fd.search_key, cnid, NULL); |
98 | entry_size = hfs_cat_build_thread(sb, &entry, S_ISDIR(inode->i_mode) ? | 101 | entry_size = hfs_cat_build_thread(sb, &entry, S_ISDIR(inode->i_mode) ? |
@@ -184,14 +187,14 @@ int hfs_cat_find_brec(struct super_block *sb, u32 cnid, | |||
184 | 187 | ||
185 | type = rec.type; | 188 | type = rec.type; |
186 | if (type != HFS_CDR_THD && type != HFS_CDR_FTH) { | 189 | if (type != HFS_CDR_THD && type != HFS_CDR_FTH) { |
187 | printk(KERN_ERR "hfs: found bad thread record in catalog\n"); | 190 | pr_err("found bad thread record in catalog\n"); |
188 | return -EIO; | 191 | return -EIO; |
189 | } | 192 | } |
190 | 193 | ||
191 | fd->search_key->cat.ParID = rec.thread.ParID; | 194 | fd->search_key->cat.ParID = rec.thread.ParID; |
192 | len = fd->search_key->cat.CName.len = rec.thread.CName.len; | 195 | len = fd->search_key->cat.CName.len = rec.thread.CName.len; |
193 | if (len > HFS_NAMELEN) { | 196 | if (len > HFS_NAMELEN) { |
194 | printk(KERN_ERR "hfs: bad catalog namelength\n"); | 197 | pr_err("bad catalog namelength\n"); |
195 | return -EIO; | 198 | return -EIO; |
196 | } | 199 | } |
197 | memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len); | 200 | memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len); |
@@ -212,9 +215,11 @@ int hfs_cat_delete(u32 cnid, struct inode *dir, struct qstr *str) | |||
212 | struct list_head *pos; | 215 | struct list_head *pos; |
213 | int res, type; | 216 | int res, type; |
214 | 217 | ||
215 | dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); | 218 | hfs_dbg(CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); |
216 | sb = dir->i_sb; | 219 | sb = dir->i_sb; |
217 | hfs_find_init(HFS_SB(sb)->cat_tree, &fd); | 220 | res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); |
221 | if (res) | ||
222 | return res; | ||
218 | 223 | ||
219 | hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str); | 224 | hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str); |
220 | res = hfs_brec_find(&fd); | 225 | res = hfs_brec_find(&fd); |
@@ -278,10 +283,13 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, struct qstr *src_name, | |||
278 | int entry_size, type; | 283 | int entry_size, type; |
279 | int err; | 284 | int err; |
280 | 285 | ||
281 | dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", cnid, src_dir->i_ino, src_name->name, | 286 | hfs_dbg(CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", |
287 | cnid, src_dir->i_ino, src_name->name, | ||
282 | dst_dir->i_ino, dst_name->name); | 288 | dst_dir->i_ino, dst_name->name); |
283 | sb = src_dir->i_sb; | 289 | sb = src_dir->i_sb; |
284 | hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); | 290 | err = hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); |
291 | if (err) | ||
292 | return err; | ||
285 | dst_fd = src_fd; | 293 | dst_fd = src_fd; |
286 | 294 | ||
287 | /* find the old dir entry and read the data */ | 295 | /* find the old dir entry and read the data */ |
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 5f7f1abd5f6d..17c22a8fd40a 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -25,7 +25,9 @@ static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, | |||
25 | struct inode *inode = NULL; | 25 | struct inode *inode = NULL; |
26 | int res; | 26 | int res; |
27 | 27 | ||
28 | hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); | 28 | res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); |
29 | if (res) | ||
30 | return ERR_PTR(res); | ||
29 | hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); | 31 | hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); |
30 | res = hfs_brec_read(&fd, &rec, sizeof(rec)); | 32 | res = hfs_brec_read(&fd, &rec, sizeof(rec)); |
31 | if (res) { | 33 | if (res) { |
@@ -63,7 +65,9 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
63 | if (filp->f_pos >= inode->i_size) | 65 | if (filp->f_pos >= inode->i_size) |
64 | return 0; | 66 | return 0; |
65 | 67 | ||
66 | hfs_find_init(HFS_SB(sb)->cat_tree, &fd); | 68 | err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); |
69 | if (err) | ||
70 | return err; | ||
67 | hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); | 71 | hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); |
68 | err = hfs_brec_find(&fd); | 72 | err = hfs_brec_find(&fd); |
69 | if (err) | 73 | if (err) |
@@ -84,12 +88,12 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
84 | 88 | ||
85 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); | 89 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); |
86 | if (entry.type != HFS_CDR_THD) { | 90 | if (entry.type != HFS_CDR_THD) { |
87 | printk(KERN_ERR "hfs: bad catalog folder thread\n"); | 91 | pr_err("bad catalog folder thread\n"); |
88 | err = -EIO; | 92 | err = -EIO; |
89 | goto out; | 93 | goto out; |
90 | } | 94 | } |
91 | //if (fd.entrylength < HFS_MIN_THREAD_SZ) { | 95 | //if (fd.entrylength < HFS_MIN_THREAD_SZ) { |
92 | // printk(KERN_ERR "hfs: truncated catalog thread\n"); | 96 | // pr_err("truncated catalog thread\n"); |
93 | // err = -EIO; | 97 | // err = -EIO; |
94 | // goto out; | 98 | // goto out; |
95 | //} | 99 | //} |
@@ -108,7 +112,7 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
108 | 112 | ||
109 | for (;;) { | 113 | for (;;) { |
110 | if (be32_to_cpu(fd.key->cat.ParID) != inode->i_ino) { | 114 | if (be32_to_cpu(fd.key->cat.ParID) != inode->i_ino) { |
111 | printk(KERN_ERR "hfs: walked past end of dir\n"); | 115 | pr_err("walked past end of dir\n"); |
112 | err = -EIO; | 116 | err = -EIO; |
113 | goto out; | 117 | goto out; |
114 | } | 118 | } |
@@ -123,7 +127,7 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
123 | len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName); | 127 | len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName); |
124 | if (type == HFS_CDR_DIR) { | 128 | if (type == HFS_CDR_DIR) { |
125 | if (fd.entrylength < sizeof(struct hfs_cat_dir)) { | 129 | if (fd.entrylength < sizeof(struct hfs_cat_dir)) { |
126 | printk(KERN_ERR "hfs: small dir entry\n"); | 130 | pr_err("small dir entry\n"); |
127 | err = -EIO; | 131 | err = -EIO; |
128 | goto out; | 132 | goto out; |
129 | } | 133 | } |
@@ -132,7 +136,7 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
132 | break; | 136 | break; |
133 | } else if (type == HFS_CDR_FIL) { | 137 | } else if (type == HFS_CDR_FIL) { |
134 | if (fd.entrylength < sizeof(struct hfs_cat_file)) { | 138 | if (fd.entrylength < sizeof(struct hfs_cat_file)) { |
135 | printk(KERN_ERR "hfs: small file entry\n"); | 139 | pr_err("small file entry\n"); |
136 | err = -EIO; | 140 | err = -EIO; |
137 | goto out; | 141 | goto out; |
138 | } | 142 | } |
@@ -140,7 +144,7 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
140 | be32_to_cpu(entry.file.FlNum), DT_REG)) | 144 | be32_to_cpu(entry.file.FlNum), DT_REG)) |
141 | break; | 145 | break; |
142 | } else { | 146 | } else { |
143 | printk(KERN_ERR "hfs: bad catalog entry type %d\n", type); | 147 | pr_err("bad catalog entry type %d\n", type); |
144 | err = -EIO; | 148 | err = -EIO; |
145 | goto out; | 149 | goto out; |
146 | } | 150 | } |
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index a67955a0c36f..e33a0d36a93e 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c | |||
@@ -107,7 +107,7 @@ static u16 hfs_ext_lastblock(struct hfs_extent *ext) | |||
107 | return be16_to_cpu(ext->block) + be16_to_cpu(ext->count); | 107 | return be16_to_cpu(ext->block) + be16_to_cpu(ext->count); |
108 | } | 108 | } |
109 | 109 | ||
110 | static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) | 110 | static int __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) |
111 | { | 111 | { |
112 | int res; | 112 | int res; |
113 | 113 | ||
@@ -116,26 +116,31 @@ static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd | |||
116 | res = hfs_brec_find(fd); | 116 | res = hfs_brec_find(fd); |
117 | if (HFS_I(inode)->flags & HFS_FLG_EXT_NEW) { | 117 | if (HFS_I(inode)->flags & HFS_FLG_EXT_NEW) { |
118 | if (res != -ENOENT) | 118 | if (res != -ENOENT) |
119 | return; | 119 | return res; |
120 | hfs_brec_insert(fd, HFS_I(inode)->cached_extents, sizeof(hfs_extent_rec)); | 120 | hfs_brec_insert(fd, HFS_I(inode)->cached_extents, sizeof(hfs_extent_rec)); |
121 | HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW); | 121 | HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW); |
122 | } else { | 122 | } else { |
123 | if (res) | 123 | if (res) |
124 | return; | 124 | return res; |
125 | hfs_bnode_write(fd->bnode, HFS_I(inode)->cached_extents, fd->entryoffset, fd->entrylength); | 125 | hfs_bnode_write(fd->bnode, HFS_I(inode)->cached_extents, fd->entryoffset, fd->entrylength); |
126 | HFS_I(inode)->flags &= ~HFS_FLG_EXT_DIRTY; | 126 | HFS_I(inode)->flags &= ~HFS_FLG_EXT_DIRTY; |
127 | } | 127 | } |
128 | return 0; | ||
128 | } | 129 | } |
129 | 130 | ||
130 | void hfs_ext_write_extent(struct inode *inode) | 131 | int hfs_ext_write_extent(struct inode *inode) |
131 | { | 132 | { |
132 | struct hfs_find_data fd; | 133 | struct hfs_find_data fd; |
134 | int res = 0; | ||
133 | 135 | ||
134 | if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) { | 136 | if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) { |
135 | hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd); | 137 | res = hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd); |
136 | __hfs_ext_write_extent(inode, &fd); | 138 | if (res) |
139 | return res; | ||
140 | res = __hfs_ext_write_extent(inode, &fd); | ||
137 | hfs_find_exit(&fd); | 141 | hfs_find_exit(&fd); |
138 | } | 142 | } |
143 | return res; | ||
139 | } | 144 | } |
140 | 145 | ||
141 | static inline int __hfs_ext_read_extent(struct hfs_find_data *fd, struct hfs_extent *extent, | 146 | static inline int __hfs_ext_read_extent(struct hfs_find_data *fd, struct hfs_extent *extent, |
@@ -161,8 +166,11 @@ static inline int __hfs_ext_cache_extent(struct hfs_find_data *fd, struct inode | |||
161 | { | 166 | { |
162 | int res; | 167 | int res; |
163 | 168 | ||
164 | if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) | 169 | if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) { |
165 | __hfs_ext_write_extent(inode, fd); | 170 | res = __hfs_ext_write_extent(inode, fd); |
171 | if (res) | ||
172 | return res; | ||
173 | } | ||
166 | 174 | ||
167 | res = __hfs_ext_read_extent(fd, HFS_I(inode)->cached_extents, inode->i_ino, | 175 | res = __hfs_ext_read_extent(fd, HFS_I(inode)->cached_extents, inode->i_ino, |
168 | block, HFS_IS_RSRC(inode) ? HFS_FK_RSRC : HFS_FK_DATA); | 176 | block, HFS_IS_RSRC(inode) ? HFS_FK_RSRC : HFS_FK_DATA); |
@@ -185,9 +193,11 @@ static int hfs_ext_read_extent(struct inode *inode, u16 block) | |||
185 | block < HFS_I(inode)->cached_start + HFS_I(inode)->cached_blocks) | 193 | block < HFS_I(inode)->cached_start + HFS_I(inode)->cached_blocks) |
186 | return 0; | 194 | return 0; |
187 | 195 | ||
188 | hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd); | 196 | res = hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd); |
189 | res = __hfs_ext_cache_extent(&fd, inode, block); | 197 | if (!res) { |
190 | hfs_find_exit(&fd); | 198 | res = __hfs_ext_cache_extent(&fd, inode, block); |
199 | hfs_find_exit(&fd); | ||
200 | } | ||
191 | return res; | 201 | return res; |
192 | } | 202 | } |
193 | 203 | ||
@@ -195,11 +205,12 @@ static void hfs_dump_extent(struct hfs_extent *extent) | |||
195 | { | 205 | { |
196 | int i; | 206 | int i; |
197 | 207 | ||
198 | dprint(DBG_EXTENT, " "); | 208 | hfs_dbg(EXTENT, " "); |
199 | for (i = 0; i < 3; i++) | 209 | for (i = 0; i < 3; i++) |
200 | dprint(DBG_EXTENT, " %u:%u", be16_to_cpu(extent[i].block), | 210 | hfs_dbg_cont(EXTENT, " %u:%u", |
201 | be16_to_cpu(extent[i].count)); | 211 | be16_to_cpu(extent[i].block), |
202 | dprint(DBG_EXTENT, "\n"); | 212 | be16_to_cpu(extent[i].count)); |
213 | hfs_dbg_cont(EXTENT, "\n"); | ||
203 | } | 214 | } |
204 | 215 | ||
205 | static int hfs_add_extent(struct hfs_extent *extent, u16 offset, | 216 | static int hfs_add_extent(struct hfs_extent *extent, u16 offset, |
@@ -298,7 +309,9 @@ int hfs_free_fork(struct super_block *sb, struct hfs_cat_file *file, int type) | |||
298 | if (total_blocks == blocks) | 309 | if (total_blocks == blocks) |
299 | return 0; | 310 | return 0; |
300 | 311 | ||
301 | hfs_find_init(HFS_SB(sb)->ext_tree, &fd); | 312 | res = hfs_find_init(HFS_SB(sb)->ext_tree, &fd); |
313 | if (res) | ||
314 | return res; | ||
302 | do { | 315 | do { |
303 | res = __hfs_ext_read_extent(&fd, extent, cnid, total_blocks, type); | 316 | res = __hfs_ext_read_extent(&fd, extent, cnid, total_blocks, type); |
304 | if (res) | 317 | if (res) |
@@ -392,10 +405,10 @@ int hfs_extend_file(struct inode *inode) | |||
392 | goto out; | 405 | goto out; |
393 | } | 406 | } |
394 | 407 | ||
395 | dprint(DBG_EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); | 408 | hfs_dbg(EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); |
396 | if (HFS_I(inode)->alloc_blocks == HFS_I(inode)->first_blocks) { | 409 | if (HFS_I(inode)->alloc_blocks == HFS_I(inode)->first_blocks) { |
397 | if (!HFS_I(inode)->first_blocks) { | 410 | if (!HFS_I(inode)->first_blocks) { |
398 | dprint(DBG_EXTENT, "first extents\n"); | 411 | hfs_dbg(EXTENT, "first extents\n"); |
399 | /* no extents yet */ | 412 | /* no extents yet */ |
400 | HFS_I(inode)->first_extents[0].block = cpu_to_be16(start); | 413 | HFS_I(inode)->first_extents[0].block = cpu_to_be16(start); |
401 | HFS_I(inode)->first_extents[0].count = cpu_to_be16(len); | 414 | HFS_I(inode)->first_extents[0].count = cpu_to_be16(len); |
@@ -437,8 +450,10 @@ out: | |||
437 | return res; | 450 | return res; |
438 | 451 | ||
439 | insert_extent: | 452 | insert_extent: |
440 | dprint(DBG_EXTENT, "insert new extent\n"); | 453 | hfs_dbg(EXTENT, "insert new extent\n"); |
441 | hfs_ext_write_extent(inode); | 454 | res = hfs_ext_write_extent(inode); |
455 | if (res) | ||
456 | goto out; | ||
442 | 457 | ||
443 | memset(HFS_I(inode)->cached_extents, 0, sizeof(hfs_extent_rec)); | 458 | memset(HFS_I(inode)->cached_extents, 0, sizeof(hfs_extent_rec)); |
444 | HFS_I(inode)->cached_extents[0].block = cpu_to_be16(start); | 459 | HFS_I(inode)->cached_extents[0].block = cpu_to_be16(start); |
@@ -460,13 +475,13 @@ void hfs_file_truncate(struct inode *inode) | |||
460 | u32 size; | 475 | u32 size; |
461 | int res; | 476 | int res; |
462 | 477 | ||
463 | dprint(DBG_INODE, "truncate: %lu, %Lu -> %Lu\n", inode->i_ino, | 478 | hfs_dbg(INODE, "truncate: %lu, %Lu -> %Lu\n", |
464 | (long long)HFS_I(inode)->phys_size, inode->i_size); | 479 | inode->i_ino, (long long)HFS_I(inode)->phys_size, |
480 | inode->i_size); | ||
465 | if (inode->i_size > HFS_I(inode)->phys_size) { | 481 | if (inode->i_size > HFS_I(inode)->phys_size) { |
466 | struct address_space *mapping = inode->i_mapping; | 482 | struct address_space *mapping = inode->i_mapping; |
467 | void *fsdata; | 483 | void *fsdata; |
468 | struct page *page; | 484 | struct page *page; |
469 | int res; | ||
470 | 485 | ||
471 | /* XXX: Can use generic_cont_expand? */ | 486 | /* XXX: Can use generic_cont_expand? */ |
472 | size = inode->i_size - 1; | 487 | size = inode->i_size - 1; |
@@ -488,7 +503,12 @@ void hfs_file_truncate(struct inode *inode) | |||
488 | goto out; | 503 | goto out; |
489 | 504 | ||
490 | mutex_lock(&HFS_I(inode)->extents_lock); | 505 | mutex_lock(&HFS_I(inode)->extents_lock); |
491 | hfs_find_init(HFS_SB(sb)->ext_tree, &fd); | 506 | res = hfs_find_init(HFS_SB(sb)->ext_tree, &fd); |
507 | if (res) { | ||
508 | mutex_unlock(&HFS_I(inode)->extents_lock); | ||
509 | /* XXX: We lack error handling of hfs_file_truncate() */ | ||
510 | return; | ||
511 | } | ||
492 | while (1) { | 512 | while (1) { |
493 | if (alloc_cnt == HFS_I(inode)->first_blocks) { | 513 | if (alloc_cnt == HFS_I(inode)->first_blocks) { |
494 | hfs_free_extents(sb, HFS_I(inode)->first_extents, | 514 | hfs_free_extents(sb, HFS_I(inode)->first_extents, |
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index 693df9fe52b2..a73b11839a41 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -9,6 +9,12 @@ | |||
9 | #ifndef _LINUX_HFS_FS_H | 9 | #ifndef _LINUX_HFS_FS_H |
10 | #define _LINUX_HFS_FS_H | 10 | #define _LINUX_HFS_FS_H |
11 | 11 | ||
12 | #ifdef pr_fmt | ||
13 | #undef pr_fmt | ||
14 | #endif | ||
15 | |||
16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
17 | |||
12 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
13 | #include <linux/types.h> | 19 | #include <linux/types.h> |
14 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
@@ -34,8 +40,18 @@ | |||
34 | //#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT) | 40 | //#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT) |
35 | #define DBG_MASK (0) | 41 | #define DBG_MASK (0) |
36 | 42 | ||
37 | #define dprint(flg, fmt, args...) \ | 43 | #define hfs_dbg(flg, fmt, ...) \ |
38 | if (flg & DBG_MASK) printk(fmt , ## args) | 44 | do { \ |
45 | if (DBG_##flg & DBG_MASK) \ | ||
46 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ | ||
47 | } while (0) | ||
48 | |||
49 | #define hfs_dbg_cont(flg, fmt, ...) \ | ||
50 | do { \ | ||
51 | if (DBG_##flg & DBG_MASK) \ | ||
52 | pr_cont(fmt, ##__VA_ARGS__); \ | ||
53 | } while (0) | ||
54 | |||
39 | 55 | ||
40 | /* | 56 | /* |
41 | * struct hfs_inode_info | 57 | * struct hfs_inode_info |
@@ -174,7 +190,7 @@ extern const struct inode_operations hfs_dir_inode_operations; | |||
174 | /* extent.c */ | 190 | /* extent.c */ |
175 | extern int hfs_ext_keycmp(const btree_key *, const btree_key *); | 191 | extern int hfs_ext_keycmp(const btree_key *, const btree_key *); |
176 | extern int hfs_free_fork(struct super_block *, struct hfs_cat_file *, int); | 192 | extern int hfs_free_fork(struct super_block *, struct hfs_cat_file *, int); |
177 | extern void hfs_ext_write_extent(struct inode *); | 193 | extern int hfs_ext_write_extent(struct inode *); |
178 | extern int hfs_extend_file(struct inode *); | 194 | extern int hfs_extend_file(struct inode *); |
179 | extern void hfs_file_truncate(struct inode *); | 195 | extern void hfs_file_truncate(struct inode *); |
180 | 196 | ||
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 3031dfdd2358..716e1aafb2e2 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -237,7 +237,7 @@ void hfs_delete_inode(struct inode *inode) | |||
237 | { | 237 | { |
238 | struct super_block *sb = inode->i_sb; | 238 | struct super_block *sb = inode->i_sb; |
239 | 239 | ||
240 | dprint(DBG_INODE, "delete_inode: %lu\n", inode->i_ino); | 240 | hfs_dbg(INODE, "delete_inode: %lu\n", inode->i_ino); |
241 | if (S_ISDIR(inode->i_mode)) { | 241 | if (S_ISDIR(inode->i_mode)) { |
242 | HFS_SB(sb)->folder_count--; | 242 | HFS_SB(sb)->folder_count--; |
243 | if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID)) | 243 | if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID)) |
@@ -416,9 +416,12 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
416 | struct inode *main_inode = inode; | 416 | struct inode *main_inode = inode; |
417 | struct hfs_find_data fd; | 417 | struct hfs_find_data fd; |
418 | hfs_cat_rec rec; | 418 | hfs_cat_rec rec; |
419 | int res; | ||
419 | 420 | ||
420 | dprint(DBG_INODE, "hfs_write_inode: %lu\n", inode->i_ino); | 421 | hfs_dbg(INODE, "hfs_write_inode: %lu\n", inode->i_ino); |
421 | hfs_ext_write_extent(inode); | 422 | res = hfs_ext_write_extent(inode); |
423 | if (res) | ||
424 | return res; | ||
422 | 425 | ||
423 | if (inode->i_ino < HFS_FIRSTUSER_CNID) { | 426 | if (inode->i_ino < HFS_FIRSTUSER_CNID) { |
424 | switch (inode->i_ino) { | 427 | switch (inode->i_ino) { |
@@ -515,7 +518,11 @@ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry, | |||
515 | if (!inode) | 518 | if (!inode) |
516 | return ERR_PTR(-ENOMEM); | 519 | return ERR_PTR(-ENOMEM); |
517 | 520 | ||
518 | hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); | 521 | res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); |
522 | if (res) { | ||
523 | iput(inode); | ||
524 | return ERR_PTR(res); | ||
525 | } | ||
519 | fd.search_key->cat = HFS_I(dir)->cat_key; | 526 | fd.search_key->cat = HFS_I(dir)->cat_key; |
520 | res = hfs_brec_read(&fd, &rec, sizeof(rec)); | 527 | res = hfs_brec_read(&fd, &rec, sizeof(rec)); |
521 | if (!res) { | 528 | if (!res) { |
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index b7ec224910c5..aa3f0d6d043c 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c | |||
@@ -48,7 +48,7 @@ static int hfs_get_last_session(struct super_block *sb, | |||
48 | *start = (sector_t)te.cdte_addr.lba << 2; | 48 | *start = (sector_t)te.cdte_addr.lba << 2; |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | printk(KERN_ERR "hfs: invalid session number or type of track\n"); | 51 | pr_err("invalid session number or type of track\n"); |
52 | return -EINVAL; | 52 | return -EINVAL; |
53 | } | 53 | } |
54 | ms_info.addr_format = CDROM_LBA; | 54 | ms_info.addr_format = CDROM_LBA; |
@@ -101,7 +101,7 @@ int hfs_mdb_get(struct super_block *sb) | |||
101 | 101 | ||
102 | HFS_SB(sb)->alloc_blksz = size = be32_to_cpu(mdb->drAlBlkSiz); | 102 | HFS_SB(sb)->alloc_blksz = size = be32_to_cpu(mdb->drAlBlkSiz); |
103 | if (!size || (size & (HFS_SECTOR_SIZE - 1))) { | 103 | if (!size || (size & (HFS_SECTOR_SIZE - 1))) { |
104 | printk(KERN_ERR "hfs: bad allocation block size %d\n", size); | 104 | pr_err("bad allocation block size %d\n", size); |
105 | goto out_bh; | 105 | goto out_bh; |
106 | } | 106 | } |
107 | 107 | ||
@@ -118,7 +118,7 @@ int hfs_mdb_get(struct super_block *sb) | |||
118 | size >>= 1; | 118 | size >>= 1; |
119 | brelse(bh); | 119 | brelse(bh); |
120 | if (!sb_set_blocksize(sb, size)) { | 120 | if (!sb_set_blocksize(sb, size)) { |
121 | printk(KERN_ERR "hfs: unable to set blocksize to %u\n", size); | 121 | pr_err("unable to set blocksize to %u\n", size); |
122 | goto out; | 122 | goto out; |
123 | } | 123 | } |
124 | 124 | ||
@@ -162,8 +162,8 @@ int hfs_mdb_get(struct super_block *sb) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | if (!HFS_SB(sb)->alt_mdb) { | 164 | if (!HFS_SB(sb)->alt_mdb) { |
165 | printk(KERN_WARNING "hfs: unable to locate alternate MDB\n"); | 165 | pr_warn("unable to locate alternate MDB\n"); |
166 | printk(KERN_WARNING "hfs: continuing without an alternate MDB\n"); | 166 | pr_warn("continuing without an alternate MDB\n"); |
167 | } | 167 | } |
168 | 168 | ||
169 | HFS_SB(sb)->bitmap = (__be32 *)__get_free_pages(GFP_KERNEL, PAGE_SIZE < 8192 ? 1 : 0); | 169 | HFS_SB(sb)->bitmap = (__be32 *)__get_free_pages(GFP_KERNEL, PAGE_SIZE < 8192 ? 1 : 0); |
@@ -178,7 +178,7 @@ int hfs_mdb_get(struct super_block *sb) | |||
178 | while (size) { | 178 | while (size) { |
179 | bh = sb_bread(sb, off >> sb->s_blocksize_bits); | 179 | bh = sb_bread(sb, off >> sb->s_blocksize_bits); |
180 | if (!bh) { | 180 | if (!bh) { |
181 | printk(KERN_ERR "hfs: unable to read volume bitmap\n"); | 181 | pr_err("unable to read volume bitmap\n"); |
182 | goto out; | 182 | goto out; |
183 | } | 183 | } |
184 | off2 = off & (sb->s_blocksize - 1); | 184 | off2 = off & (sb->s_blocksize - 1); |
@@ -192,23 +192,22 @@ int hfs_mdb_get(struct super_block *sb) | |||
192 | 192 | ||
193 | HFS_SB(sb)->ext_tree = hfs_btree_open(sb, HFS_EXT_CNID, hfs_ext_keycmp); | 193 | HFS_SB(sb)->ext_tree = hfs_btree_open(sb, HFS_EXT_CNID, hfs_ext_keycmp); |
194 | if (!HFS_SB(sb)->ext_tree) { | 194 | if (!HFS_SB(sb)->ext_tree) { |
195 | printk(KERN_ERR "hfs: unable to open extent tree\n"); | 195 | pr_err("unable to open extent tree\n"); |
196 | goto out; | 196 | goto out; |
197 | } | 197 | } |
198 | HFS_SB(sb)->cat_tree = hfs_btree_open(sb, HFS_CAT_CNID, hfs_cat_keycmp); | 198 | HFS_SB(sb)->cat_tree = hfs_btree_open(sb, HFS_CAT_CNID, hfs_cat_keycmp); |
199 | if (!HFS_SB(sb)->cat_tree) { | 199 | if (!HFS_SB(sb)->cat_tree) { |
200 | printk(KERN_ERR "hfs: unable to open catalog tree\n"); | 200 | pr_err("unable to open catalog tree\n"); |
201 | goto out; | 201 | goto out; |
202 | } | 202 | } |
203 | 203 | ||
204 | attrib = mdb->drAtrb; | 204 | attrib = mdb->drAtrb; |
205 | if (!(attrib & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) { | 205 | if (!(attrib & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) { |
206 | printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, " | 206 | pr_warn("filesystem was not cleanly unmounted, running fsck.hfs is recommended. mounting read-only.\n"); |
207 | "running fsck.hfs is recommended. mounting read-only.\n"); | ||
208 | sb->s_flags |= MS_RDONLY; | 207 | sb->s_flags |= MS_RDONLY; |
209 | } | 208 | } |
210 | if ((attrib & cpu_to_be16(HFS_SB_ATTRIB_SLOCK))) { | 209 | if ((attrib & cpu_to_be16(HFS_SB_ATTRIB_SLOCK))) { |
211 | printk(KERN_WARNING "hfs: filesystem is marked locked, mounting read-only.\n"); | 210 | pr_warn("filesystem is marked locked, mounting read-only.\n"); |
212 | sb->s_flags |= MS_RDONLY; | 211 | sb->s_flags |= MS_RDONLY; |
213 | } | 212 | } |
214 | if (!(sb->s_flags & MS_RDONLY)) { | 213 | if (!(sb->s_flags & MS_RDONLY)) { |
@@ -312,7 +311,7 @@ void hfs_mdb_commit(struct super_block *sb) | |||
312 | while (size) { | 311 | while (size) { |
313 | bh = sb_bread(sb, block); | 312 | bh = sb_bread(sb, block); |
314 | if (!bh) { | 313 | if (!bh) { |
315 | printk(KERN_ERR "hfs: unable to read volume bitmap\n"); | 314 | pr_err("unable to read volume bitmap\n"); |
316 | break; | 315 | break; |
317 | } | 316 | } |
318 | len = min((int)sb->s_blocksize - off, size); | 317 | len = min((int)sb->s_blocksize - off, size); |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index bbaaa8a4ee64..2d2039e754cd 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -117,12 +117,11 @@ static int hfs_remount(struct super_block *sb, int *flags, char *data) | |||
117 | return 0; | 117 | return 0; |
118 | if (!(*flags & MS_RDONLY)) { | 118 | if (!(*flags & MS_RDONLY)) { |
119 | if (!(HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) { | 119 | if (!(HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) { |
120 | printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, " | 120 | pr_warn("filesystem was not cleanly unmounted, running fsck.hfs is recommended. leaving read-only.\n"); |
121 | "running fsck.hfs is recommended. leaving read-only.\n"); | ||
122 | sb->s_flags |= MS_RDONLY; | 121 | sb->s_flags |= MS_RDONLY; |
123 | *flags |= MS_RDONLY; | 122 | *flags |= MS_RDONLY; |
124 | } else if (HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_SLOCK)) { | 123 | } else if (HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_SLOCK)) { |
125 | printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n"); | 124 | pr_warn("filesystem is marked locked, leaving read-only.\n"); |
126 | sb->s_flags |= MS_RDONLY; | 125 | sb->s_flags |= MS_RDONLY; |
127 | *flags |= MS_RDONLY; | 126 | *flags |= MS_RDONLY; |
128 | } | 127 | } |
@@ -253,29 +252,29 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
253 | switch (token) { | 252 | switch (token) { |
254 | case opt_uid: | 253 | case opt_uid: |
255 | if (match_int(&args[0], &tmp)) { | 254 | if (match_int(&args[0], &tmp)) { |
256 | printk(KERN_ERR "hfs: uid requires an argument\n"); | 255 | pr_err("uid requires an argument\n"); |
257 | return 0; | 256 | return 0; |
258 | } | 257 | } |
259 | hsb->s_uid = make_kuid(current_user_ns(), (uid_t)tmp); | 258 | hsb->s_uid = make_kuid(current_user_ns(), (uid_t)tmp); |
260 | if (!uid_valid(hsb->s_uid)) { | 259 | if (!uid_valid(hsb->s_uid)) { |
261 | printk(KERN_ERR "hfs: invalid uid %d\n", tmp); | 260 | pr_err("invalid uid %d\n", tmp); |
262 | return 0; | 261 | return 0; |
263 | } | 262 | } |
264 | break; | 263 | break; |
265 | case opt_gid: | 264 | case opt_gid: |
266 | if (match_int(&args[0], &tmp)) { | 265 | if (match_int(&args[0], &tmp)) { |
267 | printk(KERN_ERR "hfs: gid requires an argument\n"); | 266 | pr_err("gid requires an argument\n"); |
268 | return 0; | 267 | return 0; |
269 | } | 268 | } |
270 | hsb->s_gid = make_kgid(current_user_ns(), (gid_t)tmp); | 269 | hsb->s_gid = make_kgid(current_user_ns(), (gid_t)tmp); |
271 | if (!gid_valid(hsb->s_gid)) { | 270 | if (!gid_valid(hsb->s_gid)) { |
272 | printk(KERN_ERR "hfs: invalid gid %d\n", tmp); | 271 | pr_err("invalid gid %d\n", tmp); |
273 | return 0; | 272 | return 0; |
274 | } | 273 | } |
275 | break; | 274 | break; |
276 | case opt_umask: | 275 | case opt_umask: |
277 | if (match_octal(&args[0], &tmp)) { | 276 | if (match_octal(&args[0], &tmp)) { |
278 | printk(KERN_ERR "hfs: umask requires a value\n"); | 277 | pr_err("umask requires a value\n"); |
279 | return 0; | 278 | return 0; |
280 | } | 279 | } |
281 | hsb->s_file_umask = (umode_t)tmp; | 280 | hsb->s_file_umask = (umode_t)tmp; |
@@ -283,39 +282,39 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
283 | break; | 282 | break; |
284 | case opt_file_umask: | 283 | case opt_file_umask: |
285 | if (match_octal(&args[0], &tmp)) { | 284 | if (match_octal(&args[0], &tmp)) { |
286 | printk(KERN_ERR "hfs: file_umask requires a value\n"); | 285 | pr_err("file_umask requires a value\n"); |
287 | return 0; | 286 | return 0; |
288 | } | 287 | } |
289 | hsb->s_file_umask = (umode_t)tmp; | 288 | hsb->s_file_umask = (umode_t)tmp; |
290 | break; | 289 | break; |
291 | case opt_dir_umask: | 290 | case opt_dir_umask: |
292 | if (match_octal(&args[0], &tmp)) { | 291 | if (match_octal(&args[0], &tmp)) { |
293 | printk(KERN_ERR "hfs: dir_umask requires a value\n"); | 292 | pr_err("dir_umask requires a value\n"); |
294 | return 0; | 293 | return 0; |
295 | } | 294 | } |
296 | hsb->s_dir_umask = (umode_t)tmp; | 295 | hsb->s_dir_umask = (umode_t)tmp; |
297 | break; | 296 | break; |
298 | case opt_part: | 297 | case opt_part: |
299 | if (match_int(&args[0], &hsb->part)) { | 298 | if (match_int(&args[0], &hsb->part)) { |
300 | printk(KERN_ERR "hfs: part requires an argument\n"); | 299 | pr_err("part requires an argument\n"); |
301 | return 0; | 300 | return 0; |
302 | } | 301 | } |
303 | break; | 302 | break; |
304 | case opt_session: | 303 | case opt_session: |
305 | if (match_int(&args[0], &hsb->session)) { | 304 | if (match_int(&args[0], &hsb->session)) { |
306 | printk(KERN_ERR "hfs: session requires an argument\n"); | 305 | pr_err("session requires an argument\n"); |
307 | return 0; | 306 | return 0; |
308 | } | 307 | } |
309 | break; | 308 | break; |
310 | case opt_type: | 309 | case opt_type: |
311 | if (match_fourchar(&args[0], &hsb->s_type)) { | 310 | if (match_fourchar(&args[0], &hsb->s_type)) { |
312 | printk(KERN_ERR "hfs: type requires a 4 character value\n"); | 311 | pr_err("type requires a 4 character value\n"); |
313 | return 0; | 312 | return 0; |
314 | } | 313 | } |
315 | break; | 314 | break; |
316 | case opt_creator: | 315 | case opt_creator: |
317 | if (match_fourchar(&args[0], &hsb->s_creator)) { | 316 | if (match_fourchar(&args[0], &hsb->s_creator)) { |
318 | printk(KERN_ERR "hfs: creator requires a 4 character value\n"); | 317 | pr_err("creator requires a 4 character value\n"); |
319 | return 0; | 318 | return 0; |
320 | } | 319 | } |
321 | break; | 320 | break; |
@@ -324,14 +323,14 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
324 | break; | 323 | break; |
325 | case opt_codepage: | 324 | case opt_codepage: |
326 | if (hsb->nls_disk) { | 325 | if (hsb->nls_disk) { |
327 | printk(KERN_ERR "hfs: unable to change codepage\n"); | 326 | pr_err("unable to change codepage\n"); |
328 | return 0; | 327 | return 0; |
329 | } | 328 | } |
330 | p = match_strdup(&args[0]); | 329 | p = match_strdup(&args[0]); |
331 | if (p) | 330 | if (p) |
332 | hsb->nls_disk = load_nls(p); | 331 | hsb->nls_disk = load_nls(p); |
333 | if (!hsb->nls_disk) { | 332 | if (!hsb->nls_disk) { |
334 | printk(KERN_ERR "hfs: unable to load codepage \"%s\"\n", p); | 333 | pr_err("unable to load codepage \"%s\"\n", p); |
335 | kfree(p); | 334 | kfree(p); |
336 | return 0; | 335 | return 0; |
337 | } | 336 | } |
@@ -339,14 +338,14 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
339 | break; | 338 | break; |
340 | case opt_iocharset: | 339 | case opt_iocharset: |
341 | if (hsb->nls_io) { | 340 | if (hsb->nls_io) { |
342 | printk(KERN_ERR "hfs: unable to change iocharset\n"); | 341 | pr_err("unable to change iocharset\n"); |
343 | return 0; | 342 | return 0; |
344 | } | 343 | } |
345 | p = match_strdup(&args[0]); | 344 | p = match_strdup(&args[0]); |
346 | if (p) | 345 | if (p) |
347 | hsb->nls_io = load_nls(p); | 346 | hsb->nls_io = load_nls(p); |
348 | if (!hsb->nls_io) { | 347 | if (!hsb->nls_io) { |
349 | printk(KERN_ERR "hfs: unable to load iocharset \"%s\"\n", p); | 348 | pr_err("unable to load iocharset \"%s\"\n", p); |
350 | kfree(p); | 349 | kfree(p); |
351 | return 0; | 350 | return 0; |
352 | } | 351 | } |
@@ -360,7 +359,7 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
360 | if (hsb->nls_disk && !hsb->nls_io) { | 359 | if (hsb->nls_disk && !hsb->nls_io) { |
361 | hsb->nls_io = load_nls_default(); | 360 | hsb->nls_io = load_nls_default(); |
362 | if (!hsb->nls_io) { | 361 | if (!hsb->nls_io) { |
363 | printk(KERN_ERR "hfs: unable to load default iocharset\n"); | 362 | pr_err("unable to load default iocharset\n"); |
364 | return 0; | 363 | return 0; |
365 | } | 364 | } |
366 | } | 365 | } |
@@ -400,7 +399,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
400 | 399 | ||
401 | res = -EINVAL; | 400 | res = -EINVAL; |
402 | if (!parse_options((char *)data, sbi)) { | 401 | if (!parse_options((char *)data, sbi)) { |
403 | printk(KERN_ERR "hfs: unable to parse mount options.\n"); | 402 | pr_err("unable to parse mount options\n"); |
404 | goto bail; | 403 | goto bail; |
405 | } | 404 | } |
406 | 405 | ||
@@ -411,14 +410,16 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
411 | res = hfs_mdb_get(sb); | 410 | res = hfs_mdb_get(sb); |
412 | if (res) { | 411 | if (res) { |
413 | if (!silent) | 412 | if (!silent) |
414 | printk(KERN_WARNING "hfs: can't find a HFS filesystem on dev %s.\n", | 413 | pr_warn("can't find a HFS filesystem on dev %s\n", |
415 | hfs_mdb_name(sb)); | 414 | hfs_mdb_name(sb)); |
416 | res = -EINVAL; | 415 | res = -EINVAL; |
417 | goto bail; | 416 | goto bail; |
418 | } | 417 | } |
419 | 418 | ||
420 | /* try to get the root inode */ | 419 | /* try to get the root inode */ |
421 | hfs_find_init(HFS_SB(sb)->cat_tree, &fd); | 420 | res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); |
421 | if (res) | ||
422 | goto bail_no_root; | ||
422 | res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); | 423 | res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); |
423 | if (!res) { | 424 | if (!res) { |
424 | if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { | 425 | if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { |
@@ -447,7 +448,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
447 | return 0; | 448 | return 0; |
448 | 449 | ||
449 | bail_no_root: | 450 | bail_no_root: |
450 | printk(KERN_ERR "hfs: get root inode failed.\n"); | 451 | pr_err("get root inode failed\n"); |
451 | bail: | 452 | bail: |
452 | hfs_mdb_put(sb); | 453 | hfs_mdb_put(sb); |
453 | return res; | 454 | return res; |
diff --git a/fs/hfsplus/attributes.c b/fs/hfsplus/attributes.c index 8d691f124714..0f47890299c4 100644 --- a/fs/hfsplus/attributes.c +++ b/fs/hfsplus/attributes.c | |||
@@ -56,7 +56,7 @@ int hfsplus_attr_build_key(struct super_block *sb, hfsplus_btree_key *key, | |||
56 | if (name) { | 56 | if (name) { |
57 | len = strlen(name); | 57 | len = strlen(name); |
58 | if (len > HFSPLUS_ATTR_MAX_STRLEN) { | 58 | if (len > HFSPLUS_ATTR_MAX_STRLEN) { |
59 | printk(KERN_ERR "hfs: invalid xattr name's length\n"); | 59 | pr_err("invalid xattr name's length\n"); |
60 | return -EINVAL; | 60 | return -EINVAL; |
61 | } | 61 | } |
62 | hfsplus_asc2uni(sb, | 62 | hfsplus_asc2uni(sb, |
@@ -166,10 +166,10 @@ int hfsplus_find_attr(struct super_block *sb, u32 cnid, | |||
166 | { | 166 | { |
167 | int err = 0; | 167 | int err = 0; |
168 | 168 | ||
169 | dprint(DBG_ATTR_MOD, "find_attr: %s,%d\n", name ? name : NULL, cnid); | 169 | hfs_dbg(ATTR_MOD, "find_attr: %s,%d\n", name ? name : NULL, cnid); |
170 | 170 | ||
171 | if (!HFSPLUS_SB(sb)->attr_tree) { | 171 | if (!HFSPLUS_SB(sb)->attr_tree) { |
172 | printk(KERN_ERR "hfs: attributes file doesn't exist\n"); | 172 | pr_err("attributes file doesn't exist\n"); |
173 | return -EINVAL; | 173 | return -EINVAL; |
174 | } | 174 | } |
175 | 175 | ||
@@ -228,11 +228,11 @@ int hfsplus_create_attr(struct inode *inode, | |||
228 | int entry_size; | 228 | int entry_size; |
229 | int err; | 229 | int err; |
230 | 230 | ||
231 | dprint(DBG_ATTR_MOD, "create_attr: %s,%ld\n", | 231 | hfs_dbg(ATTR_MOD, "create_attr: %s,%ld\n", |
232 | name ? name : NULL, inode->i_ino); | 232 | name ? name : NULL, inode->i_ino); |
233 | 233 | ||
234 | if (!HFSPLUS_SB(sb)->attr_tree) { | 234 | if (!HFSPLUS_SB(sb)->attr_tree) { |
235 | printk(KERN_ERR "hfs: attributes file doesn't exist\n"); | 235 | pr_err("attributes file doesn't exist\n"); |
236 | return -EINVAL; | 236 | return -EINVAL; |
237 | } | 237 | } |
238 | 238 | ||
@@ -307,10 +307,10 @@ static int __hfsplus_delete_attr(struct inode *inode, u32 cnid, | |||
307 | break; | 307 | break; |
308 | case HFSPLUS_ATTR_FORK_DATA: | 308 | case HFSPLUS_ATTR_FORK_DATA: |
309 | case HFSPLUS_ATTR_EXTENTS: | 309 | case HFSPLUS_ATTR_EXTENTS: |
310 | printk(KERN_ERR "hfs: only inline data xattr are supported\n"); | 310 | pr_err("only inline data xattr are supported\n"); |
311 | return -EOPNOTSUPP; | 311 | return -EOPNOTSUPP; |
312 | default: | 312 | default: |
313 | printk(KERN_ERR "hfs: invalid extended attribute record\n"); | 313 | pr_err("invalid extended attribute record\n"); |
314 | return -ENOENT; | 314 | return -ENOENT; |
315 | } | 315 | } |
316 | 316 | ||
@@ -328,11 +328,11 @@ int hfsplus_delete_attr(struct inode *inode, const char *name) | |||
328 | struct super_block *sb = inode->i_sb; | 328 | struct super_block *sb = inode->i_sb; |
329 | struct hfs_find_data fd; | 329 | struct hfs_find_data fd; |
330 | 330 | ||
331 | dprint(DBG_ATTR_MOD, "delete_attr: %s,%ld\n", | 331 | hfs_dbg(ATTR_MOD, "delete_attr: %s,%ld\n", |
332 | name ? name : NULL, inode->i_ino); | 332 | name ? name : NULL, inode->i_ino); |
333 | 333 | ||
334 | if (!HFSPLUS_SB(sb)->attr_tree) { | 334 | if (!HFSPLUS_SB(sb)->attr_tree) { |
335 | printk(KERN_ERR "hfs: attributes file doesn't exist\n"); | 335 | pr_err("attributes file doesn't exist\n"); |
336 | return -EINVAL; | 336 | return -EINVAL; |
337 | } | 337 | } |
338 | 338 | ||
@@ -346,7 +346,7 @@ int hfsplus_delete_attr(struct inode *inode, const char *name) | |||
346 | if (err) | 346 | if (err) |
347 | goto out; | 347 | goto out; |
348 | } else { | 348 | } else { |
349 | printk(KERN_ERR "hfs: invalid extended attribute name\n"); | 349 | pr_err("invalid extended attribute name\n"); |
350 | err = -EINVAL; | 350 | err = -EINVAL; |
351 | goto out; | 351 | goto out; |
352 | } | 352 | } |
@@ -369,10 +369,10 @@ int hfsplus_delete_all_attrs(struct inode *dir, u32 cnid) | |||
369 | int err = 0; | 369 | int err = 0; |
370 | struct hfs_find_data fd; | 370 | struct hfs_find_data fd; |
371 | 371 | ||
372 | dprint(DBG_ATTR_MOD, "delete_all_attrs: %d\n", cnid); | 372 | hfs_dbg(ATTR_MOD, "delete_all_attrs: %d\n", cnid); |
373 | 373 | ||
374 | if (!HFSPLUS_SB(dir->i_sb)->attr_tree) { | 374 | if (!HFSPLUS_SB(dir->i_sb)->attr_tree) { |
375 | printk(KERN_ERR "hfs: attributes file doesn't exist\n"); | 375 | pr_err("attributes file doesn't exist\n"); |
376 | return -EINVAL; | 376 | return -EINVAL; |
377 | } | 377 | } |
378 | 378 | ||
@@ -384,7 +384,7 @@ int hfsplus_delete_all_attrs(struct inode *dir, u32 cnid) | |||
384 | err = hfsplus_find_attr(dir->i_sb, cnid, NULL, &fd); | 384 | err = hfsplus_find_attr(dir->i_sb, cnid, NULL, &fd); |
385 | if (err) { | 385 | if (err) { |
386 | if (err != -ENOENT) | 386 | if (err != -ENOENT) |
387 | printk(KERN_ERR "hfs: xattr search failed.\n"); | 387 | pr_err("xattr search failed\n"); |
388 | goto end_delete_all; | 388 | goto end_delete_all; |
389 | } | 389 | } |
390 | 390 | ||
diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c index d73c98d1ee99..c1422d91cd36 100644 --- a/fs/hfsplus/bfind.c +++ b/fs/hfsplus/bfind.c | |||
@@ -22,7 +22,7 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd) | |||
22 | return -ENOMEM; | 22 | return -ENOMEM; |
23 | fd->search_key = ptr; | 23 | fd->search_key = ptr; |
24 | fd->key = ptr + tree->max_key_len + 2; | 24 | fd->key = ptr + tree->max_key_len + 2; |
25 | dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", | 25 | hfs_dbg(BNODE_REFS, "find_init: %d (%p)\n", |
26 | tree->cnid, __builtin_return_address(0)); | 26 | tree->cnid, __builtin_return_address(0)); |
27 | switch (tree->cnid) { | 27 | switch (tree->cnid) { |
28 | case HFSPLUS_CAT_CNID: | 28 | case HFSPLUS_CAT_CNID: |
@@ -44,7 +44,7 @@ void hfs_find_exit(struct hfs_find_data *fd) | |||
44 | { | 44 | { |
45 | hfs_bnode_put(fd->bnode); | 45 | hfs_bnode_put(fd->bnode); |
46 | kfree(fd->search_key); | 46 | kfree(fd->search_key); |
47 | dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", | 47 | hfs_dbg(BNODE_REFS, "find_exit: %d (%p)\n", |
48 | fd->tree->cnid, __builtin_return_address(0)); | 48 | fd->tree->cnid, __builtin_return_address(0)); |
49 | mutex_unlock(&fd->tree->tree_lock); | 49 | mutex_unlock(&fd->tree->tree_lock); |
50 | fd->tree = NULL; | 50 | fd->tree = NULL; |
@@ -56,7 +56,8 @@ int hfs_find_1st_rec_by_cnid(struct hfs_bnode *bnode, | |||
56 | int *end, | 56 | int *end, |
57 | int *cur_rec) | 57 | int *cur_rec) |
58 | { | 58 | { |
59 | __be32 cur_cnid, search_cnid; | 59 | __be32 cur_cnid; |
60 | __be32 search_cnid; | ||
60 | 61 | ||
61 | if (bnode->tree->cnid == HFSPLUS_EXT_CNID) { | 62 | if (bnode->tree->cnid == HFSPLUS_EXT_CNID) { |
62 | cur_cnid = fd->key->ext.cnid; | 63 | cur_cnid = fd->key->ext.cnid; |
@@ -67,8 +68,11 @@ int hfs_find_1st_rec_by_cnid(struct hfs_bnode *bnode, | |||
67 | } else if (bnode->tree->cnid == HFSPLUS_ATTR_CNID) { | 68 | } else if (bnode->tree->cnid == HFSPLUS_ATTR_CNID) { |
68 | cur_cnid = fd->key->attr.cnid; | 69 | cur_cnid = fd->key->attr.cnid; |
69 | search_cnid = fd->search_key->attr.cnid; | 70 | search_cnid = fd->search_key->attr.cnid; |
70 | } else | 71 | } else { |
72 | cur_cnid = 0; /* used-uninitialized warning */ | ||
73 | search_cnid = 0; | ||
71 | BUG(); | 74 | BUG(); |
75 | } | ||
72 | 76 | ||
73 | if (cur_cnid == search_cnid) { | 77 | if (cur_cnid == search_cnid) { |
74 | (*end) = (*cur_rec); | 78 | (*end) = (*cur_rec); |
@@ -204,7 +208,7 @@ int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare) | |||
204 | return res; | 208 | return res; |
205 | 209 | ||
206 | invalid: | 210 | invalid: |
207 | printk(KERN_ERR "hfs: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n", | 211 | pr_err("inconsistency in B*Tree (%d,%d,%d,%u,%u)\n", |
208 | height, bnode->height, bnode->type, nidx, parent); | 212 | height, bnode->height, bnode->type, nidx, parent); |
209 | res = -EIO; | 213 | res = -EIO; |
210 | release: | 214 | release: |
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index 6feefc0cb48a..d2954451519e 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c | |||
@@ -30,7 +30,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, | |||
30 | if (!len) | 30 | if (!len) |
31 | return size; | 31 | return size; |
32 | 32 | ||
33 | dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); | 33 | hfs_dbg(BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); |
34 | mutex_lock(&sbi->alloc_mutex); | 34 | mutex_lock(&sbi->alloc_mutex); |
35 | mapping = sbi->alloc_file->i_mapping; | 35 | mapping = sbi->alloc_file->i_mapping; |
36 | page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); | 36 | page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); |
@@ -89,14 +89,14 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, | |||
89 | else | 89 | else |
90 | end = pptr + ((size + 31) & (PAGE_CACHE_BITS - 1)) / 32; | 90 | end = pptr + ((size + 31) & (PAGE_CACHE_BITS - 1)) / 32; |
91 | } | 91 | } |
92 | dprint(DBG_BITMAP, "bitmap full\n"); | 92 | hfs_dbg(BITMAP, "bitmap full\n"); |
93 | start = size; | 93 | start = size; |
94 | goto out; | 94 | goto out; |
95 | 95 | ||
96 | found: | 96 | found: |
97 | start = offset + (curr - pptr) * 32 + i; | 97 | start = offset + (curr - pptr) * 32 + i; |
98 | if (start >= size) { | 98 | if (start >= size) { |
99 | dprint(DBG_BITMAP, "bitmap full\n"); | 99 | hfs_dbg(BITMAP, "bitmap full\n"); |
100 | goto out; | 100 | goto out; |
101 | } | 101 | } |
102 | /* do any partial u32 at the start */ | 102 | /* do any partial u32 at the start */ |
@@ -154,7 +154,7 @@ done: | |||
154 | *max = offset + (curr - pptr) * 32 + i - start; | 154 | *max = offset + (curr - pptr) * 32 + i - start; |
155 | sbi->free_blocks -= *max; | 155 | sbi->free_blocks -= *max; |
156 | hfsplus_mark_mdb_dirty(sb); | 156 | hfsplus_mark_mdb_dirty(sb); |
157 | dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); | 157 | hfs_dbg(BITMAP, "-> %u,%u\n", start, *max); |
158 | out: | 158 | out: |
159 | mutex_unlock(&sbi->alloc_mutex); | 159 | mutex_unlock(&sbi->alloc_mutex); |
160 | return start; | 160 | return start; |
@@ -173,7 +173,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) | |||
173 | if (!count) | 173 | if (!count) |
174 | return 0; | 174 | return 0; |
175 | 175 | ||
176 | dprint(DBG_BITMAP, "block_free: %u,%u\n", offset, count); | 176 | hfs_dbg(BITMAP, "block_free: %u,%u\n", offset, count); |
177 | /* are all of the bits in range? */ | 177 | /* are all of the bits in range? */ |
178 | if ((offset + count) > sbi->total_blocks) | 178 | if ((offset + count) > sbi->total_blocks) |
179 | return -ENOENT; | 179 | return -ENOENT; |
@@ -238,8 +238,7 @@ out: | |||
238 | return 0; | 238 | return 0; |
239 | 239 | ||
240 | kaboom: | 240 | kaboom: |
241 | printk(KERN_CRIT "hfsplus: unable to mark blocks free: error %ld\n", | 241 | pr_crit("unable to mark blocks free: error %ld\n", PTR_ERR(page)); |
242 | PTR_ERR(page)); | ||
243 | mutex_unlock(&sbi->alloc_mutex); | 242 | mutex_unlock(&sbi->alloc_mutex); |
244 | 243 | ||
245 | return -EIO; | 244 | return -EIO; |
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index f31ac6f404f1..11c860204520 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c | |||
@@ -130,7 +130,7 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, | |||
130 | struct page **src_page, **dst_page; | 130 | struct page **src_page, **dst_page; |
131 | int l; | 131 | int l; |
132 | 132 | ||
133 | dprint(DBG_BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); | 133 | hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); |
134 | if (!len) | 134 | if (!len) |
135 | return; | 135 | return; |
136 | tree = src_node->tree; | 136 | tree = src_node->tree; |
@@ -188,7 +188,7 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) | |||
188 | struct page **src_page, **dst_page; | 188 | struct page **src_page, **dst_page; |
189 | int l; | 189 | int l; |
190 | 190 | ||
191 | dprint(DBG_BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); | 191 | hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); |
192 | if (!len) | 192 | if (!len) |
193 | return; | 193 | return; |
194 | src += node->page_offset; | 194 | src += node->page_offset; |
@@ -302,16 +302,16 @@ void hfs_bnode_dump(struct hfs_bnode *node) | |||
302 | __be32 cnid; | 302 | __be32 cnid; |
303 | int i, off, key_off; | 303 | int i, off, key_off; |
304 | 304 | ||
305 | dprint(DBG_BNODE_MOD, "bnode: %d\n", node->this); | 305 | hfs_dbg(BNODE_MOD, "bnode: %d\n", node->this); |
306 | hfs_bnode_read(node, &desc, 0, sizeof(desc)); | 306 | hfs_bnode_read(node, &desc, 0, sizeof(desc)); |
307 | dprint(DBG_BNODE_MOD, "%d, %d, %d, %d, %d\n", | 307 | hfs_dbg(BNODE_MOD, "%d, %d, %d, %d, %d\n", |
308 | be32_to_cpu(desc.next), be32_to_cpu(desc.prev), | 308 | be32_to_cpu(desc.next), be32_to_cpu(desc.prev), |
309 | desc.type, desc.height, be16_to_cpu(desc.num_recs)); | 309 | desc.type, desc.height, be16_to_cpu(desc.num_recs)); |
310 | 310 | ||
311 | off = node->tree->node_size - 2; | 311 | off = node->tree->node_size - 2; |
312 | for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) { | 312 | for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) { |
313 | key_off = hfs_bnode_read_u16(node, off); | 313 | key_off = hfs_bnode_read_u16(node, off); |
314 | dprint(DBG_BNODE_MOD, " %d", key_off); | 314 | hfs_dbg(BNODE_MOD, " %d", key_off); |
315 | if (i && node->type == HFS_NODE_INDEX) { | 315 | if (i && node->type == HFS_NODE_INDEX) { |
316 | int tmp; | 316 | int tmp; |
317 | 317 | ||
@@ -320,17 +320,17 @@ void hfs_bnode_dump(struct hfs_bnode *node) | |||
320 | tmp = hfs_bnode_read_u16(node, key_off) + 2; | 320 | tmp = hfs_bnode_read_u16(node, key_off) + 2; |
321 | else | 321 | else |
322 | tmp = node->tree->max_key_len + 2; | 322 | tmp = node->tree->max_key_len + 2; |
323 | dprint(DBG_BNODE_MOD, " (%d", tmp); | 323 | hfs_dbg_cont(BNODE_MOD, " (%d", tmp); |
324 | hfs_bnode_read(node, &cnid, key_off + tmp, 4); | 324 | hfs_bnode_read(node, &cnid, key_off + tmp, 4); |
325 | dprint(DBG_BNODE_MOD, ",%d)", be32_to_cpu(cnid)); | 325 | hfs_dbg_cont(BNODE_MOD, ",%d)", be32_to_cpu(cnid)); |
326 | } else if (i && node->type == HFS_NODE_LEAF) { | 326 | } else if (i && node->type == HFS_NODE_LEAF) { |
327 | int tmp; | 327 | int tmp; |
328 | 328 | ||
329 | tmp = hfs_bnode_read_u16(node, key_off); | 329 | tmp = hfs_bnode_read_u16(node, key_off); |
330 | dprint(DBG_BNODE_MOD, " (%d)", tmp); | 330 | hfs_dbg_cont(BNODE_MOD, " (%d)", tmp); |
331 | } | 331 | } |
332 | } | 332 | } |
333 | dprint(DBG_BNODE_MOD, "\n"); | 333 | hfs_dbg_cont(BNODE_MOD, "\n"); |
334 | } | 334 | } |
335 | 335 | ||
336 | void hfs_bnode_unlink(struct hfs_bnode *node) | 336 | void hfs_bnode_unlink(struct hfs_bnode *node) |
@@ -366,7 +366,7 @@ void hfs_bnode_unlink(struct hfs_bnode *node) | |||
366 | 366 | ||
367 | /* move down? */ | 367 | /* move down? */ |
368 | if (!node->prev && !node->next) | 368 | if (!node->prev && !node->next) |
369 | dprint(DBG_BNODE_MOD, "hfs_btree_del_level\n"); | 369 | hfs_dbg(BNODE_MOD, "hfs_btree_del_level\n"); |
370 | if (!node->parent) { | 370 | if (!node->parent) { |
371 | tree->root = 0; | 371 | tree->root = 0; |
372 | tree->depth = 0; | 372 | tree->depth = 0; |
@@ -386,7 +386,7 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid) | |||
386 | struct hfs_bnode *node; | 386 | struct hfs_bnode *node; |
387 | 387 | ||
388 | if (cnid >= tree->node_count) { | 388 | if (cnid >= tree->node_count) { |
389 | printk(KERN_ERR "hfs: request for non-existent node " | 389 | pr_err("request for non-existent node " |
390 | "%d in B*Tree\n", | 390 | "%d in B*Tree\n", |
391 | cnid); | 391 | cnid); |
392 | return NULL; | 392 | return NULL; |
@@ -409,7 +409,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | |||
409 | loff_t off; | 409 | loff_t off; |
410 | 410 | ||
411 | if (cnid >= tree->node_count) { | 411 | if (cnid >= tree->node_count) { |
412 | printk(KERN_ERR "hfs: request for non-existent node " | 412 | pr_err("request for non-existent node " |
413 | "%d in B*Tree\n", | 413 | "%d in B*Tree\n", |
414 | cnid); | 414 | cnid); |
415 | return NULL; | 415 | return NULL; |
@@ -425,8 +425,8 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | |||
425 | node->this = cnid; | 425 | node->this = cnid; |
426 | set_bit(HFS_BNODE_NEW, &node->flags); | 426 | set_bit(HFS_BNODE_NEW, &node->flags); |
427 | atomic_set(&node->refcnt, 1); | 427 | atomic_set(&node->refcnt, 1); |
428 | dprint(DBG_BNODE_REFS, "new_node(%d:%d): 1\n", | 428 | hfs_dbg(BNODE_REFS, "new_node(%d:%d): 1\n", |
429 | node->tree->cnid, node->this); | 429 | node->tree->cnid, node->this); |
430 | init_waitqueue_head(&node->lock_wq); | 430 | init_waitqueue_head(&node->lock_wq); |
431 | spin_lock(&tree->hash_lock); | 431 | spin_lock(&tree->hash_lock); |
432 | node2 = hfs_bnode_findhash(tree, cnid); | 432 | node2 = hfs_bnode_findhash(tree, cnid); |
@@ -470,7 +470,7 @@ void hfs_bnode_unhash(struct hfs_bnode *node) | |||
470 | { | 470 | { |
471 | struct hfs_bnode **p; | 471 | struct hfs_bnode **p; |
472 | 472 | ||
473 | dprint(DBG_BNODE_REFS, "remove_node(%d:%d): %d\n", | 473 | hfs_dbg(BNODE_REFS, "remove_node(%d:%d): %d\n", |
474 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); | 474 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); |
475 | for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; | 475 | for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; |
476 | *p && *p != node; p = &(*p)->next_hash) | 476 | *p && *p != node; p = &(*p)->next_hash) |
@@ -588,7 +588,7 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) | |||
588 | node = hfs_bnode_findhash(tree, num); | 588 | node = hfs_bnode_findhash(tree, num); |
589 | spin_unlock(&tree->hash_lock); | 589 | spin_unlock(&tree->hash_lock); |
590 | if (node) { | 590 | if (node) { |
591 | printk(KERN_CRIT "new node %u already hashed?\n", num); | 591 | pr_crit("new node %u already hashed?\n", num); |
592 | WARN_ON(1); | 592 | WARN_ON(1); |
593 | return node; | 593 | return node; |
594 | } | 594 | } |
@@ -620,7 +620,7 @@ void hfs_bnode_get(struct hfs_bnode *node) | |||
620 | { | 620 | { |
621 | if (node) { | 621 | if (node) { |
622 | atomic_inc(&node->refcnt); | 622 | atomic_inc(&node->refcnt); |
623 | dprint(DBG_BNODE_REFS, "get_node(%d:%d): %d\n", | 623 | hfs_dbg(BNODE_REFS, "get_node(%d:%d): %d\n", |
624 | node->tree->cnid, node->this, | 624 | node->tree->cnid, node->this, |
625 | atomic_read(&node->refcnt)); | 625 | atomic_read(&node->refcnt)); |
626 | } | 626 | } |
@@ -633,7 +633,7 @@ void hfs_bnode_put(struct hfs_bnode *node) | |||
633 | struct hfs_btree *tree = node->tree; | 633 | struct hfs_btree *tree = node->tree; |
634 | int i; | 634 | int i; |
635 | 635 | ||
636 | dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n", | 636 | hfs_dbg(BNODE_REFS, "put_node(%d:%d): %d\n", |
637 | node->tree->cnid, node->this, | 637 | node->tree->cnid, node->this, |
638 | atomic_read(&node->refcnt)); | 638 | atomic_read(&node->refcnt)); |
639 | BUG_ON(!atomic_read(&node->refcnt)); | 639 | BUG_ON(!atomic_read(&node->refcnt)); |
diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c index 298d4e45604b..6e560d56094b 100644 --- a/fs/hfsplus/brec.c +++ b/fs/hfsplus/brec.c | |||
@@ -45,13 +45,13 @@ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec) | |||
45 | if (!recoff) | 45 | if (!recoff) |
46 | return 0; | 46 | return 0; |
47 | if (recoff > node->tree->node_size - 2) { | 47 | if (recoff > node->tree->node_size - 2) { |
48 | printk(KERN_ERR "hfs: recoff %d too large\n", recoff); | 48 | pr_err("recoff %d too large\n", recoff); |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
52 | retval = hfs_bnode_read_u16(node, recoff) + 2; | 52 | retval = hfs_bnode_read_u16(node, recoff) + 2; |
53 | if (retval > node->tree->max_key_len + 2) { | 53 | if (retval > node->tree->max_key_len + 2) { |
54 | printk(KERN_ERR "hfs: keylen %d too large\n", | 54 | pr_err("keylen %d too large\n", |
55 | retval); | 55 | retval); |
56 | retval = 0; | 56 | retval = 0; |
57 | } | 57 | } |
@@ -90,7 +90,7 @@ again: | |||
90 | end_rec_off = tree->node_size - (node->num_recs + 1) * 2; | 90 | end_rec_off = tree->node_size - (node->num_recs + 1) * 2; |
91 | end_off = hfs_bnode_read_u16(node, end_rec_off); | 91 | end_off = hfs_bnode_read_u16(node, end_rec_off); |
92 | end_rec_off -= 2; | 92 | end_rec_off -= 2; |
93 | dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", | 93 | hfs_dbg(BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", |
94 | rec, size, end_off, end_rec_off); | 94 | rec, size, end_off, end_rec_off); |
95 | if (size > end_rec_off - end_off) { | 95 | if (size > end_rec_off - end_off) { |
96 | if (new_node) | 96 | if (new_node) |
@@ -191,7 +191,7 @@ again: | |||
191 | mark_inode_dirty(tree->inode); | 191 | mark_inode_dirty(tree->inode); |
192 | } | 192 | } |
193 | hfs_bnode_dump(node); | 193 | hfs_bnode_dump(node); |
194 | dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n", | 194 | hfs_dbg(BNODE_MOD, "remove_rec: %d, %d\n", |
195 | fd->record, fd->keylength + fd->entrylength); | 195 | fd->record, fd->keylength + fd->entrylength); |
196 | if (!--node->num_recs) { | 196 | if (!--node->num_recs) { |
197 | hfs_bnode_unlink(node); | 197 | hfs_bnode_unlink(node); |
@@ -244,7 +244,7 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) | |||
244 | if (IS_ERR(new_node)) | 244 | if (IS_ERR(new_node)) |
245 | return new_node; | 245 | return new_node; |
246 | hfs_bnode_get(node); | 246 | hfs_bnode_get(node); |
247 | dprint(DBG_BNODE_MOD, "split_nodes: %d - %d - %d\n", | 247 | hfs_dbg(BNODE_MOD, "split_nodes: %d - %d - %d\n", |
248 | node->this, new_node->this, node->next); | 248 | node->this, new_node->this, node->next); |
249 | new_node->next = node->next; | 249 | new_node->next = node->next; |
250 | new_node->prev = node->this; | 250 | new_node->prev = node->this; |
@@ -379,7 +379,7 @@ again: | |||
379 | newkeylen = hfs_bnode_read_u16(node, 14) + 2; | 379 | newkeylen = hfs_bnode_read_u16(node, 14) + 2; |
380 | else | 380 | else |
381 | fd->keylength = newkeylen = tree->max_key_len + 2; | 381 | fd->keylength = newkeylen = tree->max_key_len + 2; |
382 | dprint(DBG_BNODE_MOD, "update_rec: %d, %d, %d\n", | 382 | hfs_dbg(BNODE_MOD, "update_rec: %d, %d, %d\n", |
383 | rec, fd->keylength, newkeylen); | 383 | rec, fd->keylength, newkeylen); |
384 | 384 | ||
385 | rec_off = tree->node_size - (rec + 2) * 2; | 385 | rec_off = tree->node_size - (rec + 2) * 2; |
@@ -391,7 +391,7 @@ again: | |||
391 | end_off = hfs_bnode_read_u16(parent, end_rec_off); | 391 | end_off = hfs_bnode_read_u16(parent, end_rec_off); |
392 | if (end_rec_off - end_off < diff) { | 392 | if (end_rec_off - end_off < diff) { |
393 | 393 | ||
394 | dprint(DBG_BNODE_MOD, "hfs: splitting index node.\n"); | 394 | hfs_dbg(BNODE_MOD, "splitting index node\n"); |
395 | fd->bnode = parent; | 395 | fd->bnode = parent; |
396 | new_node = hfs_bnode_split(fd); | 396 | new_node = hfs_bnode_split(fd); |
397 | if (IS_ERR(new_node)) | 397 | if (IS_ERR(new_node)) |
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index efb689c21a95..0c6540c91167 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c | |||
@@ -40,8 +40,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
40 | tree->inode = inode; | 40 | tree->inode = inode; |
41 | 41 | ||
42 | if (!HFSPLUS_I(tree->inode)->first_blocks) { | 42 | if (!HFSPLUS_I(tree->inode)->first_blocks) { |
43 | printk(KERN_ERR | 43 | pr_err("invalid btree extent records (0 size)\n"); |
44 | "hfs: invalid btree extent records (0 size).\n"); | ||
45 | goto free_inode; | 44 | goto free_inode; |
46 | } | 45 | } |
47 | 46 | ||
@@ -68,12 +67,12 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
68 | switch (id) { | 67 | switch (id) { |
69 | case HFSPLUS_EXT_CNID: | 68 | case HFSPLUS_EXT_CNID: |
70 | if (tree->max_key_len != HFSPLUS_EXT_KEYLEN - sizeof(u16)) { | 69 | if (tree->max_key_len != HFSPLUS_EXT_KEYLEN - sizeof(u16)) { |
71 | printk(KERN_ERR "hfs: invalid extent max_key_len %d\n", | 70 | pr_err("invalid extent max_key_len %d\n", |
72 | tree->max_key_len); | 71 | tree->max_key_len); |
73 | goto fail_page; | 72 | goto fail_page; |
74 | } | 73 | } |
75 | if (tree->attributes & HFS_TREE_VARIDXKEYS) { | 74 | if (tree->attributes & HFS_TREE_VARIDXKEYS) { |
76 | printk(KERN_ERR "hfs: invalid extent btree flag\n"); | 75 | pr_err("invalid extent btree flag\n"); |
77 | goto fail_page; | 76 | goto fail_page; |
78 | } | 77 | } |
79 | 78 | ||
@@ -81,12 +80,12 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
81 | break; | 80 | break; |
82 | case HFSPLUS_CAT_CNID: | 81 | case HFSPLUS_CAT_CNID: |
83 | if (tree->max_key_len != HFSPLUS_CAT_KEYLEN - sizeof(u16)) { | 82 | if (tree->max_key_len != HFSPLUS_CAT_KEYLEN - sizeof(u16)) { |
84 | printk(KERN_ERR "hfs: invalid catalog max_key_len %d\n", | 83 | pr_err("invalid catalog max_key_len %d\n", |
85 | tree->max_key_len); | 84 | tree->max_key_len); |
86 | goto fail_page; | 85 | goto fail_page; |
87 | } | 86 | } |
88 | if (!(tree->attributes & HFS_TREE_VARIDXKEYS)) { | 87 | if (!(tree->attributes & HFS_TREE_VARIDXKEYS)) { |
89 | printk(KERN_ERR "hfs: invalid catalog btree flag\n"); | 88 | pr_err("invalid catalog btree flag\n"); |
90 | goto fail_page; | 89 | goto fail_page; |
91 | } | 90 | } |
92 | 91 | ||
@@ -100,19 +99,19 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
100 | break; | 99 | break; |
101 | case HFSPLUS_ATTR_CNID: | 100 | case HFSPLUS_ATTR_CNID: |
102 | if (tree->max_key_len != HFSPLUS_ATTR_KEYLEN - sizeof(u16)) { | 101 | if (tree->max_key_len != HFSPLUS_ATTR_KEYLEN - sizeof(u16)) { |
103 | printk(KERN_ERR "hfs: invalid attributes max_key_len %d\n", | 102 | pr_err("invalid attributes max_key_len %d\n", |
104 | tree->max_key_len); | 103 | tree->max_key_len); |
105 | goto fail_page; | 104 | goto fail_page; |
106 | } | 105 | } |
107 | tree->keycmp = hfsplus_attr_bin_cmp_key; | 106 | tree->keycmp = hfsplus_attr_bin_cmp_key; |
108 | break; | 107 | break; |
109 | default: | 108 | default: |
110 | printk(KERN_ERR "hfs: unknown B*Tree requested\n"); | 109 | pr_err("unknown B*Tree requested\n"); |
111 | goto fail_page; | 110 | goto fail_page; |
112 | } | 111 | } |
113 | 112 | ||
114 | if (!(tree->attributes & HFS_TREE_BIGKEYS)) { | 113 | if (!(tree->attributes & HFS_TREE_BIGKEYS)) { |
115 | printk(KERN_ERR "hfs: invalid btree flag\n"); | 114 | pr_err("invalid btree flag\n"); |
116 | goto fail_page; | 115 | goto fail_page; |
117 | } | 116 | } |
118 | 117 | ||
@@ -155,7 +154,7 @@ void hfs_btree_close(struct hfs_btree *tree) | |||
155 | while ((node = tree->node_hash[i])) { | 154 | while ((node = tree->node_hash[i])) { |
156 | tree->node_hash[i] = node->next_hash; | 155 | tree->node_hash[i] = node->next_hash; |
157 | if (atomic_read(&node->refcnt)) | 156 | if (atomic_read(&node->refcnt)) |
158 | printk(KERN_CRIT "hfs: node %d:%d " | 157 | pr_crit("node %d:%d " |
159 | "still has %d user(s)!\n", | 158 | "still has %d user(s)!\n", |
160 | node->tree->cnid, node->this, | 159 | node->tree->cnid, node->this, |
161 | atomic_read(&node->refcnt)); | 160 | atomic_read(&node->refcnt)); |
@@ -303,7 +302,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) | |||
303 | kunmap(*pagep); | 302 | kunmap(*pagep); |
304 | nidx = node->next; | 303 | nidx = node->next; |
305 | if (!nidx) { | 304 | if (!nidx) { |
306 | dprint(DBG_BNODE_MOD, "hfs: create new bmap node.\n"); | 305 | hfs_dbg(BNODE_MOD, "create new bmap node\n"); |
307 | next_node = hfs_bmap_new_bmap(node, idx); | 306 | next_node = hfs_bmap_new_bmap(node, idx); |
308 | } else | 307 | } else |
309 | next_node = hfs_bnode_find(tree, nidx); | 308 | next_node = hfs_bnode_find(tree, nidx); |
@@ -329,7 +328,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
329 | u32 nidx; | 328 | u32 nidx; |
330 | u8 *data, byte, m; | 329 | u8 *data, byte, m; |
331 | 330 | ||
332 | dprint(DBG_BNODE_MOD, "btree_free_node: %u\n", node->this); | 331 | hfs_dbg(BNODE_MOD, "btree_free_node: %u\n", node->this); |
333 | BUG_ON(!node->this); | 332 | BUG_ON(!node->this); |
334 | tree = node->tree; | 333 | tree = node->tree; |
335 | nidx = node->this; | 334 | nidx = node->this; |
@@ -345,7 +344,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
345 | hfs_bnode_put(node); | 344 | hfs_bnode_put(node); |
346 | if (!i) { | 345 | if (!i) { |
347 | /* panic */; | 346 | /* panic */; |
348 | printk(KERN_CRIT "hfs: unable to free bnode %u. " | 347 | pr_crit("unable to free bnode %u. " |
349 | "bmap not found!\n", | 348 | "bmap not found!\n", |
350 | node->this); | 349 | node->this); |
351 | return; | 350 | return; |
@@ -355,7 +354,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
355 | return; | 354 | return; |
356 | if (node->type != HFS_NODE_MAP) { | 355 | if (node->type != HFS_NODE_MAP) { |
357 | /* panic */; | 356 | /* panic */; |
358 | printk(KERN_CRIT "hfs: invalid bmap found! " | 357 | pr_crit("invalid bmap found! " |
359 | "(%u,%d)\n", | 358 | "(%u,%d)\n", |
360 | node->this, node->type); | 359 | node->this, node->type); |
361 | hfs_bnode_put(node); | 360 | hfs_bnode_put(node); |
@@ -370,7 +369,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
370 | m = 1 << (~nidx & 7); | 369 | m = 1 << (~nidx & 7); |
371 | byte = data[off]; | 370 | byte = data[off]; |
372 | if (!(byte & m)) { | 371 | if (!(byte & m)) { |
373 | printk(KERN_CRIT "hfs: trying to free free bnode " | 372 | pr_crit("trying to free free bnode " |
374 | "%u(%d)\n", | 373 | "%u(%d)\n", |
375 | node->this, node->type); | 374 | node->this, node->type); |
376 | kunmap(page); | 375 | kunmap(page); |
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 840d71edd193..968ce411db53 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c | |||
@@ -188,12 +188,12 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid, | |||
188 | 188 | ||
189 | type = be16_to_cpu(tmp.type); | 189 | type = be16_to_cpu(tmp.type); |
190 | if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) { | 190 | if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) { |
191 | printk(KERN_ERR "hfs: found bad thread record in catalog\n"); | 191 | pr_err("found bad thread record in catalog\n"); |
192 | return -EIO; | 192 | return -EIO; |
193 | } | 193 | } |
194 | 194 | ||
195 | if (be16_to_cpu(tmp.thread.nodeName.length) > 255) { | 195 | if (be16_to_cpu(tmp.thread.nodeName.length) > 255) { |
196 | printk(KERN_ERR "hfs: catalog name length corrupted\n"); | 196 | pr_err("catalog name length corrupted\n"); |
197 | return -EIO; | 197 | return -EIO; |
198 | } | 198 | } |
199 | 199 | ||
@@ -212,7 +212,7 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, | |||
212 | int entry_size; | 212 | int entry_size; |
213 | int err; | 213 | int err; |
214 | 214 | ||
215 | dprint(DBG_CAT_MOD, "create_cat: %s,%u(%d)\n", | 215 | hfs_dbg(CAT_MOD, "create_cat: %s,%u(%d)\n", |
216 | str->name, cnid, inode->i_nlink); | 216 | str->name, cnid, inode->i_nlink); |
217 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); | 217 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); |
218 | if (err) | 218 | if (err) |
@@ -271,8 +271,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) | |||
271 | int err, off; | 271 | int err, off; |
272 | u16 type; | 272 | u16 type; |
273 | 273 | ||
274 | dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", | 274 | hfs_dbg(CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); |
275 | str ? str->name : NULL, cnid); | ||
276 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); | 275 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); |
277 | if (err) | 276 | if (err) |
278 | return err; | 277 | return err; |
@@ -361,7 +360,7 @@ int hfsplus_rename_cat(u32 cnid, | |||
361 | int entry_size, type; | 360 | int entry_size, type; |
362 | int err; | 361 | int err; |
363 | 362 | ||
364 | dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", | 363 | hfs_dbg(CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", |
365 | cnid, src_dir->i_ino, src_name->name, | 364 | cnid, src_dir->i_ino, src_name->name, |
366 | dst_dir->i_ino, dst_name->name); | 365 | dst_dir->i_ino, dst_name->name); |
367 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &src_fd); | 366 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &src_fd); |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 031c24e50521..a37ac934732f 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -103,7 +103,7 @@ again: | |||
103 | } else if (!dentry->d_fsdata) | 103 | } else if (!dentry->d_fsdata) |
104 | dentry->d_fsdata = (void *)(unsigned long)cnid; | 104 | dentry->d_fsdata = (void *)(unsigned long)cnid; |
105 | } else { | 105 | } else { |
106 | printk(KERN_ERR "hfs: invalid catalog entry type in lookup\n"); | 106 | pr_err("invalid catalog entry type in lookup\n"); |
107 | err = -EIO; | 107 | err = -EIO; |
108 | goto fail; | 108 | goto fail; |
109 | } | 109 | } |
@@ -159,12 +159,12 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
159 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, | 159 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
160 | fd.entrylength); | 160 | fd.entrylength); |
161 | if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { | 161 | if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { |
162 | printk(KERN_ERR "hfs: bad catalog folder thread\n"); | 162 | pr_err("bad catalog folder thread\n"); |
163 | err = -EIO; | 163 | err = -EIO; |
164 | goto out; | 164 | goto out; |
165 | } | 165 | } |
166 | if (fd.entrylength < HFSPLUS_MIN_THREAD_SZ) { | 166 | if (fd.entrylength < HFSPLUS_MIN_THREAD_SZ) { |
167 | printk(KERN_ERR "hfs: truncated catalog thread\n"); | 167 | pr_err("truncated catalog thread\n"); |
168 | err = -EIO; | 168 | err = -EIO; |
169 | goto out; | 169 | goto out; |
170 | } | 170 | } |
@@ -183,7 +183,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
183 | 183 | ||
184 | for (;;) { | 184 | for (;;) { |
185 | if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) { | 185 | if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) { |
186 | printk(KERN_ERR "hfs: walked past end of dir\n"); | 186 | pr_err("walked past end of dir\n"); |
187 | err = -EIO; | 187 | err = -EIO; |
188 | goto out; | 188 | goto out; |
189 | } | 189 | } |
@@ -203,7 +203,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
203 | if (type == HFSPLUS_FOLDER) { | 203 | if (type == HFSPLUS_FOLDER) { |
204 | if (fd.entrylength < | 204 | if (fd.entrylength < |
205 | sizeof(struct hfsplus_cat_folder)) { | 205 | sizeof(struct hfsplus_cat_folder)) { |
206 | printk(KERN_ERR "hfs: small dir entry\n"); | 206 | pr_err("small dir entry\n"); |
207 | err = -EIO; | 207 | err = -EIO; |
208 | goto out; | 208 | goto out; |
209 | } | 209 | } |
@@ -216,7 +216,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
216 | break; | 216 | break; |
217 | } else if (type == HFSPLUS_FILE) { | 217 | } else if (type == HFSPLUS_FILE) { |
218 | if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { | 218 | if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { |
219 | printk(KERN_ERR "hfs: small file entry\n"); | 219 | pr_err("small file entry\n"); |
220 | err = -EIO; | 220 | err = -EIO; |
221 | goto out; | 221 | goto out; |
222 | } | 222 | } |
@@ -224,7 +224,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
224 | be32_to_cpu(entry.file.id), DT_REG)) | 224 | be32_to_cpu(entry.file.id), DT_REG)) |
225 | break; | 225 | break; |
226 | } else { | 226 | } else { |
227 | printk(KERN_ERR "hfs: bad catalog entry type\n"); | 227 | pr_err("bad catalog entry type\n"); |
228 | err = -EIO; | 228 | err = -EIO; |
229 | goto out; | 229 | goto out; |
230 | } | 230 | } |
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index a94f0f779d5e..fbb212fbb1ef 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c | |||
@@ -83,7 +83,7 @@ static u32 hfsplus_ext_lastblock(struct hfsplus_extent *ext) | |||
83 | return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count); | 83 | return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void __hfsplus_ext_write_extent(struct inode *inode, | 86 | static int __hfsplus_ext_write_extent(struct inode *inode, |
87 | struct hfs_find_data *fd) | 87 | struct hfs_find_data *fd) |
88 | { | 88 | { |
89 | struct hfsplus_inode_info *hip = HFSPLUS_I(inode); | 89 | struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
@@ -98,13 +98,13 @@ static void __hfsplus_ext_write_extent(struct inode *inode, | |||
98 | res = hfs_brec_find(fd, hfs_find_rec_by_key); | 98 | res = hfs_brec_find(fd, hfs_find_rec_by_key); |
99 | if (hip->extent_state & HFSPLUS_EXT_NEW) { | 99 | if (hip->extent_state & HFSPLUS_EXT_NEW) { |
100 | if (res != -ENOENT) | 100 | if (res != -ENOENT) |
101 | return; | 101 | return res; |
102 | hfs_brec_insert(fd, hip->cached_extents, | 102 | hfs_brec_insert(fd, hip->cached_extents, |
103 | sizeof(hfsplus_extent_rec)); | 103 | sizeof(hfsplus_extent_rec)); |
104 | hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); | 104 | hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); |
105 | } else { | 105 | } else { |
106 | if (res) | 106 | if (res) |
107 | return; | 107 | return res; |
108 | hfs_bnode_write(fd->bnode, hip->cached_extents, | 108 | hfs_bnode_write(fd->bnode, hip->cached_extents, |
109 | fd->entryoffset, fd->entrylength); | 109 | fd->entryoffset, fd->entrylength); |
110 | hip->extent_state &= ~HFSPLUS_EXT_DIRTY; | 110 | hip->extent_state &= ~HFSPLUS_EXT_DIRTY; |
@@ -117,11 +117,13 @@ static void __hfsplus_ext_write_extent(struct inode *inode, | |||
117 | * to explicily mark the inode dirty, too. | 117 | * to explicily mark the inode dirty, too. |
118 | */ | 118 | */ |
119 | set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags); | 119 | set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags); |
120 | |||
121 | return 0; | ||
120 | } | 122 | } |
121 | 123 | ||
122 | static int hfsplus_ext_write_extent_locked(struct inode *inode) | 124 | static int hfsplus_ext_write_extent_locked(struct inode *inode) |
123 | { | 125 | { |
124 | int res; | 126 | int res = 0; |
125 | 127 | ||
126 | if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) { | 128 | if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) { |
127 | struct hfs_find_data fd; | 129 | struct hfs_find_data fd; |
@@ -129,10 +131,10 @@ static int hfsplus_ext_write_extent_locked(struct inode *inode) | |||
129 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd); | 131 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd); |
130 | if (res) | 132 | if (res) |
131 | return res; | 133 | return res; |
132 | __hfsplus_ext_write_extent(inode, &fd); | 134 | res = __hfsplus_ext_write_extent(inode, &fd); |
133 | hfs_find_exit(&fd); | 135 | hfs_find_exit(&fd); |
134 | } | 136 | } |
135 | return 0; | 137 | return res; |
136 | } | 138 | } |
137 | 139 | ||
138 | int hfsplus_ext_write_extent(struct inode *inode) | 140 | int hfsplus_ext_write_extent(struct inode *inode) |
@@ -175,8 +177,11 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, | |||
175 | 177 | ||
176 | WARN_ON(!mutex_is_locked(&hip->extents_lock)); | 178 | WARN_ON(!mutex_is_locked(&hip->extents_lock)); |
177 | 179 | ||
178 | if (hip->extent_state & HFSPLUS_EXT_DIRTY) | 180 | if (hip->extent_state & HFSPLUS_EXT_DIRTY) { |
179 | __hfsplus_ext_write_extent(inode, fd); | 181 | res = __hfsplus_ext_write_extent(inode, fd); |
182 | if (res) | ||
183 | return res; | ||
184 | } | ||
180 | 185 | ||
181 | res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino, | 186 | res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino, |
182 | block, HFSPLUS_IS_RSRC(inode) ? | 187 | block, HFSPLUS_IS_RSRC(inode) ? |
@@ -265,7 +270,7 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock, | |||
265 | mutex_unlock(&hip->extents_lock); | 270 | mutex_unlock(&hip->extents_lock); |
266 | 271 | ||
267 | done: | 272 | done: |
268 | dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n", | 273 | hfs_dbg(EXTENT, "get_block(%lu): %llu - %u\n", |
269 | inode->i_ino, (long long)iblock, dblock); | 274 | inode->i_ino, (long long)iblock, dblock); |
270 | 275 | ||
271 | mask = (1 << sbi->fs_shift) - 1; | 276 | mask = (1 << sbi->fs_shift) - 1; |
@@ -288,11 +293,12 @@ static void hfsplus_dump_extent(struct hfsplus_extent *extent) | |||
288 | { | 293 | { |
289 | int i; | 294 | int i; |
290 | 295 | ||
291 | dprint(DBG_EXTENT, " "); | 296 | hfs_dbg(EXTENT, " "); |
292 | for (i = 0; i < 8; i++) | 297 | for (i = 0; i < 8; i++) |
293 | dprint(DBG_EXTENT, " %u:%u", be32_to_cpu(extent[i].start_block), | 298 | hfs_dbg_cont(EXTENT, " %u:%u", |
294 | be32_to_cpu(extent[i].block_count)); | 299 | be32_to_cpu(extent[i].start_block), |
295 | dprint(DBG_EXTENT, "\n"); | 300 | be32_to_cpu(extent[i].block_count)); |
301 | hfs_dbg_cont(EXTENT, "\n"); | ||
296 | } | 302 | } |
297 | 303 | ||
298 | static int hfsplus_add_extent(struct hfsplus_extent *extent, u32 offset, | 304 | static int hfsplus_add_extent(struct hfsplus_extent *extent, u32 offset, |
@@ -348,8 +354,8 @@ found: | |||
348 | if (count <= block_nr) { | 354 | if (count <= block_nr) { |
349 | err = hfsplus_block_free(sb, start, count); | 355 | err = hfsplus_block_free(sb, start, count); |
350 | if (err) { | 356 | if (err) { |
351 | printk(KERN_ERR "hfs: can't free extent\n"); | 357 | pr_err("can't free extent\n"); |
352 | dprint(DBG_EXTENT, " start: %u count: %u\n", | 358 | hfs_dbg(EXTENT, " start: %u count: %u\n", |
353 | start, count); | 359 | start, count); |
354 | } | 360 | } |
355 | extent->block_count = 0; | 361 | extent->block_count = 0; |
@@ -359,8 +365,8 @@ found: | |||
359 | count -= block_nr; | 365 | count -= block_nr; |
360 | err = hfsplus_block_free(sb, start + count, block_nr); | 366 | err = hfsplus_block_free(sb, start + count, block_nr); |
361 | if (err) { | 367 | if (err) { |
362 | printk(KERN_ERR "hfs: can't free extent\n"); | 368 | pr_err("can't free extent\n"); |
363 | dprint(DBG_EXTENT, " start: %u count: %u\n", | 369 | hfs_dbg(EXTENT, " start: %u count: %u\n", |
364 | start, count); | 370 | start, count); |
365 | } | 371 | } |
366 | extent->block_count = cpu_to_be32(count); | 372 | extent->block_count = cpu_to_be32(count); |
@@ -432,7 +438,7 @@ int hfsplus_file_extend(struct inode *inode) | |||
432 | if (sbi->alloc_file->i_size * 8 < | 438 | if (sbi->alloc_file->i_size * 8 < |
433 | sbi->total_blocks - sbi->free_blocks + 8) { | 439 | sbi->total_blocks - sbi->free_blocks + 8) { |
434 | /* extend alloc file */ | 440 | /* extend alloc file */ |
435 | printk(KERN_ERR "hfs: extend alloc file! " | 441 | pr_err("extend alloc file! " |
436 | "(%llu,%u,%u)\n", | 442 | "(%llu,%u,%u)\n", |
437 | sbi->alloc_file->i_size * 8, | 443 | sbi->alloc_file->i_size * 8, |
438 | sbi->total_blocks, sbi->free_blocks); | 444 | sbi->total_blocks, sbi->free_blocks); |
@@ -459,11 +465,11 @@ int hfsplus_file_extend(struct inode *inode) | |||
459 | } | 465 | } |
460 | } | 466 | } |
461 | 467 | ||
462 | dprint(DBG_EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); | 468 | hfs_dbg(EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); |
463 | 469 | ||
464 | if (hip->alloc_blocks <= hip->first_blocks) { | 470 | if (hip->alloc_blocks <= hip->first_blocks) { |
465 | if (!hip->first_blocks) { | 471 | if (!hip->first_blocks) { |
466 | dprint(DBG_EXTENT, "first extents\n"); | 472 | hfs_dbg(EXTENT, "first extents\n"); |
467 | /* no extents yet */ | 473 | /* no extents yet */ |
468 | hip->first_extents[0].start_block = cpu_to_be32(start); | 474 | hip->first_extents[0].start_block = cpu_to_be32(start); |
469 | hip->first_extents[0].block_count = cpu_to_be32(len); | 475 | hip->first_extents[0].block_count = cpu_to_be32(len); |
@@ -500,7 +506,7 @@ out: | |||
500 | return res; | 506 | return res; |
501 | 507 | ||
502 | insert_extent: | 508 | insert_extent: |
503 | dprint(DBG_EXTENT, "insert new extent\n"); | 509 | hfs_dbg(EXTENT, "insert new extent\n"); |
504 | res = hfsplus_ext_write_extent_locked(inode); | 510 | res = hfsplus_ext_write_extent_locked(inode); |
505 | if (res) | 511 | if (res) |
506 | goto out; | 512 | goto out; |
@@ -525,15 +531,14 @@ void hfsplus_file_truncate(struct inode *inode) | |||
525 | u32 alloc_cnt, blk_cnt, start; | 531 | u32 alloc_cnt, blk_cnt, start; |
526 | int res; | 532 | int res; |
527 | 533 | ||
528 | dprint(DBG_INODE, "truncate: %lu, %llu -> %llu\n", | 534 | hfs_dbg(INODE, "truncate: %lu, %llu -> %llu\n", |
529 | inode->i_ino, (long long)hip->phys_size, | 535 | inode->i_ino, (long long)hip->phys_size, inode->i_size); |
530 | inode->i_size); | ||
531 | 536 | ||
532 | if (inode->i_size > hip->phys_size) { | 537 | if (inode->i_size > hip->phys_size) { |
533 | struct address_space *mapping = inode->i_mapping; | 538 | struct address_space *mapping = inode->i_mapping; |
534 | struct page *page; | 539 | struct page *page; |
535 | void *fsdata; | 540 | void *fsdata; |
536 | u32 size = inode->i_size; | 541 | loff_t size = inode->i_size; |
537 | 542 | ||
538 | res = pagecache_write_begin(NULL, mapping, size, 0, | 543 | res = pagecache_write_begin(NULL, mapping, size, 0, |
539 | AOP_FLAG_UNINTERRUPTIBLE, | 544 | AOP_FLAG_UNINTERRUPTIBLE, |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 05b11f36024c..60b0a3388b26 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -10,6 +10,12 @@ | |||
10 | #ifndef _LINUX_HFSPLUS_FS_H | 10 | #ifndef _LINUX_HFSPLUS_FS_H |
11 | #define _LINUX_HFSPLUS_FS_H | 11 | #define _LINUX_HFSPLUS_FS_H |
12 | 12 | ||
13 | #ifdef pr_fmt | ||
14 | #undef pr_fmt | ||
15 | #endif | ||
16 | |||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
13 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
14 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
15 | #include <linux/buffer_head.h> | 21 | #include <linux/buffer_head.h> |
@@ -32,9 +38,17 @@ | |||
32 | #endif | 38 | #endif |
33 | #define DBG_MASK (0) | 39 | #define DBG_MASK (0) |
34 | 40 | ||
35 | #define dprint(flg, fmt, args...) \ | 41 | #define hfs_dbg(flg, fmt, ...) \ |
36 | if (flg & DBG_MASK) \ | 42 | do { \ |
37 | printk(fmt , ## args) | 43 | if (DBG_##flg & DBG_MASK) \ |
44 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ | ||
45 | } while (0) | ||
46 | |||
47 | #define hfs_dbg_cont(flg, fmt, ...) \ | ||
48 | do { \ | ||
49 | if (DBG_##flg & DBG_MASK) \ | ||
50 | pr_cont(fmt, ##__VA_ARGS__); \ | ||
51 | } while (0) | ||
38 | 52 | ||
39 | /* Runtime config options */ | 53 | /* Runtime config options */ |
40 | #define HFSPLUS_DEF_CR_TYPE 0x3F3F3F3F /* '????' */ | 54 | #define HFSPLUS_DEF_CR_TYPE 0x3F3F3F3F /* '????' */ |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 160ccc9cdb4b..7faaa964968e 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -357,7 +357,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, | |||
357 | if (!error) | 357 | if (!error) |
358 | error = error2; | 358 | error = error2; |
359 | } else { | 359 | } else { |
360 | printk(KERN_ERR "hfs: sync non-existent attributes tree\n"); | 360 | pr_err("sync non-existent attributes tree\n"); |
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
@@ -573,7 +573,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
573 | inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); | 573 | inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); |
574 | HFSPLUS_I(inode)->create_date = file->create_date; | 574 | HFSPLUS_I(inode)->create_date = file->create_date; |
575 | } else { | 575 | } else { |
576 | printk(KERN_ERR "hfs: bad catalog entry used to create inode\n"); | 576 | pr_err("bad catalog entry used to create inode\n"); |
577 | res = -EIO; | 577 | res = -EIO; |
578 | } | 578 | } |
579 | return res; | 579 | return res; |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index ed257c671615..968eab5bc1f5 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
@@ -113,67 +113,67 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) | |||
113 | switch (token) { | 113 | switch (token) { |
114 | case opt_creator: | 114 | case opt_creator: |
115 | if (match_fourchar(&args[0], &sbi->creator)) { | 115 | if (match_fourchar(&args[0], &sbi->creator)) { |
116 | printk(KERN_ERR "hfs: creator requires a 4 character value\n"); | 116 | pr_err("creator requires a 4 character value\n"); |
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | break; | 119 | break; |
120 | case opt_type: | 120 | case opt_type: |
121 | if (match_fourchar(&args[0], &sbi->type)) { | 121 | if (match_fourchar(&args[0], &sbi->type)) { |
122 | printk(KERN_ERR "hfs: type requires a 4 character value\n"); | 122 | pr_err("type requires a 4 character value\n"); |
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
125 | break; | 125 | break; |
126 | case opt_umask: | 126 | case opt_umask: |
127 | if (match_octal(&args[0], &tmp)) { | 127 | if (match_octal(&args[0], &tmp)) { |
128 | printk(KERN_ERR "hfs: umask requires a value\n"); | 128 | pr_err("umask requires a value\n"); |
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | sbi->umask = (umode_t)tmp; | 131 | sbi->umask = (umode_t)tmp; |
132 | break; | 132 | break; |
133 | case opt_uid: | 133 | case opt_uid: |
134 | if (match_int(&args[0], &tmp)) { | 134 | if (match_int(&args[0], &tmp)) { |
135 | printk(KERN_ERR "hfs: uid requires an argument\n"); | 135 | pr_err("uid requires an argument\n"); |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | sbi->uid = make_kuid(current_user_ns(), (uid_t)tmp); | 138 | sbi->uid = make_kuid(current_user_ns(), (uid_t)tmp); |
139 | if (!uid_valid(sbi->uid)) { | 139 | if (!uid_valid(sbi->uid)) { |
140 | printk(KERN_ERR "hfs: invalid uid specified\n"); | 140 | pr_err("invalid uid specified\n"); |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | break; | 143 | break; |
144 | case opt_gid: | 144 | case opt_gid: |
145 | if (match_int(&args[0], &tmp)) { | 145 | if (match_int(&args[0], &tmp)) { |
146 | printk(KERN_ERR "hfs: gid requires an argument\n"); | 146 | pr_err("gid requires an argument\n"); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | sbi->gid = make_kgid(current_user_ns(), (gid_t)tmp); | 149 | sbi->gid = make_kgid(current_user_ns(), (gid_t)tmp); |
150 | if (!gid_valid(sbi->gid)) { | 150 | if (!gid_valid(sbi->gid)) { |
151 | printk(KERN_ERR "hfs: invalid gid specified\n"); | 151 | pr_err("invalid gid specified\n"); |
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | break; | 154 | break; |
155 | case opt_part: | 155 | case opt_part: |
156 | if (match_int(&args[0], &sbi->part)) { | 156 | if (match_int(&args[0], &sbi->part)) { |
157 | printk(KERN_ERR "hfs: part requires an argument\n"); | 157 | pr_err("part requires an argument\n"); |
158 | return 0; | 158 | return 0; |
159 | } | 159 | } |
160 | break; | 160 | break; |
161 | case opt_session: | 161 | case opt_session: |
162 | if (match_int(&args[0], &sbi->session)) { | 162 | if (match_int(&args[0], &sbi->session)) { |
163 | printk(KERN_ERR "hfs: session requires an argument\n"); | 163 | pr_err("session requires an argument\n"); |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | break; | 166 | break; |
167 | case opt_nls: | 167 | case opt_nls: |
168 | if (sbi->nls) { | 168 | if (sbi->nls) { |
169 | printk(KERN_ERR "hfs: unable to change nls mapping\n"); | 169 | pr_err("unable to change nls mapping\n"); |
170 | return 0; | 170 | return 0; |
171 | } | 171 | } |
172 | p = match_strdup(&args[0]); | 172 | p = match_strdup(&args[0]); |
173 | if (p) | 173 | if (p) |
174 | sbi->nls = load_nls(p); | 174 | sbi->nls = load_nls(p); |
175 | if (!sbi->nls) { | 175 | if (!sbi->nls) { |
176 | printk(KERN_ERR "hfs: unable to load " | 176 | pr_err("unable to load " |
177 | "nls mapping \"%s\"\n", | 177 | "nls mapping \"%s\"\n", |
178 | p); | 178 | p); |
179 | kfree(p); | 179 | kfree(p); |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 7b87284e46dc..4c4d142cf890 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -132,7 +132,7 @@ static int hfsplus_system_write_inode(struct inode *inode) | |||
132 | if (tree) { | 132 | if (tree) { |
133 | int err = hfs_btree_write(tree); | 133 | int err = hfs_btree_write(tree); |
134 | if (err) { | 134 | if (err) { |
135 | printk(KERN_ERR "hfs: b-tree write err: %d, ino %lu\n", | 135 | pr_err("b-tree write err: %d, ino %lu\n", |
136 | err, inode->i_ino); | 136 | err, inode->i_ino); |
137 | return err; | 137 | return err; |
138 | } | 138 | } |
@@ -145,7 +145,7 @@ static int hfsplus_write_inode(struct inode *inode, | |||
145 | { | 145 | { |
146 | int err; | 146 | int err; |
147 | 147 | ||
148 | dprint(DBG_INODE, "hfsplus_write_inode: %lu\n", inode->i_ino); | 148 | hfs_dbg(INODE, "hfsplus_write_inode: %lu\n", inode->i_ino); |
149 | 149 | ||
150 | err = hfsplus_ext_write_extent(inode); | 150 | err = hfsplus_ext_write_extent(inode); |
151 | if (err) | 151 | if (err) |
@@ -160,7 +160,7 @@ static int hfsplus_write_inode(struct inode *inode, | |||
160 | 160 | ||
161 | static void hfsplus_evict_inode(struct inode *inode) | 161 | static void hfsplus_evict_inode(struct inode *inode) |
162 | { | 162 | { |
163 | dprint(DBG_INODE, "hfsplus_evict_inode: %lu\n", inode->i_ino); | 163 | hfs_dbg(INODE, "hfsplus_evict_inode: %lu\n", inode->i_ino); |
164 | truncate_inode_pages(&inode->i_data, 0); | 164 | truncate_inode_pages(&inode->i_data, 0); |
165 | clear_inode(inode); | 165 | clear_inode(inode); |
166 | if (HFSPLUS_IS_RSRC(inode)) { | 166 | if (HFSPLUS_IS_RSRC(inode)) { |
@@ -179,7 +179,7 @@ static int hfsplus_sync_fs(struct super_block *sb, int wait) | |||
179 | if (!wait) | 179 | if (!wait) |
180 | return 0; | 180 | return 0; |
181 | 181 | ||
182 | dprint(DBG_SUPER, "hfsplus_sync_fs\n"); | 182 | hfs_dbg(SUPER, "hfsplus_sync_fs\n"); |
183 | 183 | ||
184 | /* | 184 | /* |
185 | * Explicitly write out the special metadata inodes. | 185 | * Explicitly write out the special metadata inodes. |
@@ -251,7 +251,7 @@ static void delayed_sync_fs(struct work_struct *work) | |||
251 | 251 | ||
252 | err = hfsplus_sync_fs(sbi->alloc_file->i_sb, 1); | 252 | err = hfsplus_sync_fs(sbi->alloc_file->i_sb, 1); |
253 | if (err) | 253 | if (err) |
254 | printk(KERN_ERR "hfs: delayed sync fs err %d\n", err); | 254 | pr_err("delayed sync fs err %d\n", err); |
255 | } | 255 | } |
256 | 256 | ||
257 | void hfsplus_mark_mdb_dirty(struct super_block *sb) | 257 | void hfsplus_mark_mdb_dirty(struct super_block *sb) |
@@ -275,7 +275,7 @@ static void hfsplus_put_super(struct super_block *sb) | |||
275 | { | 275 | { |
276 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | 276 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); |
277 | 277 | ||
278 | dprint(DBG_SUPER, "hfsplus_put_super\n"); | 278 | hfs_dbg(SUPER, "hfsplus_put_super\n"); |
279 | 279 | ||
280 | cancel_delayed_work_sync(&sbi->sync_work); | 280 | cancel_delayed_work_sync(&sbi->sync_work); |
281 | 281 | ||
@@ -333,25 +333,19 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) | |||
333 | return -EINVAL; | 333 | return -EINVAL; |
334 | 334 | ||
335 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { | 335 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { |
336 | printk(KERN_WARNING "hfs: filesystem was " | 336 | pr_warn("filesystem was not cleanly unmounted, running fsck.hfsplus is recommended. leaving read-only.\n"); |
337 | "not cleanly unmounted, " | ||
338 | "running fsck.hfsplus is recommended. " | ||
339 | "leaving read-only.\n"); | ||
340 | sb->s_flags |= MS_RDONLY; | 337 | sb->s_flags |= MS_RDONLY; |
341 | *flags |= MS_RDONLY; | 338 | *flags |= MS_RDONLY; |
342 | } else if (force) { | 339 | } else if (force) { |
343 | /* nothing */ | 340 | /* nothing */ |
344 | } else if (vhdr->attributes & | 341 | } else if (vhdr->attributes & |
345 | cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { | 342 | cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { |
346 | printk(KERN_WARNING "hfs: filesystem is marked locked, " | 343 | pr_warn("filesystem is marked locked, leaving read-only.\n"); |
347 | "leaving read-only.\n"); | ||
348 | sb->s_flags |= MS_RDONLY; | 344 | sb->s_flags |= MS_RDONLY; |
349 | *flags |= MS_RDONLY; | 345 | *flags |= MS_RDONLY; |
350 | } else if (vhdr->attributes & | 346 | } else if (vhdr->attributes & |
351 | cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { | 347 | cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { |
352 | printk(KERN_WARNING "hfs: filesystem is " | 348 | pr_warn("filesystem is marked journaled, leaving read-only.\n"); |
353 | "marked journaled, " | ||
354 | "leaving read-only.\n"); | ||
355 | sb->s_flags |= MS_RDONLY; | 349 | sb->s_flags |= MS_RDONLY; |
356 | *flags |= MS_RDONLY; | 350 | *flags |= MS_RDONLY; |
357 | } | 351 | } |
@@ -397,7 +391,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
397 | 391 | ||
398 | err = -EINVAL; | 392 | err = -EINVAL; |
399 | if (!hfsplus_parse_options(data, sbi)) { | 393 | if (!hfsplus_parse_options(data, sbi)) { |
400 | printk(KERN_ERR "hfs: unable to parse mount options\n"); | 394 | pr_err("unable to parse mount options\n"); |
401 | goto out_unload_nls; | 395 | goto out_unload_nls; |
402 | } | 396 | } |
403 | 397 | ||
@@ -405,14 +399,14 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
405 | nls = sbi->nls; | 399 | nls = sbi->nls; |
406 | sbi->nls = load_nls("utf8"); | 400 | sbi->nls = load_nls("utf8"); |
407 | if (!sbi->nls) { | 401 | if (!sbi->nls) { |
408 | printk(KERN_ERR "hfs: unable to load nls for utf8\n"); | 402 | pr_err("unable to load nls for utf8\n"); |
409 | goto out_unload_nls; | 403 | goto out_unload_nls; |
410 | } | 404 | } |
411 | 405 | ||
412 | /* Grab the volume header */ | 406 | /* Grab the volume header */ |
413 | if (hfsplus_read_wrapper(sb)) { | 407 | if (hfsplus_read_wrapper(sb)) { |
414 | if (!silent) | 408 | if (!silent) |
415 | printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n"); | 409 | pr_warn("unable to find HFS+ superblock\n"); |
416 | goto out_unload_nls; | 410 | goto out_unload_nls; |
417 | } | 411 | } |
418 | vhdr = sbi->s_vhdr; | 412 | vhdr = sbi->s_vhdr; |
@@ -421,7 +415,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
421 | sb->s_magic = HFSPLUS_VOLHEAD_SIG; | 415 | sb->s_magic = HFSPLUS_VOLHEAD_SIG; |
422 | if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || | 416 | if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || |
423 | be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { | 417 | be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { |
424 | printk(KERN_ERR "hfs: wrong filesystem version\n"); | 418 | pr_err("wrong filesystem version\n"); |
425 | goto out_free_vhdr; | 419 | goto out_free_vhdr; |
426 | } | 420 | } |
427 | sbi->total_blocks = be32_to_cpu(vhdr->total_blocks); | 421 | sbi->total_blocks = be32_to_cpu(vhdr->total_blocks); |
@@ -445,7 +439,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
445 | 439 | ||
446 | if ((last_fs_block > (sector_t)(~0ULL) >> (sbi->alloc_blksz_shift - 9)) || | 440 | if ((last_fs_block > (sector_t)(~0ULL) >> (sbi->alloc_blksz_shift - 9)) || |
447 | (last_fs_page > (pgoff_t)(~0ULL))) { | 441 | (last_fs_page > (pgoff_t)(~0ULL))) { |
448 | printk(KERN_ERR "hfs: filesystem size too large.\n"); | 442 | pr_err("filesystem size too large\n"); |
449 | goto out_free_vhdr; | 443 | goto out_free_vhdr; |
450 | } | 444 | } |
451 | 445 | ||
@@ -454,22 +448,16 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
454 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 448 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
455 | 449 | ||
456 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { | 450 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { |
457 | printk(KERN_WARNING "hfs: Filesystem was " | 451 | pr_warn("Filesystem was not cleanly unmounted, running fsck.hfsplus is recommended. mounting read-only.\n"); |
458 | "not cleanly unmounted, " | ||
459 | "running fsck.hfsplus is recommended. " | ||
460 | "mounting read-only.\n"); | ||
461 | sb->s_flags |= MS_RDONLY; | 452 | sb->s_flags |= MS_RDONLY; |
462 | } else if (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) { | 453 | } else if (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) { |
463 | /* nothing */ | 454 | /* nothing */ |
464 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { | 455 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { |
465 | printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n"); | 456 | pr_warn("Filesystem is marked locked, mounting read-only.\n"); |
466 | sb->s_flags |= MS_RDONLY; | 457 | sb->s_flags |= MS_RDONLY; |
467 | } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && | 458 | } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && |
468 | !(sb->s_flags & MS_RDONLY)) { | 459 | !(sb->s_flags & MS_RDONLY)) { |
469 | printk(KERN_WARNING "hfs: write access to " | 460 | pr_warn("write access to a journaled filesystem is not supported, use the force option at your own risk, mounting read-only.\n"); |
470 | "a journaled filesystem is not supported, " | ||
471 | "use the force option at your own risk, " | ||
472 | "mounting read-only.\n"); | ||
473 | sb->s_flags |= MS_RDONLY; | 461 | sb->s_flags |= MS_RDONLY; |
474 | } | 462 | } |
475 | 463 | ||
@@ -478,18 +466,18 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
478 | /* Load metadata objects (B*Trees) */ | 466 | /* Load metadata objects (B*Trees) */ |
479 | sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); | 467 | sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); |
480 | if (!sbi->ext_tree) { | 468 | if (!sbi->ext_tree) { |
481 | printk(KERN_ERR "hfs: failed to load extents file\n"); | 469 | pr_err("failed to load extents file\n"); |
482 | goto out_free_vhdr; | 470 | goto out_free_vhdr; |
483 | } | 471 | } |
484 | sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); | 472 | sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); |
485 | if (!sbi->cat_tree) { | 473 | if (!sbi->cat_tree) { |
486 | printk(KERN_ERR "hfs: failed to load catalog file\n"); | 474 | pr_err("failed to load catalog file\n"); |
487 | goto out_close_ext_tree; | 475 | goto out_close_ext_tree; |
488 | } | 476 | } |
489 | if (vhdr->attr_file.total_blocks != 0) { | 477 | if (vhdr->attr_file.total_blocks != 0) { |
490 | sbi->attr_tree = hfs_btree_open(sb, HFSPLUS_ATTR_CNID); | 478 | sbi->attr_tree = hfs_btree_open(sb, HFSPLUS_ATTR_CNID); |
491 | if (!sbi->attr_tree) { | 479 | if (!sbi->attr_tree) { |
492 | printk(KERN_ERR "hfs: failed to load attributes file\n"); | 480 | pr_err("failed to load attributes file\n"); |
493 | goto out_close_cat_tree; | 481 | goto out_close_cat_tree; |
494 | } | 482 | } |
495 | } | 483 | } |
@@ -497,7 +485,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
497 | 485 | ||
498 | inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); | 486 | inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); |
499 | if (IS_ERR(inode)) { | 487 | if (IS_ERR(inode)) { |
500 | printk(KERN_ERR "hfs: failed to load allocation file\n"); | 488 | pr_err("failed to load allocation file\n"); |
501 | err = PTR_ERR(inode); | 489 | err = PTR_ERR(inode); |
502 | goto out_close_attr_tree; | 490 | goto out_close_attr_tree; |
503 | } | 491 | } |
@@ -506,7 +494,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
506 | /* Load the root directory */ | 494 | /* Load the root directory */ |
507 | root = hfsplus_iget(sb, HFSPLUS_ROOT_CNID); | 495 | root = hfsplus_iget(sb, HFSPLUS_ROOT_CNID); |
508 | if (IS_ERR(root)) { | 496 | if (IS_ERR(root)) { |
509 | printk(KERN_ERR "hfs: failed to load root directory\n"); | 497 | pr_err("failed to load root directory\n"); |
510 | err = PTR_ERR(root); | 498 | err = PTR_ERR(root); |
511 | goto out_put_alloc_file; | 499 | goto out_put_alloc_file; |
512 | } | 500 | } |
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 90effcccca9a..b51a6079108d 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
@@ -156,7 +156,7 @@ static int hfsplus_get_last_session(struct super_block *sb, | |||
156 | *start = (sector_t)te.cdte_addr.lba << 2; | 156 | *start = (sector_t)te.cdte_addr.lba << 2; |
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
159 | printk(KERN_ERR "hfs: invalid session number or type of track\n"); | 159 | pr_err("invalid session number or type of track\n"); |
160 | return -EINVAL; | 160 | return -EINVAL; |
161 | } | 161 | } |
162 | ms_info.addr_format = CDROM_LBA; | 162 | ms_info.addr_format = CDROM_LBA; |
@@ -234,8 +234,7 @@ reread: | |||
234 | 234 | ||
235 | error = -EINVAL; | 235 | error = -EINVAL; |
236 | if (sbi->s_backup_vhdr->signature != sbi->s_vhdr->signature) { | 236 | if (sbi->s_backup_vhdr->signature != sbi->s_vhdr->signature) { |
237 | printk(KERN_WARNING | 237 | pr_warn("invalid secondary volume header\n"); |
238 | "hfs: invalid secondary volume header\n"); | ||
239 | goto out_free_backup_vhdr; | 238 | goto out_free_backup_vhdr; |
240 | } | 239 | } |
241 | 240 | ||
@@ -259,8 +258,7 @@ reread: | |||
259 | blocksize >>= 1; | 258 | blocksize >>= 1; |
260 | 259 | ||
261 | if (sb_set_blocksize(sb, blocksize) != blocksize) { | 260 | if (sb_set_blocksize(sb, blocksize) != blocksize) { |
262 | printk(KERN_ERR "hfs: unable to set blocksize to %u!\n", | 261 | pr_err("unable to set blocksize to %u!\n", blocksize); |
263 | blocksize); | ||
264 | goto out_free_backup_vhdr; | 262 | goto out_free_backup_vhdr; |
265 | } | 263 | } |
266 | 264 | ||
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index e8a4b0815c61..f66346155df5 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c | |||
@@ -107,19 +107,19 @@ int __hfsplus_setxattr(struct inode *inode, const char *name, | |||
107 | 107 | ||
108 | err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &cat_fd); | 108 | err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &cat_fd); |
109 | if (err) { | 109 | if (err) { |
110 | printk(KERN_ERR "hfs: can't init xattr find struct\n"); | 110 | pr_err("can't init xattr find struct\n"); |
111 | return err; | 111 | return err; |
112 | } | 112 | } |
113 | 113 | ||
114 | err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &cat_fd); | 114 | err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &cat_fd); |
115 | if (err) { | 115 | if (err) { |
116 | printk(KERN_ERR "hfs: catalog searching failed\n"); | 116 | pr_err("catalog searching failed\n"); |
117 | goto end_setxattr; | 117 | goto end_setxattr; |
118 | } | 118 | } |
119 | 119 | ||
120 | if (!strcmp_xattr_finder_info(name)) { | 120 | if (!strcmp_xattr_finder_info(name)) { |
121 | if (flags & XATTR_CREATE) { | 121 | if (flags & XATTR_CREATE) { |
122 | printk(KERN_ERR "hfs: xattr exists yet\n"); | 122 | pr_err("xattr exists yet\n"); |
123 | err = -EOPNOTSUPP; | 123 | err = -EOPNOTSUPP; |
124 | goto end_setxattr; | 124 | goto end_setxattr; |
125 | } | 125 | } |
@@ -165,7 +165,7 @@ int __hfsplus_setxattr(struct inode *inode, const char *name, | |||
165 | 165 | ||
166 | if (hfsplus_attr_exists(inode, name)) { | 166 | if (hfsplus_attr_exists(inode, name)) { |
167 | if (flags & XATTR_CREATE) { | 167 | if (flags & XATTR_CREATE) { |
168 | printk(KERN_ERR "hfs: xattr exists yet\n"); | 168 | pr_err("xattr exists yet\n"); |
169 | err = -EOPNOTSUPP; | 169 | err = -EOPNOTSUPP; |
170 | goto end_setxattr; | 170 | goto end_setxattr; |
171 | } | 171 | } |
@@ -177,7 +177,7 @@ int __hfsplus_setxattr(struct inode *inode, const char *name, | |||
177 | goto end_setxattr; | 177 | goto end_setxattr; |
178 | } else { | 178 | } else { |
179 | if (flags & XATTR_REPLACE) { | 179 | if (flags & XATTR_REPLACE) { |
180 | printk(KERN_ERR "hfs: cannot replace xattr\n"); | 180 | pr_err("cannot replace xattr\n"); |
181 | err = -EOPNOTSUPP; | 181 | err = -EOPNOTSUPP; |
182 | goto end_setxattr; | 182 | goto end_setxattr; |
183 | } | 183 | } |
@@ -210,7 +210,7 @@ int __hfsplus_setxattr(struct inode *inode, const char *name, | |||
210 | cat_entry_flags); | 210 | cat_entry_flags); |
211 | hfsplus_mark_inode_dirty(inode, HFSPLUS_I_CAT_DIRTY); | 211 | hfsplus_mark_inode_dirty(inode, HFSPLUS_I_CAT_DIRTY); |
212 | } else { | 212 | } else { |
213 | printk(KERN_ERR "hfs: invalid catalog entry type\n"); | 213 | pr_err("invalid catalog entry type\n"); |
214 | err = -EIO; | 214 | err = -EIO; |
215 | goto end_setxattr; | 215 | goto end_setxattr; |
216 | } | 216 | } |
@@ -269,7 +269,7 @@ static ssize_t hfsplus_getxattr_finder_info(struct dentry *dentry, | |||
269 | if (size >= record_len) { | 269 | if (size >= record_len) { |
270 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); | 270 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); |
271 | if (res) { | 271 | if (res) { |
272 | printk(KERN_ERR "hfs: can't init xattr find struct\n"); | 272 | pr_err("can't init xattr find struct\n"); |
273 | return res; | 273 | return res; |
274 | } | 274 | } |
275 | res = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd); | 275 | res = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd); |
@@ -340,13 +340,13 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | |||
340 | 340 | ||
341 | entry = hfsplus_alloc_attr_entry(); | 341 | entry = hfsplus_alloc_attr_entry(); |
342 | if (!entry) { | 342 | if (!entry) { |
343 | printk(KERN_ERR "hfs: can't allocate xattr entry\n"); | 343 | pr_err("can't allocate xattr entry\n"); |
344 | return -ENOMEM; | 344 | return -ENOMEM; |
345 | } | 345 | } |
346 | 346 | ||
347 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->attr_tree, &fd); | 347 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->attr_tree, &fd); |
348 | if (res) { | 348 | if (res) { |
349 | printk(KERN_ERR "hfs: can't init xattr find struct\n"); | 349 | pr_err("can't init xattr find struct\n"); |
350 | goto failed_getxattr_init; | 350 | goto failed_getxattr_init; |
351 | } | 351 | } |
352 | 352 | ||
@@ -355,7 +355,7 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | |||
355 | if (res == -ENOENT) | 355 | if (res == -ENOENT) |
356 | res = -ENODATA; | 356 | res = -ENODATA; |
357 | else | 357 | else |
358 | printk(KERN_ERR "hfs: xattr searching failed\n"); | 358 | pr_err("xattr searching failed\n"); |
359 | goto out; | 359 | goto out; |
360 | } | 360 | } |
361 | 361 | ||
@@ -368,17 +368,17 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | |||
368 | offsetof(struct hfsplus_attr_inline_data, | 368 | offsetof(struct hfsplus_attr_inline_data, |
369 | length)); | 369 | length)); |
370 | if (record_length > HFSPLUS_MAX_INLINE_DATA_SIZE) { | 370 | if (record_length > HFSPLUS_MAX_INLINE_DATA_SIZE) { |
371 | printk(KERN_ERR "hfs: invalid xattr record size\n"); | 371 | pr_err("invalid xattr record size\n"); |
372 | res = -EIO; | 372 | res = -EIO; |
373 | goto out; | 373 | goto out; |
374 | } | 374 | } |
375 | } else if (record_type == HFSPLUS_ATTR_FORK_DATA || | 375 | } else if (record_type == HFSPLUS_ATTR_FORK_DATA || |
376 | record_type == HFSPLUS_ATTR_EXTENTS) { | 376 | record_type == HFSPLUS_ATTR_EXTENTS) { |
377 | printk(KERN_ERR "hfs: only inline data xattr are supported\n"); | 377 | pr_err("only inline data xattr are supported\n"); |
378 | res = -EOPNOTSUPP; | 378 | res = -EOPNOTSUPP; |
379 | goto out; | 379 | goto out; |
380 | } else { | 380 | } else { |
381 | printk(KERN_ERR "hfs: invalid xattr record\n"); | 381 | pr_err("invalid xattr record\n"); |
382 | res = -EIO; | 382 | res = -EIO; |
383 | goto out; | 383 | goto out; |
384 | } | 384 | } |
@@ -427,7 +427,7 @@ static ssize_t hfsplus_listxattr_finder_info(struct dentry *dentry, | |||
427 | 427 | ||
428 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); | 428 | res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); |
429 | if (res) { | 429 | if (res) { |
430 | printk(KERN_ERR "hfs: can't init xattr find struct\n"); | 430 | pr_err("can't init xattr find struct\n"); |
431 | return res; | 431 | return res; |
432 | } | 432 | } |
433 | 433 | ||
@@ -506,7 +506,7 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
506 | 506 | ||
507 | err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->attr_tree, &fd); | 507 | err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->attr_tree, &fd); |
508 | if (err) { | 508 | if (err) { |
509 | printk(KERN_ERR "hfs: can't init xattr find struct\n"); | 509 | pr_err("can't init xattr find struct\n"); |
510 | return err; | 510 | return err; |
511 | } | 511 | } |
512 | 512 | ||
@@ -525,8 +525,7 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
525 | for (;;) { | 525 | for (;;) { |
526 | key_len = hfs_bnode_read_u16(fd.bnode, fd.keyoffset); | 526 | key_len = hfs_bnode_read_u16(fd.bnode, fd.keyoffset); |
527 | if (key_len == 0 || key_len > fd.tree->max_key_len) { | 527 | if (key_len == 0 || key_len > fd.tree->max_key_len) { |
528 | printk(KERN_ERR "hfs: invalid xattr key length: %d\n", | 528 | pr_err("invalid xattr key length: %d\n", key_len); |
529 | key_len); | ||
530 | res = -EIO; | 529 | res = -EIO; |
531 | goto end_listxattr; | 530 | goto end_listxattr; |
532 | } | 531 | } |
@@ -541,7 +540,7 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
541 | if (hfsplus_uni2asc(inode->i_sb, | 540 | if (hfsplus_uni2asc(inode->i_sb, |
542 | (const struct hfsplus_unistr *)&fd.key->attr.key_name, | 541 | (const struct hfsplus_unistr *)&fd.key->attr.key_name, |
543 | strbuf, &xattr_name_len)) { | 542 | strbuf, &xattr_name_len)) { |
544 | printk(KERN_ERR "hfs: unicode conversion failed\n"); | 543 | pr_err("unicode conversion failed\n"); |
545 | res = -EIO; | 544 | res = -EIO; |
546 | goto end_listxattr; | 545 | goto end_listxattr; |
547 | } | 546 | } |
@@ -598,13 +597,13 @@ int hfsplus_removexattr(struct dentry *dentry, const char *name) | |||
598 | 597 | ||
599 | err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &cat_fd); | 598 | err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &cat_fd); |
600 | if (err) { | 599 | if (err) { |
601 | printk(KERN_ERR "hfs: can't init xattr find struct\n"); | 600 | pr_err("can't init xattr find struct\n"); |
602 | return err; | 601 | return err; |
603 | } | 602 | } |
604 | 603 | ||
605 | err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &cat_fd); | 604 | err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &cat_fd); |
606 | if (err) { | 605 | if (err) { |
607 | printk(KERN_ERR "hfs: catalog searching failed\n"); | 606 | pr_err("catalog searching failed\n"); |
608 | goto end_removexattr; | 607 | goto end_removexattr; |
609 | } | 608 | } |
610 | 609 | ||
@@ -643,7 +642,7 @@ int hfsplus_removexattr(struct dentry *dentry, const char *name) | |||
643 | flags); | 642 | flags); |
644 | hfsplus_mark_inode_dirty(inode, HFSPLUS_I_CAT_DIRTY); | 643 | hfsplus_mark_inode_dirty(inode, HFSPLUS_I_CAT_DIRTY); |
645 | } else { | 644 | } else { |
646 | printk(KERN_ERR "hfs: invalid catalog entry type\n"); | 645 | pr_err("invalid catalog entry type\n"); |
647 | err = -EIO; | 646 | err = -EIO; |
648 | goto end_removexattr; | 647 | goto end_removexattr; |
649 | } | 648 | } |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 84e3d856e91d..523464e62849 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -110,7 +110,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
110 | * way when do_mmap_pgoff unwinds (may be important on powerpc | 110 | * way when do_mmap_pgoff unwinds (may be important on powerpc |
111 | * and ia64). | 111 | * and ia64). |
112 | */ | 112 | */ |
113 | vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND | VM_DONTDUMP; | 113 | vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; |
114 | vma->vm_ops = &hugetlb_vm_ops; | 114 | vma->vm_ops = &hugetlb_vm_ops; |
115 | 115 | ||
116 | if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) | 116 | if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) |
diff --git a/fs/inode.c b/fs/inode.c index f5f7c06c36fb..a898b3d43ccf 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -725,7 +725,7 @@ void prune_icache_sb(struct super_block *sb, int nr_to_scan) | |||
725 | * inode to the back of the list so we don't spin on it. | 725 | * inode to the back of the list so we don't spin on it. |
726 | */ | 726 | */ |
727 | if (!spin_trylock(&inode->i_lock)) { | 727 | if (!spin_trylock(&inode->i_lock)) { |
728 | list_move_tail(&inode->i_lru, &sb->s_inode_lru); | 728 | list_move(&inode->i_lru, &sb->s_inode_lru); |
729 | continue; | 729 | continue; |
730 | } | 730 | } |
731 | 731 | ||
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 86b39b167c23..11bb11f48b3a 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -162,8 +162,17 @@ static void journal_do_submit_data(struct buffer_head **wbuf, int bufs, | |||
162 | 162 | ||
163 | for (i = 0; i < bufs; i++) { | 163 | for (i = 0; i < bufs; i++) { |
164 | wbuf[i]->b_end_io = end_buffer_write_sync; | 164 | wbuf[i]->b_end_io = end_buffer_write_sync; |
165 | /* We use-up our safety reference in submit_bh() */ | 165 | /* |
166 | submit_bh(write_op, wbuf[i]); | 166 | * Here we write back pagecache data that may be mmaped. Since |
167 | * we cannot afford to clean the page and set PageWriteback | ||
168 | * here due to lock ordering (page lock ranks above transaction | ||
169 | * start), the data can change while IO is in flight. Tell the | ||
170 | * block layer it should bounce the bio pages if stable data | ||
171 | * during write is required. | ||
172 | * | ||
173 | * We use up our safety reference in submit_bh(). | ||
174 | */ | ||
175 | _submit_bh(write_op, wbuf[i], 1 << BIO_SNAP_STABLE); | ||
167 | } | 176 | } |
168 | } | 177 | } |
169 | 178 | ||
@@ -667,7 +676,17 @@ start_journal_io: | |||
667 | clear_buffer_dirty(bh); | 676 | clear_buffer_dirty(bh); |
668 | set_buffer_uptodate(bh); | 677 | set_buffer_uptodate(bh); |
669 | bh->b_end_io = journal_end_buffer_io_sync; | 678 | bh->b_end_io = journal_end_buffer_io_sync; |
670 | submit_bh(write_op, bh); | 679 | /* |
680 | * In data=journal mode, here we can end up | ||
681 | * writing pagecache data that might be | ||
682 | * mmapped. Since we can't afford to clean the | ||
683 | * page and set PageWriteback (see the comment | ||
684 | * near the other use of _submit_bh()), the | ||
685 | * data can change while the write is in | ||
686 | * flight. Tell the block layer to bounce the | ||
687 | * bio pages if stable pages are required. | ||
688 | */ | ||
689 | _submit_bh(write_op, bh, 1 << BIO_SNAP_STABLE); | ||
671 | } | 690 | } |
672 | cond_resched(); | 691 | cond_resched(); |
673 | 692 | ||
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 81cc7eaff863..865c4308acb6 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -310,8 +310,6 @@ int journal_write_metadata_buffer(transaction_t *transaction, | |||
310 | 310 | ||
311 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); | 311 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); |
312 | /* keep subsequent assertions sane */ | 312 | /* keep subsequent assertions sane */ |
313 | new_bh->b_state = 0; | ||
314 | init_buffer(new_bh, NULL, NULL); | ||
315 | atomic_set(&new_bh->b_count, 1); | 313 | atomic_set(&new_bh->b_count, 1); |
316 | new_jh = journal_add_journal_head(new_bh); /* This sleeps */ | 314 | new_jh = journal_add_journal_head(new_bh); /* This sleeps */ |
317 | 315 | ||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 886ec2faa9b4..f6c5ba027f4f 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -367,8 +367,6 @@ retry_alloc: | |||
367 | } | 367 | } |
368 | 368 | ||
369 | /* keep subsequent assertions sane */ | 369 | /* keep subsequent assertions sane */ |
370 | new_bh->b_state = 0; | ||
371 | init_buffer(new_bh, NULL, NULL); | ||
372 | atomic_set(&new_bh->b_count, 1); | 370 | atomic_set(&new_bh->b_count, 1); |
373 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ | 371 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ |
374 | 372 | ||
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 0796c45d0d4d..01bfe7662751 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -144,6 +144,9 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) | |||
144 | timeout); | 144 | timeout); |
145 | if (ret < 0) | 145 | if (ret < 0) |
146 | return -ERESTARTSYS; | 146 | return -ERESTARTSYS; |
147 | /* Reset the lock status after a server reboot so we resend */ | ||
148 | if (block->b_status == nlm_lck_denied_grace_period) | ||
149 | block->b_status = nlm_lck_blocked; | ||
147 | req->a_res.status = block->b_status; | 150 | req->a_res.status = block->b_status; |
148 | return 0; | 151 | return 0; |
149 | } | 152 | } |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 7e529c3c45c0..9760ecb9b60f 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -550,9 +550,6 @@ again: | |||
550 | status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); | 550 | status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); |
551 | if (status < 0) | 551 | if (status < 0) |
552 | break; | 552 | break; |
553 | /* Resend the blocking lock request after a server reboot */ | ||
554 | if (resp->status == nlm_lck_denied_grace_period) | ||
555 | continue; | ||
556 | if (resp->status != nlm_lck_blocked) | 553 | if (resp->status != nlm_lck_blocked) |
557 | break; | 554 | break; |
558 | } | 555 | } |
diff --git a/fs/namespace.c b/fs/namespace.c index d581e45c0a9f..341d3f564082 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1690,7 +1690,7 @@ static int do_loopback(struct path *path, const char *old_name, | |||
1690 | 1690 | ||
1691 | if (IS_ERR(mnt)) { | 1691 | if (IS_ERR(mnt)) { |
1692 | err = PTR_ERR(mnt); | 1692 | err = PTR_ERR(mnt); |
1693 | goto out; | 1693 | goto out2; |
1694 | } | 1694 | } |
1695 | 1695 | ||
1696 | err = graft_tree(mnt, path); | 1696 | err = graft_tree(mnt, path); |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 5088b57b078a..cff089a412c7 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -125,6 +125,9 @@ nfs41_callback_svc(void *vrqstp) | |||
125 | set_freezable(); | 125 | set_freezable(); |
126 | 126 | ||
127 | while (!kthread_should_stop()) { | 127 | while (!kthread_should_stop()) { |
128 | if (try_to_freeze()) | ||
129 | continue; | ||
130 | |||
128 | prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE); | 131 | prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE); |
129 | spin_lock_bh(&serv->sv_cb_lock); | 132 | spin_lock_bh(&serv->sv_cb_lock); |
130 | if (!list_empty(&serv->sv_cb_list)) { | 133 | if (!list_empty(&serv->sv_cb_list)) { |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 2960512792c2..a13d26ede254 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -500,7 +500,7 @@ __be32 nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy, | |||
500 | &args->craa_type_mask)) | 500 | &args->craa_type_mask)) |
501 | pnfs_recall_all_layouts(cps->clp); | 501 | pnfs_recall_all_layouts(cps->clp); |
502 | if (flags) | 502 | if (flags) |
503 | nfs_expire_all_delegation_types(cps->clp, flags); | 503 | nfs_expire_unused_delegation_types(cps->clp, flags); |
504 | out: | 504 | out: |
505 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); | 505 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); |
506 | return status; | 506 | return status; |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 84d8eae203a7..c513b0cc835f 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -593,6 +593,8 @@ int nfs_create_rpc_client(struct nfs_client *clp, | |||
593 | args.flags |= RPC_CLNT_CREATE_DISCRTRY; | 593 | args.flags |= RPC_CLNT_CREATE_DISCRTRY; |
594 | if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags)) | 594 | if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags)) |
595 | args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; | 595 | args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; |
596 | if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags)) | ||
597 | args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS; | ||
596 | 598 | ||
597 | if (!IS_ERR(clp->cl_rpcclient)) | 599 | if (!IS_ERR(clp->cl_rpcclient)) |
598 | return 0; | 600 | return 0; |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 6390a4b5fee7..57db3244f4d9 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -64,17 +64,15 @@ int nfs4_have_delegation(struct inode *inode, fmode_t flags) | |||
64 | return ret; | 64 | return ret; |
65 | } | 65 | } |
66 | 66 | ||
67 | static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) | 67 | static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) |
68 | { | 68 | { |
69 | struct inode *inode = state->inode; | 69 | struct inode *inode = state->inode; |
70 | struct file_lock *fl; | 70 | struct file_lock *fl; |
71 | int status = 0; | 71 | int status = 0; |
72 | 72 | ||
73 | if (inode->i_flock == NULL) | 73 | if (inode->i_flock == NULL) |
74 | return 0; | ||
75 | |||
76 | if (inode->i_flock == NULL) | ||
77 | goto out; | 74 | goto out; |
75 | |||
78 | /* Protect inode->i_flock using the file locks lock */ | 76 | /* Protect inode->i_flock using the file locks lock */ |
79 | lock_flocks(); | 77 | lock_flocks(); |
80 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 78 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
@@ -83,7 +81,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ | |||
83 | if (nfs_file_open_context(fl->fl_file) != ctx) | 81 | if (nfs_file_open_context(fl->fl_file) != ctx) |
84 | continue; | 82 | continue; |
85 | unlock_flocks(); | 83 | unlock_flocks(); |
86 | status = nfs4_lock_delegation_recall(state, fl); | 84 | status = nfs4_lock_delegation_recall(fl, state, stateid); |
87 | if (status < 0) | 85 | if (status < 0) |
88 | goto out; | 86 | goto out; |
89 | lock_flocks(); | 87 | lock_flocks(); |
@@ -120,7 +118,7 @@ again: | |||
120 | seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); | 118 | seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); |
121 | err = nfs4_open_delegation_recall(ctx, state, stateid); | 119 | err = nfs4_open_delegation_recall(ctx, state, stateid); |
122 | if (!err) | 120 | if (!err) |
123 | err = nfs_delegation_claim_locks(ctx, state); | 121 | err = nfs_delegation_claim_locks(ctx, state, stateid); |
124 | if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) | 122 | if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) |
125 | err = -EAGAIN; | 123 | err = -EAGAIN; |
126 | mutex_unlock(&sp->so_delegreturn_mutex); | 124 | mutex_unlock(&sp->so_delegreturn_mutex); |
@@ -389,6 +387,24 @@ out: | |||
389 | return err; | 387 | return err; |
390 | } | 388 | } |
391 | 389 | ||
390 | static bool nfs_delegation_need_return(struct nfs_delegation *delegation) | ||
391 | { | ||
392 | bool ret = false; | ||
393 | |||
394 | if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags)) | ||
395 | ret = true; | ||
396 | if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) { | ||
397 | struct inode *inode; | ||
398 | |||
399 | spin_lock(&delegation->lock); | ||
400 | inode = delegation->inode; | ||
401 | if (inode && list_empty(&NFS_I(inode)->open_files)) | ||
402 | ret = true; | ||
403 | spin_unlock(&delegation->lock); | ||
404 | } | ||
405 | return ret; | ||
406 | } | ||
407 | |||
392 | /** | 408 | /** |
393 | * nfs_client_return_marked_delegations - return previously marked delegations | 409 | * nfs_client_return_marked_delegations - return previously marked delegations |
394 | * @clp: nfs_client to process | 410 | * @clp: nfs_client to process |
@@ -411,8 +427,7 @@ restart: | |||
411 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { | 427 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { |
412 | list_for_each_entry_rcu(delegation, &server->delegations, | 428 | list_for_each_entry_rcu(delegation, &server->delegations, |
413 | super_list) { | 429 | super_list) { |
414 | if (!test_and_clear_bit(NFS_DELEGATION_RETURN, | 430 | if (!nfs_delegation_need_return(delegation)) |
415 | &delegation->flags)) | ||
416 | continue; | 431 | continue; |
417 | inode = nfs_delegation_grab_inode(delegation); | 432 | inode = nfs_delegation_grab_inode(delegation); |
418 | if (inode == NULL) | 433 | if (inode == NULL) |
@@ -471,6 +486,13 @@ int nfs4_inode_return_delegation(struct inode *inode) | |||
471 | return err; | 486 | return err; |
472 | } | 487 | } |
473 | 488 | ||
489 | static void nfs_mark_return_if_closed_delegation(struct nfs_server *server, | ||
490 | struct nfs_delegation *delegation) | ||
491 | { | ||
492 | set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags); | ||
493 | set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state); | ||
494 | } | ||
495 | |||
474 | static void nfs_mark_return_delegation(struct nfs_server *server, | 496 | static void nfs_mark_return_delegation(struct nfs_server *server, |
475 | struct nfs_delegation *delegation) | 497 | struct nfs_delegation *delegation) |
476 | { | 498 | { |
@@ -478,6 +500,45 @@ static void nfs_mark_return_delegation(struct nfs_server *server, | |||
478 | set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state); | 500 | set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state); |
479 | } | 501 | } |
480 | 502 | ||
503 | static bool nfs_server_mark_return_all_delegations(struct nfs_server *server) | ||
504 | { | ||
505 | struct nfs_delegation *delegation; | ||
506 | bool ret = false; | ||
507 | |||
508 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { | ||
509 | nfs_mark_return_delegation(server, delegation); | ||
510 | ret = true; | ||
511 | } | ||
512 | return ret; | ||
513 | } | ||
514 | |||
515 | static void nfs_client_mark_return_all_delegations(struct nfs_client *clp) | ||
516 | { | ||
517 | struct nfs_server *server; | ||
518 | |||
519 | rcu_read_lock(); | ||
520 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) | ||
521 | nfs_server_mark_return_all_delegations(server); | ||
522 | rcu_read_unlock(); | ||
523 | } | ||
524 | |||
525 | static void nfs_delegation_run_state_manager(struct nfs_client *clp) | ||
526 | { | ||
527 | if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) | ||
528 | nfs4_schedule_state_manager(clp); | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * nfs_expire_all_delegations | ||
533 | * @clp: client to process | ||
534 | * | ||
535 | */ | ||
536 | void nfs_expire_all_delegations(struct nfs_client *clp) | ||
537 | { | ||
538 | nfs_client_mark_return_all_delegations(clp); | ||
539 | nfs_delegation_run_state_manager(clp); | ||
540 | } | ||
541 | |||
481 | /** | 542 | /** |
482 | * nfs_super_return_all_delegations - return delegations for one superblock | 543 | * nfs_super_return_all_delegations - return delegations for one superblock |
483 | * @sb: sb to process | 544 | * @sb: sb to process |
@@ -486,24 +547,22 @@ static void nfs_mark_return_delegation(struct nfs_server *server, | |||
486 | void nfs_server_return_all_delegations(struct nfs_server *server) | 547 | void nfs_server_return_all_delegations(struct nfs_server *server) |
487 | { | 548 | { |
488 | struct nfs_client *clp = server->nfs_client; | 549 | struct nfs_client *clp = server->nfs_client; |
489 | struct nfs_delegation *delegation; | 550 | bool need_wait; |
490 | 551 | ||
491 | if (clp == NULL) | 552 | if (clp == NULL) |
492 | return; | 553 | return; |
493 | 554 | ||
494 | rcu_read_lock(); | 555 | rcu_read_lock(); |
495 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { | 556 | need_wait = nfs_server_mark_return_all_delegations(server); |
496 | spin_lock(&delegation->lock); | ||
497 | set_bit(NFS_DELEGATION_RETURN, &delegation->flags); | ||
498 | spin_unlock(&delegation->lock); | ||
499 | } | ||
500 | rcu_read_unlock(); | 557 | rcu_read_unlock(); |
501 | 558 | ||
502 | if (nfs_client_return_marked_delegations(clp) != 0) | 559 | if (need_wait) { |
503 | nfs4_schedule_state_manager(clp); | 560 | nfs4_schedule_state_manager(clp); |
561 | nfs4_wait_clnt_recover(clp); | ||
562 | } | ||
504 | } | 563 | } |
505 | 564 | ||
506 | static void nfs_mark_return_all_delegation_types(struct nfs_server *server, | 565 | static void nfs_mark_return_unused_delegation_types(struct nfs_server *server, |
507 | fmode_t flags) | 566 | fmode_t flags) |
508 | { | 567 | { |
509 | struct nfs_delegation *delegation; | 568 | struct nfs_delegation *delegation; |
@@ -512,27 +571,21 @@ static void nfs_mark_return_all_delegation_types(struct nfs_server *server, | |||
512 | if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE)) | 571 | if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE)) |
513 | continue; | 572 | continue; |
514 | if (delegation->type & flags) | 573 | if (delegation->type & flags) |
515 | nfs_mark_return_delegation(server, delegation); | 574 | nfs_mark_return_if_closed_delegation(server, delegation); |
516 | } | 575 | } |
517 | } | 576 | } |
518 | 577 | ||
519 | static void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, | 578 | static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *clp, |
520 | fmode_t flags) | 579 | fmode_t flags) |
521 | { | 580 | { |
522 | struct nfs_server *server; | 581 | struct nfs_server *server; |
523 | 582 | ||
524 | rcu_read_lock(); | 583 | rcu_read_lock(); |
525 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) | 584 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) |
526 | nfs_mark_return_all_delegation_types(server, flags); | 585 | nfs_mark_return_unused_delegation_types(server, flags); |
527 | rcu_read_unlock(); | 586 | rcu_read_unlock(); |
528 | } | 587 | } |
529 | 588 | ||
530 | static void nfs_delegation_run_state_manager(struct nfs_client *clp) | ||
531 | { | ||
532 | if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) | ||
533 | nfs4_schedule_state_manager(clp); | ||
534 | } | ||
535 | |||
536 | void nfs_remove_bad_delegation(struct inode *inode) | 589 | void nfs_remove_bad_delegation(struct inode *inode) |
537 | { | 590 | { |
538 | struct nfs_delegation *delegation; | 591 | struct nfs_delegation *delegation; |
@@ -546,27 +599,17 @@ void nfs_remove_bad_delegation(struct inode *inode) | |||
546 | EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation); | 599 | EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation); |
547 | 600 | ||
548 | /** | 601 | /** |
549 | * nfs_expire_all_delegation_types | 602 | * nfs_expire_unused_delegation_types |
550 | * @clp: client to process | 603 | * @clp: client to process |
551 | * @flags: delegation types to expire | 604 | * @flags: delegation types to expire |
552 | * | 605 | * |
553 | */ | 606 | */ |
554 | void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags) | 607 | void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags) |
555 | { | 608 | { |
556 | nfs_client_mark_return_all_delegation_types(clp, flags); | 609 | nfs_client_mark_return_unused_delegation_types(clp, flags); |
557 | nfs_delegation_run_state_manager(clp); | 610 | nfs_delegation_run_state_manager(clp); |
558 | } | 611 | } |
559 | 612 | ||
560 | /** | ||
561 | * nfs_expire_all_delegations | ||
562 | * @clp: client to process | ||
563 | * | ||
564 | */ | ||
565 | void nfs_expire_all_delegations(struct nfs_client *clp) | ||
566 | { | ||
567 | nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE); | ||
568 | } | ||
569 | |||
570 | static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server) | 613 | static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server) |
571 | { | 614 | { |
572 | struct nfs_delegation *delegation; | 615 | struct nfs_delegation *delegation; |
@@ -574,7 +617,7 @@ static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server) | |||
574 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { | 617 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { |
575 | if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) | 618 | if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) |
576 | continue; | 619 | continue; |
577 | nfs_mark_return_delegation(server, delegation); | 620 | nfs_mark_return_if_closed_delegation(server, delegation); |
578 | } | 621 | } |
579 | } | 622 | } |
580 | 623 | ||
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index d54d4fca6793..9a79c7a99d6d 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h | |||
@@ -28,6 +28,7 @@ struct nfs_delegation { | |||
28 | enum { | 28 | enum { |
29 | NFS_DELEGATION_NEED_RECLAIM = 0, | 29 | NFS_DELEGATION_NEED_RECLAIM = 0, |
30 | NFS_DELEGATION_RETURN, | 30 | NFS_DELEGATION_RETURN, |
31 | NFS_DELEGATION_RETURN_IF_CLOSED, | ||
31 | NFS_DELEGATION_REFERENCED, | 32 | NFS_DELEGATION_REFERENCED, |
32 | NFS_DELEGATION_RETURNING, | 33 | NFS_DELEGATION_RETURNING, |
33 | }; | 34 | }; |
@@ -41,7 +42,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode); | |||
41 | struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); | 42 | struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); |
42 | void nfs_server_return_all_delegations(struct nfs_server *); | 43 | void nfs_server_return_all_delegations(struct nfs_server *); |
43 | void nfs_expire_all_delegations(struct nfs_client *clp); | 44 | void nfs_expire_all_delegations(struct nfs_client *clp); |
44 | void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags); | 45 | void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags); |
45 | void nfs_expire_unreferenced_delegations(struct nfs_client *clp); | 46 | void nfs_expire_unreferenced_delegations(struct nfs_client *clp); |
46 | int nfs_client_return_marked_delegations(struct nfs_client *clp); | 47 | int nfs_client_return_marked_delegations(struct nfs_client *clp); |
47 | int nfs_delegations_present(struct nfs_client *clp); | 48 | int nfs_delegations_present(struct nfs_client *clp); |
@@ -53,7 +54,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp); | |||
53 | /* NFSv4 delegation-related procedures */ | 54 | /* NFSv4 delegation-related procedures */ |
54 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync); | 55 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync); |
55 | int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid); | 56 | int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid); |
56 | int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); | 57 | int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid); |
57 | bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_t flags); | 58 | bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_t flags); |
58 | 59 | ||
59 | void nfs_mark_delegation_referenced(struct nfs_delegation *delegation); | 60 | void nfs_mark_delegation_referenced(struct nfs_delegation *delegation); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f23f455be42b..e093e73178b7 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1486,6 +1486,8 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) | |||
1486 | goto no_open; | 1486 | goto no_open; |
1487 | if (d_mountpoint(dentry)) | 1487 | if (d_mountpoint(dentry)) |
1488 | goto no_open; | 1488 | goto no_open; |
1489 | if (NFS_SB(dentry->d_sb)->caps & NFS_CAP_ATOMIC_OPEN_V1) | ||
1490 | goto no_open; | ||
1489 | 1491 | ||
1490 | inode = dentry->d_inode; | 1492 | inode = dentry->d_inode; |
1491 | parent = dget_parent(dentry); | 1493 | parent = dget_parent(dentry); |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 29f4a48a0ee6..a87a44f84113 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -744,6 +744,7 @@ static int | |||
744 | do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | 744 | do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) |
745 | { | 745 | { |
746 | struct inode *inode = filp->f_mapping->host; | 746 | struct inode *inode = filp->f_mapping->host; |
747 | struct nfs_lock_context *l_ctx; | ||
747 | int status; | 748 | int status; |
748 | 749 | ||
749 | /* | 750 | /* |
@@ -752,6 +753,14 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | |||
752 | */ | 753 | */ |
753 | nfs_sync_mapping(filp->f_mapping); | 754 | nfs_sync_mapping(filp->f_mapping); |
754 | 755 | ||
756 | l_ctx = nfs_get_lock_context(nfs_file_open_context(filp)); | ||
757 | if (!IS_ERR(l_ctx)) { | ||
758 | status = nfs_iocounter_wait(&l_ctx->io_count); | ||
759 | nfs_put_lock_context(l_ctx); | ||
760 | if (status < 0) | ||
761 | return status; | ||
762 | } | ||
763 | |||
755 | /* NOTE: special case | 764 | /* NOTE: special case |
756 | * If we're signalled while cleaning up locks on process exit, we | 765 | * If we're signalled while cleaning up locks on process exit, we |
757 | * still need to complete the unlock. | 766 | * still need to complete the unlock. |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 1f941674b089..c1c7a9d78722 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -561,20 +561,22 @@ static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) | |||
561 | l_ctx->lockowner.l_owner = current->files; | 561 | l_ctx->lockowner.l_owner = current->files; |
562 | l_ctx->lockowner.l_pid = current->tgid; | 562 | l_ctx->lockowner.l_pid = current->tgid; |
563 | INIT_LIST_HEAD(&l_ctx->list); | 563 | INIT_LIST_HEAD(&l_ctx->list); |
564 | nfs_iocounter_init(&l_ctx->io_count); | ||
564 | } | 565 | } |
565 | 566 | ||
566 | static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx) | 567 | static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx) |
567 | { | 568 | { |
568 | struct nfs_lock_context *pos; | 569 | struct nfs_lock_context *head = &ctx->lock_context; |
570 | struct nfs_lock_context *pos = head; | ||
569 | 571 | ||
570 | list_for_each_entry(pos, &ctx->lock_context.list, list) { | 572 | do { |
571 | if (pos->lockowner.l_owner != current->files) | 573 | if (pos->lockowner.l_owner != current->files) |
572 | continue; | 574 | continue; |
573 | if (pos->lockowner.l_pid != current->tgid) | 575 | if (pos->lockowner.l_pid != current->tgid) |
574 | continue; | 576 | continue; |
575 | atomic_inc(&pos->count); | 577 | atomic_inc(&pos->count); |
576 | return pos; | 578 | return pos; |
577 | } | 579 | } while ((pos = list_entry(pos->list.next, typeof(*pos), list)) != head); |
578 | return NULL; | 580 | return NULL; |
579 | } | 581 | } |
580 | 582 | ||
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 541c9ebdbc5a..91e59a39fc08 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -229,6 +229,13 @@ extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, | |||
229 | struct nfs_pgio_header *hdr, | 229 | struct nfs_pgio_header *hdr, |
230 | void (*release)(struct nfs_pgio_header *hdr)); | 230 | void (*release)(struct nfs_pgio_header *hdr)); |
231 | void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos); | 231 | void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos); |
232 | int nfs_iocounter_wait(struct nfs_io_counter *c); | ||
233 | |||
234 | static inline void nfs_iocounter_init(struct nfs_io_counter *c) | ||
235 | { | ||
236 | c->flags = 0; | ||
237 | atomic_set(&c->io_count, 0); | ||
238 | } | ||
232 | 239 | ||
233 | /* nfs2xdr.c */ | 240 | /* nfs2xdr.c */ |
234 | extern struct rpc_procinfo nfs_procedures[]; | 241 | extern struct rpc_procinfo nfs_procedures[]; |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 944c9a5c1039..553a83cc4106 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -36,6 +36,7 @@ enum nfs4_client_state { | |||
36 | 36 | ||
37 | struct nfs4_minor_version_ops { | 37 | struct nfs4_minor_version_ops { |
38 | u32 minor_version; | 38 | u32 minor_version; |
39 | unsigned init_caps; | ||
39 | 40 | ||
40 | int (*call_sync)(struct rpc_clnt *clnt, | 41 | int (*call_sync)(struct rpc_clnt *clnt, |
41 | struct nfs_server *server, | 42 | struct nfs_server *server, |
@@ -143,12 +144,14 @@ struct nfs4_lock_state { | |||
143 | enum { | 144 | enum { |
144 | LK_STATE_IN_USE, | 145 | LK_STATE_IN_USE, |
145 | NFS_DELEGATED_STATE, /* Current stateid is delegation */ | 146 | NFS_DELEGATED_STATE, /* Current stateid is delegation */ |
147 | NFS_OPEN_STATE, /* OPEN stateid is set */ | ||
146 | NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */ | 148 | NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */ |
147 | NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */ | 149 | NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */ |
148 | NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ | 150 | NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ |
149 | NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */ | 151 | NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */ |
150 | NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */ | 152 | NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */ |
151 | NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */ | 153 | NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */ |
154 | NFS_STATE_RECOVERY_FAILED, /* OPEN stateid state recovery failed */ | ||
152 | }; | 155 | }; |
153 | 156 | ||
154 | struct nfs4_state { | 157 | struct nfs4_state { |
@@ -233,6 +236,10 @@ extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr | |||
233 | extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); | 236 | extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); |
234 | extern int nfs4_release_lockowner(struct nfs4_lock_state *); | 237 | extern int nfs4_release_lockowner(struct nfs4_lock_state *); |
235 | extern const struct xattr_handler *nfs4_xattr_handlers[]; | 238 | extern const struct xattr_handler *nfs4_xattr_handlers[]; |
239 | extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, | ||
240 | const struct nfs_open_context *ctx, | ||
241 | const struct nfs_lock_context *l_ctx, | ||
242 | fmode_t fmode); | ||
236 | 243 | ||
237 | #if defined(CONFIG_NFS_V4_1) | 244 | #if defined(CONFIG_NFS_V4_1) |
238 | static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server) | 245 | static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server) |
@@ -347,13 +354,13 @@ extern int nfs4_wait_clnt_recover(struct nfs_client *clp); | |||
347 | extern int nfs4_client_recover_expired_lease(struct nfs_client *clp); | 354 | extern int nfs4_client_recover_expired_lease(struct nfs_client *clp); |
348 | extern void nfs4_schedule_state_manager(struct nfs_client *); | 355 | extern void nfs4_schedule_state_manager(struct nfs_client *); |
349 | extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); | 356 | extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); |
350 | extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); | 357 | extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); |
351 | extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); | 358 | extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); |
352 | extern void nfs41_handle_server_scope(struct nfs_client *, | 359 | extern void nfs41_handle_server_scope(struct nfs_client *, |
353 | struct nfs41_server_scope **); | 360 | struct nfs41_server_scope **); |
354 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); | 361 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); |
355 | extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); | 362 | extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); |
356 | extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *, | 363 | extern int nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *, |
357 | fmode_t, const struct nfs_lockowner *); | 364 | fmode_t, const struct nfs_lockowner *); |
358 | 365 | ||
359 | extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask); | 366 | extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask); |
@@ -412,6 +419,11 @@ static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_statei | |||
412 | return memcmp(dst, src, sizeof(*dst)) == 0; | 419 | return memcmp(dst, src, sizeof(*dst)) == 0; |
413 | } | 420 | } |
414 | 421 | ||
422 | static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state) | ||
423 | { | ||
424 | return test_bit(NFS_STATE_RECOVERY_FAILED, &state->flags) == 0; | ||
425 | } | ||
426 | |||
415 | #else | 427 | #else |
416 | 428 | ||
417 | #define nfs4_close_state(a, b) do { } while (0) | 429 | #define nfs4_close_state(a, b) do { } while (0) |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index ac4fc9a8fdbc..947b0c908aa9 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -198,8 +198,12 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, | |||
198 | /* Check NFS protocol revision and initialize RPC op vector */ | 198 | /* Check NFS protocol revision and initialize RPC op vector */ |
199 | clp->rpc_ops = &nfs_v4_clientops; | 199 | clp->rpc_ops = &nfs_v4_clientops; |
200 | 200 | ||
201 | if (clp->cl_minorversion != 0) | ||
202 | __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags); | ||
201 | __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); | 203 | __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); |
202 | error = nfs_create_rpc_client(clp, timeparms, authflavour); | 204 | error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); |
205 | if (error == -EINVAL) | ||
206 | error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_NULL); | ||
203 | if (error < 0) | 207 | if (error < 0) |
204 | goto error; | 208 | goto error; |
205 | 209 | ||
@@ -300,7 +304,7 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
300 | struct rpc_cred *cred) | 304 | struct rpc_cred *cred) |
301 | { | 305 | { |
302 | struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); | 306 | struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); |
303 | struct nfs_client *pos, *n, *prev = NULL; | 307 | struct nfs_client *pos, *prev = NULL; |
304 | struct nfs4_setclientid_res clid = { | 308 | struct nfs4_setclientid_res clid = { |
305 | .clientid = new->cl_clientid, | 309 | .clientid = new->cl_clientid, |
306 | .confirm = new->cl_confirm, | 310 | .confirm = new->cl_confirm, |
@@ -308,10 +312,23 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
308 | int status = -NFS4ERR_STALE_CLIENTID; | 312 | int status = -NFS4ERR_STALE_CLIENTID; |
309 | 313 | ||
310 | spin_lock(&nn->nfs_client_lock); | 314 | spin_lock(&nn->nfs_client_lock); |
311 | list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { | 315 | list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { |
312 | /* If "pos" isn't marked ready, we can't trust the | 316 | /* If "pos" isn't marked ready, we can't trust the |
313 | * remaining fields in "pos" */ | 317 | * remaining fields in "pos" */ |
314 | if (pos->cl_cons_state < NFS_CS_READY) | 318 | if (pos->cl_cons_state > NFS_CS_READY) { |
319 | atomic_inc(&pos->cl_count); | ||
320 | spin_unlock(&nn->nfs_client_lock); | ||
321 | |||
322 | if (prev) | ||
323 | nfs_put_client(prev); | ||
324 | prev = pos; | ||
325 | |||
326 | status = nfs_wait_client_init_complete(pos); | ||
327 | spin_lock(&nn->nfs_client_lock); | ||
328 | if (status < 0) | ||
329 | continue; | ||
330 | } | ||
331 | if (pos->cl_cons_state != NFS_CS_READY) | ||
315 | continue; | 332 | continue; |
316 | 333 | ||
317 | if (pos->rpc_ops != new->rpc_ops) | 334 | if (pos->rpc_ops != new->rpc_ops) |
@@ -423,16 +440,16 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
423 | struct rpc_cred *cred) | 440 | struct rpc_cred *cred) |
424 | { | 441 | { |
425 | struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); | 442 | struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); |
426 | struct nfs_client *pos, *n, *prev = NULL; | 443 | struct nfs_client *pos, *prev = NULL; |
427 | int status = -NFS4ERR_STALE_CLIENTID; | 444 | int status = -NFS4ERR_STALE_CLIENTID; |
428 | 445 | ||
429 | spin_lock(&nn->nfs_client_lock); | 446 | spin_lock(&nn->nfs_client_lock); |
430 | list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { | 447 | list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { |
431 | /* If "pos" isn't marked ready, we can't trust the | 448 | /* If "pos" isn't marked ready, we can't trust the |
432 | * remaining fields in "pos", especially the client | 449 | * remaining fields in "pos", especially the client |
433 | * ID and serverowner fields. Wait for CREATE_SESSION | 450 | * ID and serverowner fields. Wait for CREATE_SESSION |
434 | * to finish. */ | 451 | * to finish. */ |
435 | if (pos->cl_cons_state < NFS_CS_READY) { | 452 | if (pos->cl_cons_state > NFS_CS_READY) { |
436 | atomic_inc(&pos->cl_count); | 453 | atomic_inc(&pos->cl_count); |
437 | spin_unlock(&nn->nfs_client_lock); | 454 | spin_unlock(&nn->nfs_client_lock); |
438 | 455 | ||
@@ -440,18 +457,17 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
440 | nfs_put_client(prev); | 457 | nfs_put_client(prev); |
441 | prev = pos; | 458 | prev = pos; |
442 | 459 | ||
443 | nfs4_schedule_lease_recovery(pos); | ||
444 | status = nfs_wait_client_init_complete(pos); | 460 | status = nfs_wait_client_init_complete(pos); |
445 | if (status < 0) { | 461 | if (status == 0) { |
446 | nfs_put_client(pos); | 462 | nfs4_schedule_lease_recovery(pos); |
447 | spin_lock(&nn->nfs_client_lock); | 463 | status = nfs4_wait_clnt_recover(pos); |
448 | continue; | ||
449 | } | 464 | } |
450 | status = pos->cl_cons_state; | ||
451 | spin_lock(&nn->nfs_client_lock); | 465 | spin_lock(&nn->nfs_client_lock); |
452 | if (status < 0) | 466 | if (status < 0) |
453 | continue; | 467 | continue; |
454 | } | 468 | } |
469 | if (pos->cl_cons_state != NFS_CS_READY) | ||
470 | continue; | ||
455 | 471 | ||
456 | if (pos->rpc_ops != new->rpc_ops) | 472 | if (pos->rpc_ops != new->rpc_ops) |
457 | continue; | 473 | continue; |
@@ -469,17 +485,18 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
469 | continue; | 485 | continue; |
470 | 486 | ||
471 | atomic_inc(&pos->cl_count); | 487 | atomic_inc(&pos->cl_count); |
472 | spin_unlock(&nn->nfs_client_lock); | 488 | *result = pos; |
489 | status = 0; | ||
473 | dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", | 490 | dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", |
474 | __func__, pos, atomic_read(&pos->cl_count)); | 491 | __func__, pos, atomic_read(&pos->cl_count)); |
475 | 492 | break; | |
476 | *result = pos; | ||
477 | return 0; | ||
478 | } | 493 | } |
479 | 494 | ||
480 | /* No matching nfs_client found. */ | 495 | /* No matching nfs_client found. */ |
481 | spin_unlock(&nn->nfs_client_lock); | 496 | spin_unlock(&nn->nfs_client_lock); |
482 | dprintk("NFS: <-- %s status = %d\n", __func__, status); | 497 | dprintk("NFS: <-- %s status = %d\n", __func__, status); |
498 | if (prev) | ||
499 | nfs_put_client(prev); | ||
483 | return status; | 500 | return status; |
484 | } | 501 | } |
485 | #endif /* CONFIG_NFS_V4_1 */ | 502 | #endif /* CONFIG_NFS_V4_1 */ |
@@ -717,6 +734,19 @@ static int nfs4_server_common_setup(struct nfs_server *server, | |||
717 | if (error < 0) | 734 | if (error < 0) |
718 | goto out; | 735 | goto out; |
719 | 736 | ||
737 | /* Set the basic capabilities */ | ||
738 | server->caps |= server->nfs_client->cl_mvops->init_caps; | ||
739 | if (server->flags & NFS_MOUNT_NORDIRPLUS) | ||
740 | server->caps &= ~NFS_CAP_READDIRPLUS; | ||
741 | /* | ||
742 | * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower | ||
743 | * authentication. | ||
744 | */ | ||
745 | if (nfs4_disable_idmapping && | ||
746 | server->client->cl_auth->au_flavor == RPC_AUTH_UNIX) | ||
747 | server->caps |= NFS_CAP_UIDGID_NOMAP; | ||
748 | |||
749 | |||
720 | /* Probe the root fh to retrieve its FSID and filehandle */ | 750 | /* Probe the root fh to retrieve its FSID and filehandle */ |
721 | error = nfs4_get_rootfh(server, mntfh); | 751 | error = nfs4_get_rootfh(server, mntfh); |
722 | if (error < 0) | 752 | if (error < 0) |
@@ -760,9 +790,6 @@ static int nfs4_init_server(struct nfs_server *server, | |||
760 | 790 | ||
761 | /* Initialise the client representation from the mount data */ | 791 | /* Initialise the client representation from the mount data */ |
762 | server->flags = data->flags; | 792 | server->flags = data->flags; |
763 | server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|NFS_CAP_POSIX_LOCK; | ||
764 | if (!(data->flags & NFS_MOUNT_NORDIRPLUS)) | ||
765 | server->caps |= NFS_CAP_READDIRPLUS; | ||
766 | server->options = data->options; | 793 | server->options = data->options; |
767 | 794 | ||
768 | /* Get a client record */ | 795 | /* Get a client record */ |
@@ -779,13 +806,6 @@ static int nfs4_init_server(struct nfs_server *server, | |||
779 | if (error < 0) | 806 | if (error < 0) |
780 | goto error; | 807 | goto error; |
781 | 808 | ||
782 | /* | ||
783 | * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower | ||
784 | * authentication. | ||
785 | */ | ||
786 | if (nfs4_disable_idmapping && data->auth_flavors[0] == RPC_AUTH_UNIX) | ||
787 | server->caps |= NFS_CAP_UIDGID_NOMAP; | ||
788 | |||
789 | if (data->rsize) | 809 | if (data->rsize) |
790 | server->rsize = nfs_block_size(data->rsize, NULL); | 810 | server->rsize = nfs_block_size(data->rsize, NULL); |
791 | if (data->wsize) | 811 | if (data->wsize) |
@@ -863,7 +883,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | |||
863 | 883 | ||
864 | /* Initialise the client representation from the parent server */ | 884 | /* Initialise the client representation from the parent server */ |
865 | nfs_server_copy_userdata(server, parent_server); | 885 | nfs_server_copy_userdata(server, parent_server); |
866 | server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR; | ||
867 | 886 | ||
868 | /* Get a client representation. | 887 | /* Get a client representation. |
869 | * Note: NFSv4 always uses TCP, */ | 888 | * Note: NFSv4 always uses TCP, */ |
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 4fb234d3aefb..22d10623f5ee 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -158,11 +158,14 @@ static int filelayout_async_handle_error(struct rpc_task *task, | |||
158 | case -NFS4ERR_OPENMODE: | 158 | case -NFS4ERR_OPENMODE: |
159 | if (state == NULL) | 159 | if (state == NULL) |
160 | break; | 160 | break; |
161 | nfs4_schedule_stateid_recovery(mds_server, state); | 161 | if (nfs4_schedule_stateid_recovery(mds_server, state) < 0) |
162 | goto out_bad_stateid; | ||
162 | goto wait_on_recovery; | 163 | goto wait_on_recovery; |
163 | case -NFS4ERR_EXPIRED: | 164 | case -NFS4ERR_EXPIRED: |
164 | if (state != NULL) | 165 | if (state != NULL) { |
165 | nfs4_schedule_stateid_recovery(mds_server, state); | 166 | if (nfs4_schedule_stateid_recovery(mds_server, state) < 0) |
167 | goto out_bad_stateid; | ||
168 | } | ||
166 | nfs4_schedule_lease_recovery(mds_client); | 169 | nfs4_schedule_lease_recovery(mds_client); |
167 | goto wait_on_recovery; | 170 | goto wait_on_recovery; |
168 | /* DS session errors */ | 171 | /* DS session errors */ |
@@ -226,6 +229,9 @@ reset: | |||
226 | out: | 229 | out: |
227 | task->tk_status = 0; | 230 | task->tk_status = 0; |
228 | return -EAGAIN; | 231 | return -EAGAIN; |
232 | out_bad_stateid: | ||
233 | task->tk_status = -EIO; | ||
234 | return 0; | ||
229 | wait_on_recovery: | 235 | wait_on_recovery: |
230 | rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL); | 236 | rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL); |
231 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0) | 237 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0) |
@@ -299,6 +305,10 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data) | |||
299 | { | 305 | { |
300 | struct nfs_read_data *rdata = data; | 306 | struct nfs_read_data *rdata = data; |
301 | 307 | ||
308 | if (unlikely(test_bit(NFS_CONTEXT_BAD, &rdata->args.context->flags))) { | ||
309 | rpc_exit(task, -EIO); | ||
310 | return; | ||
311 | } | ||
302 | if (filelayout_reset_to_mds(rdata->header->lseg)) { | 312 | if (filelayout_reset_to_mds(rdata->header->lseg)) { |
303 | dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); | 313 | dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); |
304 | filelayout_reset_read(rdata); | 314 | filelayout_reset_read(rdata); |
@@ -307,10 +317,13 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data) | |||
307 | } | 317 | } |
308 | rdata->read_done_cb = filelayout_read_done_cb; | 318 | rdata->read_done_cb = filelayout_read_done_cb; |
309 | 319 | ||
310 | nfs41_setup_sequence(rdata->ds_clp->cl_session, | 320 | if (nfs41_setup_sequence(rdata->ds_clp->cl_session, |
311 | &rdata->args.seq_args, | 321 | &rdata->args.seq_args, |
312 | &rdata->res.seq_res, | 322 | &rdata->res.seq_res, |
313 | task); | 323 | task)) |
324 | return; | ||
325 | nfs4_set_rw_stateid(&rdata->args.stateid, rdata->args.context, | ||
326 | rdata->args.lock_context, FMODE_READ); | ||
314 | } | 327 | } |
315 | 328 | ||
316 | static void filelayout_read_call_done(struct rpc_task *task, void *data) | 329 | static void filelayout_read_call_done(struct rpc_task *task, void *data) |
@@ -401,16 +414,23 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data) | |||
401 | { | 414 | { |
402 | struct nfs_write_data *wdata = data; | 415 | struct nfs_write_data *wdata = data; |
403 | 416 | ||
417 | if (unlikely(test_bit(NFS_CONTEXT_BAD, &wdata->args.context->flags))) { | ||
418 | rpc_exit(task, -EIO); | ||
419 | return; | ||
420 | } | ||
404 | if (filelayout_reset_to_mds(wdata->header->lseg)) { | 421 | if (filelayout_reset_to_mds(wdata->header->lseg)) { |
405 | dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); | 422 | dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid); |
406 | filelayout_reset_write(wdata); | 423 | filelayout_reset_write(wdata); |
407 | rpc_exit(task, 0); | 424 | rpc_exit(task, 0); |
408 | return; | 425 | return; |
409 | } | 426 | } |
410 | nfs41_setup_sequence(wdata->ds_clp->cl_session, | 427 | if (nfs41_setup_sequence(wdata->ds_clp->cl_session, |
411 | &wdata->args.seq_args, | 428 | &wdata->args.seq_args, |
412 | &wdata->res.seq_res, | 429 | &wdata->res.seq_res, |
413 | task); | 430 | task)) |
431 | return; | ||
432 | nfs4_set_rw_stateid(&wdata->args.stateid, wdata->args.context, | ||
433 | wdata->args.lock_context, FMODE_WRITE); | ||
414 | } | 434 | } |
415 | 435 | ||
416 | static void filelayout_write_call_done(struct rpc_task *task, void *data) | 436 | static void filelayout_write_call_done(struct rpc_task *task, void *data) |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 0dd766079e1c..cdb0b41a4810 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
@@ -134,33 +134,38 @@ static size_t nfs_parse_server_name(char *string, size_t len, | |||
134 | return ret; | 134 | return ret; |
135 | } | 135 | } |
136 | 136 | ||
137 | /** | ||
138 | * nfs_find_best_sec - Find a security mechanism supported locally | ||
139 | * @flavors: List of security tuples returned by SECINFO procedure | ||
140 | * | ||
141 | * Return the pseudoflavor of the first security mechanism in | ||
142 | * "flavors" that is locally supported. Return RPC_AUTH_UNIX if | ||
143 | * no matching flavor is found in the array. The "flavors" array | ||
144 | * is searched in the order returned from the server, per RFC 3530 | ||
145 | * recommendation. | ||
146 | */ | ||
137 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) | 147 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) |
138 | { | 148 | { |
139 | struct gss_api_mech *mech; | 149 | rpc_authflavor_t pseudoflavor; |
140 | struct xdr_netobj oid; | 150 | struct nfs4_secinfo4 *secinfo; |
141 | int i; | 151 | unsigned int i; |
142 | rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX; | ||
143 | 152 | ||
144 | for (i = 0; i < flavors->num_flavors; i++) { | 153 | for (i = 0; i < flavors->num_flavors; i++) { |
145 | struct nfs4_secinfo_flavor *flavor; | 154 | secinfo = &flavors->flavors[i]; |
146 | flavor = &flavors->flavors[i]; | 155 | |
147 | 156 | switch (secinfo->flavor) { | |
148 | if (flavor->flavor == RPC_AUTH_NULL || flavor->flavor == RPC_AUTH_UNIX) { | 157 | case RPC_AUTH_NULL: |
149 | pseudoflavor = flavor->flavor; | 158 | case RPC_AUTH_UNIX: |
150 | break; | 159 | case RPC_AUTH_GSS: |
151 | } else if (flavor->flavor == RPC_AUTH_GSS) { | 160 | pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor, |
152 | oid.len = flavor->gss.sec_oid4.len; | 161 | &secinfo->flavor_info); |
153 | oid.data = flavor->gss.sec_oid4.data; | 162 | if (pseudoflavor != RPC_AUTH_MAXFLAVOR) |
154 | mech = gss_mech_get_by_OID(&oid); | 163 | return pseudoflavor; |
155 | if (!mech) | ||
156 | continue; | ||
157 | pseudoflavor = gss_svc_to_pseudoflavor(mech, flavor->gss.service); | ||
158 | gss_mech_put(mech); | ||
159 | break; | 164 | break; |
160 | } | 165 | } |
161 | } | 166 | } |
162 | 167 | ||
163 | return pseudoflavor; | 168 | return RPC_AUTH_UNIX; |
164 | } | 169 | } |
165 | 170 | ||
166 | static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name) | 171 | static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 26431cf62ddb..9da4bd55eb30 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -107,6 +107,8 @@ static int nfs4_map_errors(int err) | |||
107 | return -EPROTONOSUPPORT; | 107 | return -EPROTONOSUPPORT; |
108 | case -NFS4ERR_ACCESS: | 108 | case -NFS4ERR_ACCESS: |
109 | return -EACCES; | 109 | return -EACCES; |
110 | case -NFS4ERR_FILE_OPEN: | ||
111 | return -EBUSY; | ||
110 | default: | 112 | default: |
111 | dprintk("%s could not handle NFSv4 error %d\n", | 113 | dprintk("%s could not handle NFSv4 error %d\n", |
112 | __func__, -err); | 114 | __func__, -err); |
@@ -295,19 +297,30 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc | |||
295 | } | 297 | } |
296 | if (state == NULL) | 298 | if (state == NULL) |
297 | break; | 299 | break; |
298 | nfs4_schedule_stateid_recovery(server, state); | 300 | ret = nfs4_schedule_stateid_recovery(server, state); |
301 | if (ret < 0) | ||
302 | break; | ||
299 | goto wait_on_recovery; | 303 | goto wait_on_recovery; |
300 | case -NFS4ERR_DELEG_REVOKED: | 304 | case -NFS4ERR_DELEG_REVOKED: |
301 | case -NFS4ERR_ADMIN_REVOKED: | 305 | case -NFS4ERR_ADMIN_REVOKED: |
302 | case -NFS4ERR_BAD_STATEID: | 306 | case -NFS4ERR_BAD_STATEID: |
307 | if (inode != NULL && nfs4_have_delegation(inode, FMODE_READ)) { | ||
308 | nfs_remove_bad_delegation(inode); | ||
309 | exception->retry = 1; | ||
310 | break; | ||
311 | } | ||
303 | if (state == NULL) | 312 | if (state == NULL) |
304 | break; | 313 | break; |
305 | nfs_remove_bad_delegation(state->inode); | 314 | ret = nfs4_schedule_stateid_recovery(server, state); |
306 | nfs4_schedule_stateid_recovery(server, state); | 315 | if (ret < 0) |
316 | break; | ||
307 | goto wait_on_recovery; | 317 | goto wait_on_recovery; |
308 | case -NFS4ERR_EXPIRED: | 318 | case -NFS4ERR_EXPIRED: |
309 | if (state != NULL) | 319 | if (state != NULL) { |
310 | nfs4_schedule_stateid_recovery(server, state); | 320 | ret = nfs4_schedule_stateid_recovery(server, state); |
321 | if (ret < 0) | ||
322 | break; | ||
323 | } | ||
311 | case -NFS4ERR_STALE_STATEID: | 324 | case -NFS4ERR_STALE_STATEID: |
312 | case -NFS4ERR_STALE_CLIENTID: | 325 | case -NFS4ERR_STALE_CLIENTID: |
313 | nfs4_schedule_lease_recovery(clp); | 326 | nfs4_schedule_lease_recovery(clp); |
@@ -756,10 +769,40 @@ struct nfs4_opendata { | |||
756 | struct iattr attrs; | 769 | struct iattr attrs; |
757 | unsigned long timestamp; | 770 | unsigned long timestamp; |
758 | unsigned int rpc_done : 1; | 771 | unsigned int rpc_done : 1; |
772 | unsigned int is_recover : 1; | ||
759 | int rpc_status; | 773 | int rpc_status; |
760 | int cancelled; | 774 | int cancelled; |
761 | }; | 775 | }; |
762 | 776 | ||
777 | static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server, | ||
778 | int err, struct nfs4_exception *exception) | ||
779 | { | ||
780 | if (err != -EINVAL) | ||
781 | return false; | ||
782 | if (!(server->caps & NFS_CAP_ATOMIC_OPEN_V1)) | ||
783 | return false; | ||
784 | server->caps &= ~NFS_CAP_ATOMIC_OPEN_V1; | ||
785 | exception->retry = 1; | ||
786 | return true; | ||
787 | } | ||
788 | |||
789 | static enum open_claim_type4 | ||
790 | nfs4_map_atomic_open_claim(struct nfs_server *server, | ||
791 | enum open_claim_type4 claim) | ||
792 | { | ||
793 | if (server->caps & NFS_CAP_ATOMIC_OPEN_V1) | ||
794 | return claim; | ||
795 | switch (claim) { | ||
796 | default: | ||
797 | return claim; | ||
798 | case NFS4_OPEN_CLAIM_FH: | ||
799 | return NFS4_OPEN_CLAIM_NULL; | ||
800 | case NFS4_OPEN_CLAIM_DELEG_CUR_FH: | ||
801 | return NFS4_OPEN_CLAIM_DELEGATE_CUR; | ||
802 | case NFS4_OPEN_CLAIM_DELEG_PREV_FH: | ||
803 | return NFS4_OPEN_CLAIM_DELEGATE_PREV; | ||
804 | } | ||
805 | } | ||
763 | 806 | ||
764 | static void nfs4_init_opendata_res(struct nfs4_opendata *p) | 807 | static void nfs4_init_opendata_res(struct nfs4_opendata *p) |
765 | { | 808 | { |
@@ -775,6 +818,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p) | |||
775 | static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | 818 | static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, |
776 | struct nfs4_state_owner *sp, fmode_t fmode, int flags, | 819 | struct nfs4_state_owner *sp, fmode_t fmode, int flags, |
777 | const struct iattr *attrs, | 820 | const struct iattr *attrs, |
821 | enum open_claim_type4 claim, | ||
778 | gfp_t gfp_mask) | 822 | gfp_t gfp_mask) |
779 | { | 823 | { |
780 | struct dentry *parent = dget_parent(dentry); | 824 | struct dentry *parent = dget_parent(dentry); |
@@ -793,7 +837,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | |||
793 | p->dir = parent; | 837 | p->dir = parent; |
794 | p->owner = sp; | 838 | p->owner = sp; |
795 | atomic_inc(&sp->so_count); | 839 | atomic_inc(&sp->so_count); |
796 | p->o_arg.fh = NFS_FH(dir); | ||
797 | p->o_arg.open_flags = flags; | 840 | p->o_arg.open_flags = flags; |
798 | p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); | 841 | p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); |
799 | /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS | 842 | /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS |
@@ -811,7 +854,19 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | |||
811 | p->o_arg.server = server; | 854 | p->o_arg.server = server; |
812 | p->o_arg.bitmask = server->attr_bitmask; | 855 | p->o_arg.bitmask = server->attr_bitmask; |
813 | p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; | 856 | p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; |
814 | p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; | 857 | p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); |
858 | switch (p->o_arg.claim) { | ||
859 | case NFS4_OPEN_CLAIM_NULL: | ||
860 | case NFS4_OPEN_CLAIM_DELEGATE_CUR: | ||
861 | case NFS4_OPEN_CLAIM_DELEGATE_PREV: | ||
862 | p->o_arg.fh = NFS_FH(dir); | ||
863 | break; | ||
864 | case NFS4_OPEN_CLAIM_PREVIOUS: | ||
865 | case NFS4_OPEN_CLAIM_FH: | ||
866 | case NFS4_OPEN_CLAIM_DELEG_CUR_FH: | ||
867 | case NFS4_OPEN_CLAIM_DELEG_PREV_FH: | ||
868 | p->o_arg.fh = NFS_FH(dentry->d_inode); | ||
869 | } | ||
815 | if (attrs != NULL && attrs->ia_valid != 0) { | 870 | if (attrs != NULL && attrs->ia_valid != 0) { |
816 | __be32 verf[2]; | 871 | __be32 verf[2]; |
817 | 872 | ||
@@ -924,6 +979,7 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid * | |||
924 | if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) | 979 | if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) |
925 | nfs4_stateid_copy(&state->stateid, stateid); | 980 | nfs4_stateid_copy(&state->stateid, stateid); |
926 | nfs4_stateid_copy(&state->open_stateid, stateid); | 981 | nfs4_stateid_copy(&state->open_stateid, stateid); |
982 | set_bit(NFS_OPEN_STATE, &state->flags); | ||
927 | switch (fmode) { | 983 | switch (fmode) { |
928 | case FMODE_READ: | 984 | case FMODE_READ: |
929 | set_bit(NFS_O_RDONLY_STATE, &state->flags); | 985 | set_bit(NFS_O_RDONLY_STATE, &state->flags); |
@@ -1046,9 +1102,12 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) | |||
1046 | /* Save the delegation */ | 1102 | /* Save the delegation */ |
1047 | nfs4_stateid_copy(&stateid, &delegation->stateid); | 1103 | nfs4_stateid_copy(&stateid, &delegation->stateid); |
1048 | rcu_read_unlock(); | 1104 | rcu_read_unlock(); |
1049 | ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); | 1105 | nfs_release_seqid(opendata->o_arg.seqid); |
1050 | if (ret != 0) | 1106 | if (!opendata->is_recover) { |
1051 | goto out; | 1107 | ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); |
1108 | if (ret != 0) | ||
1109 | goto out; | ||
1110 | } | ||
1052 | ret = -EAGAIN; | 1111 | ret = -EAGAIN; |
1053 | 1112 | ||
1054 | /* Try to update the stateid using the delegation */ | 1113 | /* Try to update the stateid using the delegation */ |
@@ -1193,11 +1252,13 @@ static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state * | |||
1193 | return ERR_PTR(-ENOENT); | 1252 | return ERR_PTR(-ENOENT); |
1194 | } | 1253 | } |
1195 | 1254 | ||
1196 | static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context *ctx, struct nfs4_state *state) | 1255 | static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context *ctx, |
1256 | struct nfs4_state *state, enum open_claim_type4 claim) | ||
1197 | { | 1257 | { |
1198 | struct nfs4_opendata *opendata; | 1258 | struct nfs4_opendata *opendata; |
1199 | 1259 | ||
1200 | opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, NULL, GFP_NOFS); | 1260 | opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, |
1261 | NULL, claim, GFP_NOFS); | ||
1201 | if (opendata == NULL) | 1262 | if (opendata == NULL) |
1202 | return ERR_PTR(-ENOMEM); | 1263 | return ERR_PTR(-ENOMEM); |
1203 | opendata->state = state; | 1264 | opendata->state = state; |
@@ -1233,6 +1294,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state * | |||
1233 | 1294 | ||
1234 | /* memory barrier prior to reading state->n_* */ | 1295 | /* memory barrier prior to reading state->n_* */ |
1235 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | 1296 | clear_bit(NFS_DELEGATED_STATE, &state->flags); |
1297 | clear_bit(NFS_OPEN_STATE, &state->flags); | ||
1236 | smp_rmb(); | 1298 | smp_rmb(); |
1237 | if (state->n_rdwr != 0) { | 1299 | if (state->n_rdwr != 0) { |
1238 | clear_bit(NFS_O_RDWR_STATE, &state->flags); | 1300 | clear_bit(NFS_O_RDWR_STATE, &state->flags); |
@@ -1283,11 +1345,10 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state | |||
1283 | fmode_t delegation_type = 0; | 1345 | fmode_t delegation_type = 0; |
1284 | int status; | 1346 | int status; |
1285 | 1347 | ||
1286 | opendata = nfs4_open_recoverdata_alloc(ctx, state); | 1348 | opendata = nfs4_open_recoverdata_alloc(ctx, state, |
1349 | NFS4_OPEN_CLAIM_PREVIOUS); | ||
1287 | if (IS_ERR(opendata)) | 1350 | if (IS_ERR(opendata)) |
1288 | return PTR_ERR(opendata); | 1351 | return PTR_ERR(opendata); |
1289 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS; | ||
1290 | opendata->o_arg.fh = NFS_FH(state->inode); | ||
1291 | rcu_read_lock(); | 1352 | rcu_read_lock(); |
1292 | delegation = rcu_dereference(NFS_I(state->inode)->delegation); | 1353 | delegation = rcu_dereference(NFS_I(state->inode)->delegation); |
1293 | if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0) | 1354 | if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0) |
@@ -1306,6 +1367,8 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state | |||
1306 | int err; | 1367 | int err; |
1307 | do { | 1368 | do { |
1308 | err = _nfs4_do_open_reclaim(ctx, state); | 1369 | err = _nfs4_do_open_reclaim(ctx, state); |
1370 | if (nfs4_clear_cap_atomic_open_v1(server, err, &exception)) | ||
1371 | continue; | ||
1309 | if (err != -NFS4ERR_DELAY) | 1372 | if (err != -NFS4ERR_DELAY) |
1310 | break; | 1373 | break; |
1311 | nfs4_handle_exception(server, err, &exception); | 1374 | nfs4_handle_exception(server, err, &exception); |
@@ -1320,71 +1383,72 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
1320 | 1383 | ||
1321 | ctx = nfs4_state_find_open_context(state); | 1384 | ctx = nfs4_state_find_open_context(state); |
1322 | if (IS_ERR(ctx)) | 1385 | if (IS_ERR(ctx)) |
1323 | return PTR_ERR(ctx); | 1386 | return -EAGAIN; |
1324 | ret = nfs4_do_open_reclaim(ctx, state); | 1387 | ret = nfs4_do_open_reclaim(ctx, state); |
1325 | put_nfs_open_context(ctx); | 1388 | put_nfs_open_context(ctx); |
1326 | return ret; | 1389 | return ret; |
1327 | } | 1390 | } |
1328 | 1391 | ||
1329 | static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) | 1392 | static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct nfs4_state *state, const nfs4_stateid *stateid, int err) |
1330 | { | 1393 | { |
1331 | struct nfs4_opendata *opendata; | 1394 | switch (err) { |
1332 | int ret; | 1395 | default: |
1333 | 1396 | printk(KERN_ERR "NFS: %s: unhandled error " | |
1334 | opendata = nfs4_open_recoverdata_alloc(ctx, state); | 1397 | "%d.\n", __func__, err); |
1335 | if (IS_ERR(opendata)) | 1398 | case 0: |
1336 | return PTR_ERR(opendata); | 1399 | case -ENOENT: |
1337 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR; | 1400 | case -ESTALE: |
1338 | nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid); | 1401 | break; |
1339 | ret = nfs4_open_recover(opendata, state); | 1402 | case -NFS4ERR_BADSESSION: |
1340 | nfs4_opendata_put(opendata); | 1403 | case -NFS4ERR_BADSLOT: |
1341 | return ret; | 1404 | case -NFS4ERR_BAD_HIGH_SLOT: |
1405 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: | ||
1406 | case -NFS4ERR_DEADSESSION: | ||
1407 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
1408 | nfs4_schedule_session_recovery(server->nfs_client->cl_session, err); | ||
1409 | return -EAGAIN; | ||
1410 | case -NFS4ERR_STALE_CLIENTID: | ||
1411 | case -NFS4ERR_STALE_STATEID: | ||
1412 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
1413 | case -NFS4ERR_EXPIRED: | ||
1414 | /* Don't recall a delegation if it was lost */ | ||
1415 | nfs4_schedule_lease_recovery(server->nfs_client); | ||
1416 | return -EAGAIN; | ||
1417 | case -NFS4ERR_DELEG_REVOKED: | ||
1418 | case -NFS4ERR_ADMIN_REVOKED: | ||
1419 | case -NFS4ERR_BAD_STATEID: | ||
1420 | case -NFS4ERR_OPENMODE: | ||
1421 | nfs_inode_find_state_and_recover(state->inode, | ||
1422 | stateid); | ||
1423 | nfs4_schedule_stateid_recovery(server, state); | ||
1424 | return 0; | ||
1425 | case -NFS4ERR_DELAY: | ||
1426 | case -NFS4ERR_GRACE: | ||
1427 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
1428 | ssleep(1); | ||
1429 | return -EAGAIN; | ||
1430 | case -ENOMEM: | ||
1431 | case -NFS4ERR_DENIED: | ||
1432 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ | ||
1433 | return 0; | ||
1434 | } | ||
1435 | return err; | ||
1342 | } | 1436 | } |
1343 | 1437 | ||
1344 | int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) | 1438 | int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) |
1345 | { | 1439 | { |
1346 | struct nfs4_exception exception = { }; | ||
1347 | struct nfs_server *server = NFS_SERVER(state->inode); | 1440 | struct nfs_server *server = NFS_SERVER(state->inode); |
1441 | struct nfs4_opendata *opendata; | ||
1348 | int err; | 1442 | int err; |
1349 | do { | 1443 | |
1350 | err = _nfs4_open_delegation_recall(ctx, state, stateid); | 1444 | opendata = nfs4_open_recoverdata_alloc(ctx, state, |
1351 | switch (err) { | 1445 | NFS4_OPEN_CLAIM_DELEG_CUR_FH); |
1352 | case 0: | 1446 | if (IS_ERR(opendata)) |
1353 | case -ENOENT: | 1447 | return PTR_ERR(opendata); |
1354 | case -ESTALE: | 1448 | nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid); |
1355 | goto out; | 1449 | err = nfs4_open_recover(opendata, state); |
1356 | case -NFS4ERR_BADSESSION: | 1450 | nfs4_opendata_put(opendata); |
1357 | case -NFS4ERR_BADSLOT: | 1451 | return nfs4_handle_delegation_recall_error(server, state, stateid, err); |
1358 | case -NFS4ERR_BAD_HIGH_SLOT: | ||
1359 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: | ||
1360 | case -NFS4ERR_DEADSESSION: | ||
1361 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
1362 | nfs4_schedule_session_recovery(server->nfs_client->cl_session, err); | ||
1363 | err = -EAGAIN; | ||
1364 | goto out; | ||
1365 | case -NFS4ERR_STALE_CLIENTID: | ||
1366 | case -NFS4ERR_STALE_STATEID: | ||
1367 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
1368 | case -NFS4ERR_EXPIRED: | ||
1369 | /* Don't recall a delegation if it was lost */ | ||
1370 | nfs4_schedule_lease_recovery(server->nfs_client); | ||
1371 | err = -EAGAIN; | ||
1372 | goto out; | ||
1373 | case -NFS4ERR_DELEG_REVOKED: | ||
1374 | case -NFS4ERR_ADMIN_REVOKED: | ||
1375 | case -NFS4ERR_BAD_STATEID: | ||
1376 | nfs_inode_find_state_and_recover(state->inode, | ||
1377 | stateid); | ||
1378 | nfs4_schedule_stateid_recovery(server, state); | ||
1379 | case -ENOMEM: | ||
1380 | err = 0; | ||
1381 | goto out; | ||
1382 | } | ||
1383 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
1384 | err = nfs4_handle_exception(server, err, &exception); | ||
1385 | } while (exception.retry); | ||
1386 | out: | ||
1387 | return err; | ||
1388 | } | 1452 | } |
1389 | 1453 | ||
1390 | static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) | 1454 | static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) |
@@ -1467,6 +1531,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) | |||
1467 | { | 1531 | { |
1468 | struct nfs4_opendata *data = calldata; | 1532 | struct nfs4_opendata *data = calldata; |
1469 | struct nfs4_state_owner *sp = data->owner; | 1533 | struct nfs4_state_owner *sp = data->owner; |
1534 | struct nfs_client *clp = sp->so_server->nfs_client; | ||
1470 | 1535 | ||
1471 | if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) | 1536 | if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) |
1472 | goto out_wait; | 1537 | goto out_wait; |
@@ -1482,15 +1547,20 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) | |||
1482 | rcu_read_lock(); | 1547 | rcu_read_lock(); |
1483 | delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); | 1548 | delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); |
1484 | if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR && | 1549 | if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR && |
1550 | data->o_arg.claim != NFS4_OPEN_CLAIM_DELEG_CUR_FH && | ||
1485 | can_open_delegated(delegation, data->o_arg.fmode)) | 1551 | can_open_delegated(delegation, data->o_arg.fmode)) |
1486 | goto unlock_no_action; | 1552 | goto unlock_no_action; |
1487 | rcu_read_unlock(); | 1553 | rcu_read_unlock(); |
1488 | } | 1554 | } |
1489 | /* Update client id. */ | 1555 | /* Update client id. */ |
1490 | data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid; | 1556 | data->o_arg.clientid = clp->cl_clientid; |
1491 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { | 1557 | switch (data->o_arg.claim) { |
1492 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; | 1558 | case NFS4_OPEN_CLAIM_PREVIOUS: |
1559 | case NFS4_OPEN_CLAIM_DELEG_CUR_FH: | ||
1560 | case NFS4_OPEN_CLAIM_DELEG_PREV_FH: | ||
1493 | data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0]; | 1561 | data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0]; |
1562 | case NFS4_OPEN_CLAIM_FH: | ||
1563 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; | ||
1494 | nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); | 1564 | nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); |
1495 | } | 1565 | } |
1496 | data->timestamp = jiffies; | 1566 | data->timestamp = jiffies; |
@@ -1499,6 +1569,16 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) | |||
1499 | &data->o_res.seq_res, | 1569 | &data->o_res.seq_res, |
1500 | task) != 0) | 1570 | task) != 0) |
1501 | nfs_release_seqid(data->o_arg.seqid); | 1571 | nfs_release_seqid(data->o_arg.seqid); |
1572 | |||
1573 | /* Set the create mode (note dependency on the session type) */ | ||
1574 | data->o_arg.createmode = NFS4_CREATE_UNCHECKED; | ||
1575 | if (data->o_arg.open_flags & O_EXCL) { | ||
1576 | data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE; | ||
1577 | if (nfs4_has_persistent_session(clp)) | ||
1578 | data->o_arg.createmode = NFS4_CREATE_GUARDED; | ||
1579 | else if (clp->cl_mvops->minor_version > 0) | ||
1580 | data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1; | ||
1581 | } | ||
1502 | return; | 1582 | return; |
1503 | unlock_no_action: | 1583 | unlock_no_action: |
1504 | rcu_read_unlock(); | 1584 | rcu_read_unlock(); |
@@ -1594,8 +1674,11 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover) | |||
1594 | data->rpc_done = 0; | 1674 | data->rpc_done = 0; |
1595 | data->rpc_status = 0; | 1675 | data->rpc_status = 0; |
1596 | data->cancelled = 0; | 1676 | data->cancelled = 0; |
1597 | if (isrecover) | 1677 | data->is_recover = 0; |
1678 | if (isrecover) { | ||
1598 | nfs4_set_sequence_privileged(&o_arg->seq_args); | 1679 | nfs4_set_sequence_privileged(&o_arg->seq_args); |
1680 | data->is_recover = 1; | ||
1681 | } | ||
1599 | task = rpc_run_task(&task_setup_data); | 1682 | task = rpc_run_task(&task_setup_data); |
1600 | if (IS_ERR(task)) | 1683 | if (IS_ERR(task)) |
1601 | return PTR_ERR(task); | 1684 | return PTR_ERR(task); |
@@ -1720,7 +1803,8 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s | |||
1720 | struct nfs4_opendata *opendata; | 1803 | struct nfs4_opendata *opendata; |
1721 | int ret; | 1804 | int ret; |
1722 | 1805 | ||
1723 | opendata = nfs4_open_recoverdata_alloc(ctx, state); | 1806 | opendata = nfs4_open_recoverdata_alloc(ctx, state, |
1807 | NFS4_OPEN_CLAIM_FH); | ||
1724 | if (IS_ERR(opendata)) | 1808 | if (IS_ERR(opendata)) |
1725 | return PTR_ERR(opendata); | 1809 | return PTR_ERR(opendata); |
1726 | ret = nfs4_open_recover(opendata, state); | 1810 | ret = nfs4_open_recover(opendata, state); |
@@ -1738,6 +1822,8 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state | |||
1738 | 1822 | ||
1739 | do { | 1823 | do { |
1740 | err = _nfs4_open_expired(ctx, state); | 1824 | err = _nfs4_open_expired(ctx, state); |
1825 | if (nfs4_clear_cap_atomic_open_v1(server, err, &exception)) | ||
1826 | continue; | ||
1741 | switch (err) { | 1827 | switch (err) { |
1742 | default: | 1828 | default: |
1743 | goto out; | 1829 | goto out; |
@@ -1758,7 +1844,7 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
1758 | 1844 | ||
1759 | ctx = nfs4_state_find_open_context(state); | 1845 | ctx = nfs4_state_find_open_context(state); |
1760 | if (IS_ERR(ctx)) | 1846 | if (IS_ERR(ctx)) |
1761 | return PTR_ERR(ctx); | 1847 | return -EAGAIN; |
1762 | ret = nfs4_do_open_expired(ctx, state); | 1848 | ret = nfs4_do_open_expired(ctx, state); |
1763 | put_nfs_open_context(ctx); | 1849 | put_nfs_open_context(ctx); |
1764 | return ret; | 1850 | return ret; |
@@ -1820,6 +1906,7 @@ static int nfs41_check_open_stateid(struct nfs4_state *state) | |||
1820 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); | 1906 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); |
1821 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); | 1907 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); |
1822 | clear_bit(NFS_O_RDWR_STATE, &state->flags); | 1908 | clear_bit(NFS_O_RDWR_STATE, &state->flags); |
1909 | clear_bit(NFS_OPEN_STATE, &state->flags); | ||
1823 | } | 1910 | } |
1824 | return status; | 1911 | return status; |
1825 | } | 1912 | } |
@@ -1880,10 +1967,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, | |||
1880 | if (ret != 0) | 1967 | if (ret != 0) |
1881 | goto out; | 1968 | goto out; |
1882 | 1969 | ||
1883 | if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) { | 1970 | if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) |
1884 | nfs4_schedule_stateid_recovery(server, state); | 1971 | nfs4_schedule_stateid_recovery(server, state); |
1885 | nfs4_wait_clnt_recover(server->nfs_client); | ||
1886 | } | ||
1887 | *res = state; | 1972 | *res = state; |
1888 | out: | 1973 | out: |
1889 | return ret; | 1974 | return ret; |
@@ -1905,6 +1990,7 @@ static int _nfs4_do_open(struct inode *dir, | |||
1905 | struct nfs4_state *state = NULL; | 1990 | struct nfs4_state *state = NULL; |
1906 | struct nfs_server *server = NFS_SERVER(dir); | 1991 | struct nfs_server *server = NFS_SERVER(dir); |
1907 | struct nfs4_opendata *opendata; | 1992 | struct nfs4_opendata *opendata; |
1993 | enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL; | ||
1908 | int status; | 1994 | int status; |
1909 | 1995 | ||
1910 | /* Protect against reboot recovery conflicts */ | 1996 | /* Protect against reboot recovery conflicts */ |
@@ -1920,7 +2006,10 @@ static int _nfs4_do_open(struct inode *dir, | |||
1920 | if (dentry->d_inode != NULL) | 2006 | if (dentry->d_inode != NULL) |
1921 | nfs4_return_incompatible_delegation(dentry->d_inode, fmode); | 2007 | nfs4_return_incompatible_delegation(dentry->d_inode, fmode); |
1922 | status = -ENOMEM; | 2008 | status = -ENOMEM; |
1923 | opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, GFP_KERNEL); | 2009 | if (dentry->d_inode) |
2010 | claim = NFS4_OPEN_CLAIM_FH; | ||
2011 | opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, | ||
2012 | claim, GFP_KERNEL); | ||
1924 | if (opendata == NULL) | 2013 | if (opendata == NULL) |
1925 | goto err_put_state_owner; | 2014 | goto err_put_state_owner; |
1926 | 2015 | ||
@@ -1937,7 +2026,8 @@ static int _nfs4_do_open(struct inode *dir, | |||
1937 | if (status != 0) | 2026 | if (status != 0) |
1938 | goto err_opendata_put; | 2027 | goto err_opendata_put; |
1939 | 2028 | ||
1940 | if (opendata->o_arg.open_flags & O_EXCL) { | 2029 | if ((opendata->o_arg.open_flags & O_EXCL) && |
2030 | (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) { | ||
1941 | nfs4_exclusive_attrset(opendata, sattr); | 2031 | nfs4_exclusive_attrset(opendata, sattr); |
1942 | 2032 | ||
1943 | nfs_fattr_init(opendata->o_res.f_attr); | 2033 | nfs_fattr_init(opendata->o_res.f_attr); |
@@ -1978,6 +2068,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, | |||
1978 | struct rpc_cred *cred, | 2068 | struct rpc_cred *cred, |
1979 | struct nfs4_threshold **ctx_th) | 2069 | struct nfs4_threshold **ctx_th) |
1980 | { | 2070 | { |
2071 | struct nfs_server *server = NFS_SERVER(dir); | ||
1981 | struct nfs4_exception exception = { }; | 2072 | struct nfs4_exception exception = { }; |
1982 | struct nfs4_state *res; | 2073 | struct nfs4_state *res; |
1983 | int status; | 2074 | int status; |
@@ -2021,7 +2112,9 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, | |||
2021 | exception.retry = 1; | 2112 | exception.retry = 1; |
2022 | continue; | 2113 | continue; |
2023 | } | 2114 | } |
2024 | res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir), | 2115 | if (nfs4_clear_cap_atomic_open_v1(server, status, &exception)) |
2116 | continue; | ||
2117 | res = ERR_PTR(nfs4_handle_exception(server, | ||
2025 | status, &exception)); | 2118 | status, &exception)); |
2026 | } while (exception.retry); | 2119 | } while (exception.retry); |
2027 | return res; | 2120 | return res; |
@@ -2049,20 +2142,25 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, | |||
2049 | .rpc_cred = cred, | 2142 | .rpc_cred = cred, |
2050 | }; | 2143 | }; |
2051 | unsigned long timestamp = jiffies; | 2144 | unsigned long timestamp = jiffies; |
2145 | fmode_t fmode; | ||
2146 | bool truncate; | ||
2052 | int status; | 2147 | int status; |
2053 | 2148 | ||
2054 | nfs_fattr_init(fattr); | 2149 | nfs_fattr_init(fattr); |
2055 | 2150 | ||
2056 | if (state != NULL) { | 2151 | /* Servers should only apply open mode checks for file size changes */ |
2152 | truncate = (sattr->ia_valid & ATTR_SIZE) ? true : false; | ||
2153 | fmode = truncate ? FMODE_WRITE : FMODE_READ; | ||
2154 | |||
2155 | if (nfs4_copy_delegation_stateid(&arg.stateid, inode, fmode)) { | ||
2156 | /* Use that stateid */ | ||
2157 | } else if (truncate && state != NULL && nfs4_valid_open_stateid(state)) { | ||
2057 | struct nfs_lockowner lockowner = { | 2158 | struct nfs_lockowner lockowner = { |
2058 | .l_owner = current->files, | 2159 | .l_owner = current->files, |
2059 | .l_pid = current->tgid, | 2160 | .l_pid = current->tgid, |
2060 | }; | 2161 | }; |
2061 | nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, | 2162 | nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, |
2062 | &lockowner); | 2163 | &lockowner); |
2063 | } else if (nfs4_copy_delegation_stateid(&arg.stateid, inode, | ||
2064 | FMODE_WRITE)) { | ||
2065 | /* Use that stateid */ | ||
2066 | } else | 2164 | } else |
2067 | nfs4_stateid_copy(&arg.stateid, &zero_stateid); | 2165 | nfs4_stateid_copy(&arg.stateid, &zero_stateid); |
2068 | 2166 | ||
@@ -2086,6 +2184,13 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, | |||
2086 | err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); | 2184 | err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); |
2087 | switch (err) { | 2185 | switch (err) { |
2088 | case -NFS4ERR_OPENMODE: | 2186 | case -NFS4ERR_OPENMODE: |
2187 | if (!(sattr->ia_valid & ATTR_SIZE)) { | ||
2188 | pr_warn_once("NFSv4: server %s is incorrectly " | ||
2189 | "applying open mode checks to " | ||
2190 | "a SETATTR that is not " | ||
2191 | "changing file size.\n", | ||
2192 | server->nfs_client->cl_hostname); | ||
2193 | } | ||
2089 | if (state && !(state->state & FMODE_WRITE)) { | 2194 | if (state && !(state->state & FMODE_WRITE)) { |
2090 | err = -EBADF; | 2195 | err = -EBADF; |
2091 | if (sattr->ia_valid & ATTR_OPEN) | 2196 | if (sattr->ia_valid & ATTR_OPEN) |
@@ -2129,11 +2234,19 @@ static void nfs4_close_clear_stateid_flags(struct nfs4_state *state, | |||
2129 | fmode_t fmode) | 2234 | fmode_t fmode) |
2130 | { | 2235 | { |
2131 | spin_lock(&state->owner->so_lock); | 2236 | spin_lock(&state->owner->so_lock); |
2132 | if (!(fmode & FMODE_READ)) | 2237 | clear_bit(NFS_O_RDWR_STATE, &state->flags); |
2238 | switch (fmode & (FMODE_READ|FMODE_WRITE)) { | ||
2239 | case FMODE_WRITE: | ||
2133 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); | 2240 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); |
2134 | if (!(fmode & FMODE_WRITE)) | 2241 | break; |
2242 | case FMODE_READ: | ||
2135 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); | 2243 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); |
2136 | clear_bit(NFS_O_RDWR_STATE, &state->flags); | 2244 | break; |
2245 | case 0: | ||
2246 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); | ||
2247 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); | ||
2248 | clear_bit(NFS_OPEN_STATE, &state->flags); | ||
2249 | } | ||
2137 | spin_unlock(&state->owner->so_lock); | 2250 | spin_unlock(&state->owner->so_lock); |
2138 | } | 2251 | } |
2139 | 2252 | ||
@@ -2201,6 +2314,8 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
2201 | calldata->arg.fmode &= ~FMODE_WRITE; | 2314 | calldata->arg.fmode &= ~FMODE_WRITE; |
2202 | } | 2315 | } |
2203 | } | 2316 | } |
2317 | if (!nfs4_valid_open_stateid(state)) | ||
2318 | call_close = 0; | ||
2204 | spin_unlock(&state->owner->so_lock); | 2319 | spin_unlock(&state->owner->so_lock); |
2205 | 2320 | ||
2206 | if (!call_close) { | 2321 | if (!call_close) { |
@@ -2211,8 +2326,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
2211 | if (calldata->arg.fmode == 0) { | 2326 | if (calldata->arg.fmode == 0) { |
2212 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE]; | 2327 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE]; |
2213 | if (calldata->roc && | 2328 | if (calldata->roc && |
2214 | pnfs_roc_drain(inode, &calldata->roc_barrier, task)) | 2329 | pnfs_roc_drain(inode, &calldata->roc_barrier, task)) { |
2330 | nfs_release_seqid(calldata->arg.seqid); | ||
2215 | goto out_wait; | 2331 | goto out_wait; |
2332 | } | ||
2216 | } | 2333 | } |
2217 | 2334 | ||
2218 | nfs_fattr_init(calldata->res.fattr); | 2335 | nfs_fattr_init(calldata->res.fattr); |
@@ -2443,7 +2560,7 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl | |||
2443 | 2560 | ||
2444 | auth = rpcauth_create(flavor, server->client); | 2561 | auth = rpcauth_create(flavor, server->client); |
2445 | if (IS_ERR(auth)) { | 2562 | if (IS_ERR(auth)) { |
2446 | ret = -EIO; | 2563 | ret = -EACCES; |
2447 | goto out; | 2564 | goto out; |
2448 | } | 2565 | } |
2449 | ret = nfs4_lookup_root(server, fhandle, info); | 2566 | ret = nfs4_lookup_root(server, fhandle, info); |
@@ -2451,27 +2568,36 @@ out: | |||
2451 | return ret; | 2568 | return ret; |
2452 | } | 2569 | } |
2453 | 2570 | ||
2571 | /* | ||
2572 | * Retry pseudoroot lookup with various security flavors. We do this when: | ||
2573 | * | ||
2574 | * NFSv4.0: the PUTROOTFH operation returns NFS4ERR_WRONGSEC | ||
2575 | * NFSv4.1: the server does not support the SECINFO_NO_NAME operation | ||
2576 | * | ||
2577 | * Returns zero on success, or a negative NFS4ERR value, or a | ||
2578 | * negative errno value. | ||
2579 | */ | ||
2454 | static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, | 2580 | static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, |
2455 | struct nfs_fsinfo *info) | 2581 | struct nfs_fsinfo *info) |
2456 | { | 2582 | { |
2457 | int i, len, status = 0; | 2583 | /* Per 3530bis 15.33.5 */ |
2458 | rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS]; | 2584 | static const rpc_authflavor_t flav_array[] = { |
2459 | 2585 | RPC_AUTH_GSS_KRB5P, | |
2460 | len = rpcauth_list_flavors(flav_array, ARRAY_SIZE(flav_array)); | 2586 | RPC_AUTH_GSS_KRB5I, |
2461 | if (len < 0) | 2587 | RPC_AUTH_GSS_KRB5, |
2462 | return len; | 2588 | RPC_AUTH_UNIX, /* courtesy */ |
2463 | 2589 | RPC_AUTH_NULL, | |
2464 | for (i = 0; i < len; i++) { | 2590 | }; |
2465 | /* AUTH_UNIX is the default flavor if none was specified, | 2591 | int status = -EPERM; |
2466 | * thus has already been tried. */ | 2592 | size_t i; |
2467 | if (flav_array[i] == RPC_AUTH_UNIX) | ||
2468 | continue; | ||
2469 | 2593 | ||
2594 | for (i = 0; i < ARRAY_SIZE(flav_array); i++) { | ||
2470 | status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); | 2595 | status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); |
2471 | if (status == -NFS4ERR_WRONGSEC || status == -EACCES) | 2596 | if (status == -NFS4ERR_WRONGSEC || status == -EACCES) |
2472 | continue; | 2597 | continue; |
2473 | break; | 2598 | break; |
2474 | } | 2599 | } |
2600 | |||
2475 | /* | 2601 | /* |
2476 | * -EACCESS could mean that the user doesn't have correct permissions | 2602 | * -EACCESS could mean that the user doesn't have correct permissions |
2477 | * to access the mount. It could also mean that we tried to mount | 2603 | * to access the mount. It could also mean that we tried to mount |
@@ -2484,24 +2610,36 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle, | |||
2484 | return status; | 2610 | return status; |
2485 | } | 2611 | } |
2486 | 2612 | ||
2487 | /* | 2613 | static int nfs4_do_find_root_sec(struct nfs_server *server, |
2488 | * get the file handle for the "/" directory on the server | 2614 | struct nfs_fh *fhandle, struct nfs_fsinfo *info) |
2615 | { | ||
2616 | int mv = server->nfs_client->cl_minorversion; | ||
2617 | return nfs_v4_minor_ops[mv]->find_root_sec(server, fhandle, info); | ||
2618 | } | ||
2619 | |||
2620 | /** | ||
2621 | * nfs4_proc_get_rootfh - get file handle for server's pseudoroot | ||
2622 | * @server: initialized nfs_server handle | ||
2623 | * @fhandle: we fill in the pseudo-fs root file handle | ||
2624 | * @info: we fill in an FSINFO struct | ||
2625 | * | ||
2626 | * Returns zero on success, or a negative errno. | ||
2489 | */ | 2627 | */ |
2490 | int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, | 2628 | int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, |
2491 | struct nfs_fsinfo *info) | 2629 | struct nfs_fsinfo *info) |
2492 | { | 2630 | { |
2493 | int minor_version = server->nfs_client->cl_minorversion; | 2631 | int status; |
2494 | int status = nfs4_lookup_root(server, fhandle, info); | 2632 | |
2495 | if ((status == -NFS4ERR_WRONGSEC) && !(server->flags & NFS_MOUNT_SECFLAVOUR)) | 2633 | status = nfs4_lookup_root(server, fhandle, info); |
2496 | /* | 2634 | if ((status == -NFS4ERR_WRONGSEC) && |
2497 | * A status of -NFS4ERR_WRONGSEC will be mapped to -EPERM | 2635 | !(server->flags & NFS_MOUNT_SECFLAVOUR)) |
2498 | * by nfs4_map_errors() as this function exits. | 2636 | status = nfs4_do_find_root_sec(server, fhandle, info); |
2499 | */ | 2637 | |
2500 | status = nfs_v4_minor_ops[minor_version]->find_root_sec(server, fhandle, info); | ||
2501 | if (status == 0) | 2638 | if (status == 0) |
2502 | status = nfs4_server_capabilities(server, fhandle); | 2639 | status = nfs4_server_capabilities(server, fhandle); |
2503 | if (status == 0) | 2640 | if (status == 0) |
2504 | status = nfs4_do_fsinfo(server, fhandle, info); | 2641 | status = nfs4_do_fsinfo(server, fhandle, info); |
2642 | |||
2505 | return nfs4_map_errors(status); | 2643 | return nfs4_map_errors(status); |
2506 | } | 2644 | } |
2507 | 2645 | ||
@@ -3380,12 +3518,21 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, | |||
3380 | static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) | 3518 | static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) |
3381 | { | 3519 | { |
3382 | struct nfs4_exception exception = { }; | 3520 | struct nfs4_exception exception = { }; |
3521 | unsigned long now = jiffies; | ||
3383 | int err; | 3522 | int err; |
3384 | 3523 | ||
3385 | do { | 3524 | do { |
3386 | err = nfs4_handle_exception(server, | 3525 | err = _nfs4_do_fsinfo(server, fhandle, fsinfo); |
3387 | _nfs4_do_fsinfo(server, fhandle, fsinfo), | 3526 | if (err == 0) { |
3388 | &exception); | 3527 | struct nfs_client *clp = server->nfs_client; |
3528 | |||
3529 | spin_lock(&clp->cl_lock); | ||
3530 | clp->cl_lease_time = fsinfo->lease_time * HZ; | ||
3531 | clp->cl_last_renewal = now; | ||
3532 | spin_unlock(&clp->cl_lock); | ||
3533 | break; | ||
3534 | } | ||
3535 | err = nfs4_handle_exception(server, err, &exception); | ||
3389 | } while (exception.retry); | 3536 | } while (exception.retry); |
3390 | return err; | 3537 | return err; |
3391 | } | 3538 | } |
@@ -3445,6 +3592,46 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, | |||
3445 | return err; | 3592 | return err; |
3446 | } | 3593 | } |
3447 | 3594 | ||
3595 | int nfs4_set_rw_stateid(nfs4_stateid *stateid, | ||
3596 | const struct nfs_open_context *ctx, | ||
3597 | const struct nfs_lock_context *l_ctx, | ||
3598 | fmode_t fmode) | ||
3599 | { | ||
3600 | const struct nfs_lockowner *lockowner = NULL; | ||
3601 | |||
3602 | if (l_ctx != NULL) | ||
3603 | lockowner = &l_ctx->lockowner; | ||
3604 | return nfs4_select_rw_stateid(stateid, ctx->state, fmode, lockowner); | ||
3605 | } | ||
3606 | EXPORT_SYMBOL_GPL(nfs4_set_rw_stateid); | ||
3607 | |||
3608 | static bool nfs4_stateid_is_current(nfs4_stateid *stateid, | ||
3609 | const struct nfs_open_context *ctx, | ||
3610 | const struct nfs_lock_context *l_ctx, | ||
3611 | fmode_t fmode) | ||
3612 | { | ||
3613 | nfs4_stateid current_stateid; | ||
3614 | |||
3615 | if (nfs4_set_rw_stateid(¤t_stateid, ctx, l_ctx, fmode)) | ||
3616 | return false; | ||
3617 | return nfs4_stateid_match(stateid, ¤t_stateid); | ||
3618 | } | ||
3619 | |||
3620 | static bool nfs4_error_stateid_expired(int err) | ||
3621 | { | ||
3622 | switch (err) { | ||
3623 | case -NFS4ERR_DELEG_REVOKED: | ||
3624 | case -NFS4ERR_ADMIN_REVOKED: | ||
3625 | case -NFS4ERR_BAD_STATEID: | ||
3626 | case -NFS4ERR_STALE_STATEID: | ||
3627 | case -NFS4ERR_OLD_STATEID: | ||
3628 | case -NFS4ERR_OPENMODE: | ||
3629 | case -NFS4ERR_EXPIRED: | ||
3630 | return true; | ||
3631 | } | ||
3632 | return false; | ||
3633 | } | ||
3634 | |||
3448 | void __nfs4_read_done_cb(struct nfs_read_data *data) | 3635 | void __nfs4_read_done_cb(struct nfs_read_data *data) |
3449 | { | 3636 | { |
3450 | nfs_invalidate_atime(data->header->inode); | 3637 | nfs_invalidate_atime(data->header->inode); |
@@ -3465,6 +3652,20 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) | |||
3465 | return 0; | 3652 | return 0; |
3466 | } | 3653 | } |
3467 | 3654 | ||
3655 | static bool nfs4_read_stateid_changed(struct rpc_task *task, | ||
3656 | struct nfs_readargs *args) | ||
3657 | { | ||
3658 | |||
3659 | if (!nfs4_error_stateid_expired(task->tk_status) || | ||
3660 | nfs4_stateid_is_current(&args->stateid, | ||
3661 | args->context, | ||
3662 | args->lock_context, | ||
3663 | FMODE_READ)) | ||
3664 | return false; | ||
3665 | rpc_restart_call_prepare(task); | ||
3666 | return true; | ||
3667 | } | ||
3668 | |||
3468 | static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) | 3669 | static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) |
3469 | { | 3670 | { |
3470 | 3671 | ||
@@ -3472,7 +3673,8 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) | |||
3472 | 3673 | ||
3473 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | 3674 | if (!nfs4_sequence_done(task, &data->res.seq_res)) |
3474 | return -EAGAIN; | 3675 | return -EAGAIN; |
3475 | 3676 | if (nfs4_read_stateid_changed(task, &data->args)) | |
3677 | return -EAGAIN; | ||
3476 | return data->read_done_cb ? data->read_done_cb(task, data) : | 3678 | return data->read_done_cb ? data->read_done_cb(task, data) : |
3477 | nfs4_read_done_cb(task, data); | 3679 | nfs4_read_done_cb(task, data); |
3478 | } | 3680 | } |
@@ -3487,10 +3689,13 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message | |||
3487 | 3689 | ||
3488 | static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) | 3690 | static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) |
3489 | { | 3691 | { |
3490 | nfs4_setup_sequence(NFS_SERVER(data->header->inode), | 3692 | if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), |
3491 | &data->args.seq_args, | 3693 | &data->args.seq_args, |
3492 | &data->res.seq_res, | 3694 | &data->res.seq_res, |
3493 | task); | 3695 | task)) |
3696 | return; | ||
3697 | nfs4_set_rw_stateid(&data->args.stateid, data->args.context, | ||
3698 | data->args.lock_context, FMODE_READ); | ||
3494 | } | 3699 | } |
3495 | 3700 | ||
3496 | static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data) | 3701 | static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data) |
@@ -3508,10 +3713,26 @@ static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data | |||
3508 | return 0; | 3713 | return 0; |
3509 | } | 3714 | } |
3510 | 3715 | ||
3716 | static bool nfs4_write_stateid_changed(struct rpc_task *task, | ||
3717 | struct nfs_writeargs *args) | ||
3718 | { | ||
3719 | |||
3720 | if (!nfs4_error_stateid_expired(task->tk_status) || | ||
3721 | nfs4_stateid_is_current(&args->stateid, | ||
3722 | args->context, | ||
3723 | args->lock_context, | ||
3724 | FMODE_WRITE)) | ||
3725 | return false; | ||
3726 | rpc_restart_call_prepare(task); | ||
3727 | return true; | ||
3728 | } | ||
3729 | |||
3511 | static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) | 3730 | static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) |
3512 | { | 3731 | { |
3513 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | 3732 | if (!nfs4_sequence_done(task, &data->res.seq_res)) |
3514 | return -EAGAIN; | 3733 | return -EAGAIN; |
3734 | if (nfs4_write_stateid_changed(task, &data->args)) | ||
3735 | return -EAGAIN; | ||
3515 | return data->write_done_cb ? data->write_done_cb(task, data) : | 3736 | return data->write_done_cb ? data->write_done_cb(task, data) : |
3516 | nfs4_write_done_cb(task, data); | 3737 | nfs4_write_done_cb(task, data); |
3517 | } | 3738 | } |
@@ -3551,10 +3772,13 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag | |||
3551 | 3772 | ||
3552 | static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) | 3773 | static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) |
3553 | { | 3774 | { |
3554 | nfs4_setup_sequence(NFS_SERVER(data->header->inode), | 3775 | if (nfs4_setup_sequence(NFS_SERVER(data->header->inode), |
3555 | &data->args.seq_args, | 3776 | &data->args.seq_args, |
3556 | &data->res.seq_res, | 3777 | &data->res.seq_res, |
3557 | task); | 3778 | task)) |
3779 | return; | ||
3780 | nfs4_set_rw_stateid(&data->args.stateid, data->args.context, | ||
3781 | data->args.lock_context, FMODE_WRITE); | ||
3558 | } | 3782 | } |
3559 | 3783 | ||
3560 | static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) | 3784 | static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) |
@@ -3656,7 +3880,7 @@ static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred, | |||
3656 | return -ENOMEM; | 3880 | return -ENOMEM; |
3657 | data->client = clp; | 3881 | data->client = clp; |
3658 | data->timestamp = jiffies; | 3882 | data->timestamp = jiffies; |
3659 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, | 3883 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT, |
3660 | &nfs4_renew_ops, data); | 3884 | &nfs4_renew_ops, data); |
3661 | } | 3885 | } |
3662 | 3886 | ||
@@ -3670,7 +3894,7 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) | |||
3670 | unsigned long now = jiffies; | 3894 | unsigned long now = jiffies; |
3671 | int status; | 3895 | int status; |
3672 | 3896 | ||
3673 | status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); | 3897 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); |
3674 | if (status < 0) | 3898 | if (status < 0) |
3675 | return status; | 3899 | return status; |
3676 | do_renew_lease(clp, now); | 3900 | do_renew_lease(clp, now); |
@@ -3980,11 +4204,14 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3980 | case -NFS4ERR_OPENMODE: | 4204 | case -NFS4ERR_OPENMODE: |
3981 | if (state == NULL) | 4205 | if (state == NULL) |
3982 | break; | 4206 | break; |
3983 | nfs4_schedule_stateid_recovery(server, state); | 4207 | if (nfs4_schedule_stateid_recovery(server, state) < 0) |
4208 | goto stateid_invalid; | ||
3984 | goto wait_on_recovery; | 4209 | goto wait_on_recovery; |
3985 | case -NFS4ERR_EXPIRED: | 4210 | case -NFS4ERR_EXPIRED: |
3986 | if (state != NULL) | 4211 | if (state != NULL) { |
3987 | nfs4_schedule_stateid_recovery(server, state); | 4212 | if (nfs4_schedule_stateid_recovery(server, state) < 0) |
4213 | goto stateid_invalid; | ||
4214 | } | ||
3988 | case -NFS4ERR_STALE_STATEID: | 4215 | case -NFS4ERR_STALE_STATEID: |
3989 | case -NFS4ERR_STALE_CLIENTID: | 4216 | case -NFS4ERR_STALE_CLIENTID: |
3990 | nfs4_schedule_lease_recovery(clp); | 4217 | nfs4_schedule_lease_recovery(clp); |
@@ -4016,6 +4243,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
4016 | } | 4243 | } |
4017 | task->tk_status = nfs4_map_errors(task->tk_status); | 4244 | task->tk_status = nfs4_map_errors(task->tk_status); |
4018 | return 0; | 4245 | return 0; |
4246 | stateid_invalid: | ||
4247 | task->tk_status = -EIO; | ||
4248 | return 0; | ||
4019 | wait_on_recovery: | 4249 | wait_on_recovery: |
4020 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | 4250 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); |
4021 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) | 4251 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) |
@@ -4143,27 +4373,17 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp, | |||
4143 | struct nfs4_setclientid_res *arg, | 4373 | struct nfs4_setclientid_res *arg, |
4144 | struct rpc_cred *cred) | 4374 | struct rpc_cred *cred) |
4145 | { | 4375 | { |
4146 | struct nfs_fsinfo fsinfo; | ||
4147 | struct rpc_message msg = { | 4376 | struct rpc_message msg = { |
4148 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], | 4377 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], |
4149 | .rpc_argp = arg, | 4378 | .rpc_argp = arg, |
4150 | .rpc_resp = &fsinfo, | ||
4151 | .rpc_cred = cred, | 4379 | .rpc_cred = cred, |
4152 | }; | 4380 | }; |
4153 | unsigned long now; | ||
4154 | int status; | 4381 | int status; |
4155 | 4382 | ||
4156 | dprintk("NFS call setclientid_confirm auth=%s, (client ID %llx)\n", | 4383 | dprintk("NFS call setclientid_confirm auth=%s, (client ID %llx)\n", |
4157 | clp->cl_rpcclient->cl_auth->au_ops->au_name, | 4384 | clp->cl_rpcclient->cl_auth->au_ops->au_name, |
4158 | clp->cl_clientid); | 4385 | clp->cl_clientid); |
4159 | now = jiffies; | ||
4160 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); | 4386 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); |
4161 | if (status == 0) { | ||
4162 | spin_lock(&clp->cl_lock); | ||
4163 | clp->cl_lease_time = fsinfo.lease_time * HZ; | ||
4164 | clp->cl_last_renewal = now; | ||
4165 | spin_unlock(&clp->cl_lock); | ||
4166 | } | ||
4167 | dprintk("NFS reply setclientid_confirm: %d\n", status); | 4387 | dprintk("NFS reply setclientid_confirm: %d\n", status); |
4168 | return status; | 4388 | return status; |
4169 | } | 4389 | } |
@@ -4627,17 +4847,23 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) | |||
4627 | if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) { | 4847 | if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) { |
4628 | goto out_release_lock_seqid; | 4848 | goto out_release_lock_seqid; |
4629 | } | 4849 | } |
4630 | data->arg.open_stateid = &state->stateid; | 4850 | data->arg.open_stateid = &state->open_stateid; |
4631 | data->arg.new_lock_owner = 1; | 4851 | data->arg.new_lock_owner = 1; |
4632 | data->res.open_seqid = data->arg.open_seqid; | 4852 | data->res.open_seqid = data->arg.open_seqid; |
4633 | } else | 4853 | } else |
4634 | data->arg.new_lock_owner = 0; | 4854 | data->arg.new_lock_owner = 0; |
4855 | if (!nfs4_valid_open_stateid(state)) { | ||
4856 | data->rpc_status = -EBADF; | ||
4857 | task->tk_action = NULL; | ||
4858 | goto out_release_open_seqid; | ||
4859 | } | ||
4635 | data->timestamp = jiffies; | 4860 | data->timestamp = jiffies; |
4636 | if (nfs4_setup_sequence(data->server, | 4861 | if (nfs4_setup_sequence(data->server, |
4637 | &data->arg.seq_args, | 4862 | &data->arg.seq_args, |
4638 | &data->res.seq_res, | 4863 | &data->res.seq_res, |
4639 | task) == 0) | 4864 | task) == 0) |
4640 | return; | 4865 | return; |
4866 | out_release_open_seqid: | ||
4641 | nfs_release_seqid(data->arg.open_seqid); | 4867 | nfs_release_seqid(data->arg.open_seqid); |
4642 | out_release_lock_seqid: | 4868 | out_release_lock_seqid: |
4643 | nfs_release_seqid(data->arg.lock_seqid); | 4869 | nfs_release_seqid(data->arg.lock_seqid); |
@@ -4983,58 +5209,16 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request) | |||
4983 | return status; | 5209 | return status; |
4984 | } | 5210 | } |
4985 | 5211 | ||
4986 | int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) | 5212 | int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid) |
4987 | { | 5213 | { |
4988 | struct nfs_server *server = NFS_SERVER(state->inode); | 5214 | struct nfs_server *server = NFS_SERVER(state->inode); |
4989 | struct nfs4_exception exception = { }; | ||
4990 | int err; | 5215 | int err; |
4991 | 5216 | ||
4992 | err = nfs4_set_lock_state(state, fl); | 5217 | err = nfs4_set_lock_state(state, fl); |
4993 | if (err != 0) | 5218 | if (err != 0) |
4994 | goto out; | 5219 | return err; |
4995 | do { | 5220 | err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW); |
4996 | err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW); | 5221 | return nfs4_handle_delegation_recall_error(server, state, stateid, err); |
4997 | switch (err) { | ||
4998 | default: | ||
4999 | printk(KERN_ERR "NFS: %s: unhandled error " | ||
5000 | "%d.\n", __func__, err); | ||
5001 | case 0: | ||
5002 | case -ESTALE: | ||
5003 | goto out; | ||
5004 | case -NFS4ERR_STALE_CLIENTID: | ||
5005 | case -NFS4ERR_STALE_STATEID: | ||
5006 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
5007 | case -NFS4ERR_EXPIRED: | ||
5008 | nfs4_schedule_lease_recovery(server->nfs_client); | ||
5009 | err = -EAGAIN; | ||
5010 | goto out; | ||
5011 | case -NFS4ERR_BADSESSION: | ||
5012 | case -NFS4ERR_BADSLOT: | ||
5013 | case -NFS4ERR_BAD_HIGH_SLOT: | ||
5014 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: | ||
5015 | case -NFS4ERR_DEADSESSION: | ||
5016 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
5017 | nfs4_schedule_session_recovery(server->nfs_client->cl_session, err); | ||
5018 | err = -EAGAIN; | ||
5019 | goto out; | ||
5020 | case -NFS4ERR_DELEG_REVOKED: | ||
5021 | case -NFS4ERR_ADMIN_REVOKED: | ||
5022 | case -NFS4ERR_BAD_STATEID: | ||
5023 | case -NFS4ERR_OPENMODE: | ||
5024 | nfs4_schedule_stateid_recovery(server, state); | ||
5025 | err = 0; | ||
5026 | goto out; | ||
5027 | case -ENOMEM: | ||
5028 | case -NFS4ERR_DENIED: | ||
5029 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ | ||
5030 | err = 0; | ||
5031 | goto out; | ||
5032 | } | ||
5033 | set_bit(NFS_DELEGATED_STATE, &state->flags); | ||
5034 | err = nfs4_handle_exception(server, err, &exception); | ||
5035 | } while (exception.retry); | ||
5036 | out: | ||
5037 | return err; | ||
5038 | } | 5222 | } |
5039 | 5223 | ||
5040 | struct nfs_release_lockowner_data { | 5224 | struct nfs_release_lockowner_data { |
@@ -5848,7 +6032,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, | |||
5848 | .rpc_client = clp->cl_rpcclient, | 6032 | .rpc_client = clp->cl_rpcclient, |
5849 | .rpc_message = &msg, | 6033 | .rpc_message = &msg, |
5850 | .callback_ops = &nfs41_sequence_ops, | 6034 | .callback_ops = &nfs41_sequence_ops, |
5851 | .flags = RPC_TASK_ASYNC | RPC_TASK_SOFT, | 6035 | .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT, |
5852 | }; | 6036 | }; |
5853 | 6037 | ||
5854 | if (!atomic_inc_not_zero(&clp->cl_count)) | 6038 | if (!atomic_inc_not_zero(&clp->cl_count)) |
@@ -6725,6 +6909,10 @@ static const struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = { | |||
6725 | 6909 | ||
6726 | static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = { | 6910 | static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = { |
6727 | .minor_version = 0, | 6911 | .minor_version = 0, |
6912 | .init_caps = NFS_CAP_READDIRPLUS | ||
6913 | | NFS_CAP_ATOMIC_OPEN | ||
6914 | | NFS_CAP_CHANGE_ATTR | ||
6915 | | NFS_CAP_POSIX_LOCK, | ||
6728 | .call_sync = _nfs4_call_sync, | 6916 | .call_sync = _nfs4_call_sync, |
6729 | .match_stateid = nfs4_match_stateid, | 6917 | .match_stateid = nfs4_match_stateid, |
6730 | .find_root_sec = nfs4_find_root_sec, | 6918 | .find_root_sec = nfs4_find_root_sec, |
@@ -6736,6 +6924,12 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = { | |||
6736 | #if defined(CONFIG_NFS_V4_1) | 6924 | #if defined(CONFIG_NFS_V4_1) |
6737 | static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { | 6925 | static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { |
6738 | .minor_version = 1, | 6926 | .minor_version = 1, |
6927 | .init_caps = NFS_CAP_READDIRPLUS | ||
6928 | | NFS_CAP_ATOMIC_OPEN | ||
6929 | | NFS_CAP_CHANGE_ATTR | ||
6930 | | NFS_CAP_POSIX_LOCK | ||
6931 | | NFS_CAP_STATEID_NFSV41 | ||
6932 | | NFS_CAP_ATOMIC_OPEN_V1, | ||
6739 | .call_sync = nfs4_call_sync_sequence, | 6933 | .call_sync = nfs4_call_sync_sequence, |
6740 | .match_stateid = nfs41_match_stateid, | 6934 | .match_stateid = nfs41_match_stateid, |
6741 | .find_root_sec = nfs41_find_root_sec, | 6935 | .find_root_sec = nfs41_find_root_sec, |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6ace365c6334..0b32f9483b7a 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -154,18 +154,6 @@ struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp) | |||
154 | return cred; | 154 | return cred; |
155 | } | 155 | } |
156 | 156 | ||
157 | static void nfs4_clear_machine_cred(struct nfs_client *clp) | ||
158 | { | ||
159 | struct rpc_cred *cred; | ||
160 | |||
161 | spin_lock(&clp->cl_lock); | ||
162 | cred = clp->cl_machine_cred; | ||
163 | clp->cl_machine_cred = NULL; | ||
164 | spin_unlock(&clp->cl_lock); | ||
165 | if (cred != NULL) | ||
166 | put_rpccred(cred); | ||
167 | } | ||
168 | |||
169 | static struct rpc_cred * | 157 | static struct rpc_cred * |
170 | nfs4_get_renew_cred_server_locked(struct nfs_server *server) | 158 | nfs4_get_renew_cred_server_locked(struct nfs_server *server) |
171 | { | 159 | { |
@@ -699,6 +687,8 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) | |||
699 | list_for_each_entry(state, &nfsi->open_states, inode_states) { | 687 | list_for_each_entry(state, &nfsi->open_states, inode_states) { |
700 | if (state->owner != owner) | 688 | if (state->owner != owner) |
701 | continue; | 689 | continue; |
690 | if (!nfs4_valid_open_stateid(state)) | ||
691 | continue; | ||
702 | if (atomic_inc_not_zero(&state->count)) | 692 | if (atomic_inc_not_zero(&state->count)) |
703 | return state; | 693 | return state; |
704 | } | 694 | } |
@@ -987,13 +977,14 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl) | |||
987 | return 0; | 977 | return 0; |
988 | } | 978 | } |
989 | 979 | ||
990 | static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state, | 980 | static int nfs4_copy_lock_stateid(nfs4_stateid *dst, |
981 | struct nfs4_state *state, | ||
991 | const struct nfs_lockowner *lockowner) | 982 | const struct nfs_lockowner *lockowner) |
992 | { | 983 | { |
993 | struct nfs4_lock_state *lsp; | 984 | struct nfs4_lock_state *lsp; |
994 | fl_owner_t fl_owner; | 985 | fl_owner_t fl_owner; |
995 | pid_t fl_pid; | 986 | pid_t fl_pid; |
996 | bool ret = false; | 987 | int ret = -ENOENT; |
997 | 988 | ||
998 | 989 | ||
999 | if (lockowner == NULL) | 990 | if (lockowner == NULL) |
@@ -1008,7 +999,10 @@ static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state, | |||
1008 | lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); | 999 | lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); |
1009 | if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { | 1000 | if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { |
1010 | nfs4_stateid_copy(dst, &lsp->ls_stateid); | 1001 | nfs4_stateid_copy(dst, &lsp->ls_stateid); |
1011 | ret = true; | 1002 | ret = 0; |
1003 | smp_rmb(); | ||
1004 | if (!list_empty(&lsp->ls_seqid.list)) | ||
1005 | ret = -EWOULDBLOCK; | ||
1012 | } | 1006 | } |
1013 | spin_unlock(&state->state_lock); | 1007 | spin_unlock(&state->state_lock); |
1014 | nfs4_put_lock_state(lsp); | 1008 | nfs4_put_lock_state(lsp); |
@@ -1016,28 +1010,44 @@ out: | |||
1016 | return ret; | 1010 | return ret; |
1017 | } | 1011 | } |
1018 | 1012 | ||
1019 | static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) | 1013 | static int nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) |
1020 | { | 1014 | { |
1015 | const nfs4_stateid *src; | ||
1016 | int ret; | ||
1021 | int seq; | 1017 | int seq; |
1022 | 1018 | ||
1023 | do { | 1019 | do { |
1020 | src = &zero_stateid; | ||
1024 | seq = read_seqbegin(&state->seqlock); | 1021 | seq = read_seqbegin(&state->seqlock); |
1025 | nfs4_stateid_copy(dst, &state->stateid); | 1022 | if (test_bit(NFS_OPEN_STATE, &state->flags)) |
1023 | src = &state->open_stateid; | ||
1024 | nfs4_stateid_copy(dst, src); | ||
1025 | ret = 0; | ||
1026 | smp_rmb(); | ||
1027 | if (!list_empty(&state->owner->so_seqid.list)) | ||
1028 | ret = -EWOULDBLOCK; | ||
1026 | } while (read_seqretry(&state->seqlock, seq)); | 1029 | } while (read_seqretry(&state->seqlock, seq)); |
1030 | return ret; | ||
1027 | } | 1031 | } |
1028 | 1032 | ||
1029 | /* | 1033 | /* |
1030 | * Byte-range lock aware utility to initialize the stateid of read/write | 1034 | * Byte-range lock aware utility to initialize the stateid of read/write |
1031 | * requests. | 1035 | * requests. |
1032 | */ | 1036 | */ |
1033 | void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, | 1037 | int nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, |
1034 | fmode_t fmode, const struct nfs_lockowner *lockowner) | 1038 | fmode_t fmode, const struct nfs_lockowner *lockowner) |
1035 | { | 1039 | { |
1040 | int ret = 0; | ||
1036 | if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) | 1041 | if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) |
1037 | return; | 1042 | goto out; |
1038 | if (nfs4_copy_lock_stateid(dst, state, lockowner)) | 1043 | ret = nfs4_copy_lock_stateid(dst, state, lockowner); |
1039 | return; | 1044 | if (ret != -ENOENT) |
1040 | nfs4_copy_open_stateid(dst, state); | 1045 | goto out; |
1046 | ret = nfs4_copy_open_stateid(dst, state); | ||
1047 | out: | ||
1048 | if (nfs_server_capable(state->inode, NFS_CAP_STATEID_NFSV41)) | ||
1049 | dst->seqid = 0; | ||
1050 | return ret; | ||
1041 | } | 1051 | } |
1042 | 1052 | ||
1043 | struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask) | 1053 | struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask) |
@@ -1286,14 +1296,17 @@ static int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_s | |||
1286 | return 1; | 1296 | return 1; |
1287 | } | 1297 | } |
1288 | 1298 | ||
1289 | void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state) | 1299 | int nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state) |
1290 | { | 1300 | { |
1291 | struct nfs_client *clp = server->nfs_client; | 1301 | struct nfs_client *clp = server->nfs_client; |
1292 | 1302 | ||
1303 | if (!nfs4_valid_open_stateid(state)) | ||
1304 | return -EBADF; | ||
1293 | nfs4_state_mark_reclaim_nograce(clp, state); | 1305 | nfs4_state_mark_reclaim_nograce(clp, state); |
1294 | dprintk("%s: scheduling stateid recovery for server %s\n", __func__, | 1306 | dprintk("%s: scheduling stateid recovery for server %s\n", __func__, |
1295 | clp->cl_hostname); | 1307 | clp->cl_hostname); |
1296 | nfs4_schedule_state_manager(clp); | 1308 | nfs4_schedule_state_manager(clp); |
1309 | return 0; | ||
1297 | } | 1310 | } |
1298 | EXPORT_SYMBOL_GPL(nfs4_schedule_stateid_recovery); | 1311 | EXPORT_SYMBOL_GPL(nfs4_schedule_stateid_recovery); |
1299 | 1312 | ||
@@ -1323,6 +1336,27 @@ void nfs_inode_find_state_and_recover(struct inode *inode, | |||
1323 | nfs4_schedule_state_manager(clp); | 1336 | nfs4_schedule_state_manager(clp); |
1324 | } | 1337 | } |
1325 | 1338 | ||
1339 | static void nfs4_state_mark_open_context_bad(struct nfs4_state *state) | ||
1340 | { | ||
1341 | struct inode *inode = state->inode; | ||
1342 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1343 | struct nfs_open_context *ctx; | ||
1344 | |||
1345 | spin_lock(&inode->i_lock); | ||
1346 | list_for_each_entry(ctx, &nfsi->open_files, list) { | ||
1347 | if (ctx->state != state) | ||
1348 | continue; | ||
1349 | set_bit(NFS_CONTEXT_BAD, &ctx->flags); | ||
1350 | } | ||
1351 | spin_unlock(&inode->i_lock); | ||
1352 | } | ||
1353 | |||
1354 | static void nfs4_state_mark_recovery_failed(struct nfs4_state *state, int error) | ||
1355 | { | ||
1356 | set_bit(NFS_STATE_RECOVERY_FAILED, &state->flags); | ||
1357 | nfs4_state_mark_open_context_bad(state); | ||
1358 | } | ||
1359 | |||
1326 | 1360 | ||
1327 | static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops) | 1361 | static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops) |
1328 | { | 1362 | { |
@@ -1398,6 +1432,8 @@ restart: | |||
1398 | list_for_each_entry(state, &sp->so_states, open_states) { | 1432 | list_for_each_entry(state, &sp->so_states, open_states) { |
1399 | if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) | 1433 | if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) |
1400 | continue; | 1434 | continue; |
1435 | if (!nfs4_valid_open_stateid(state)) | ||
1436 | continue; | ||
1401 | if (state->state == 0) | 1437 | if (state->state == 0) |
1402 | continue; | 1438 | continue; |
1403 | atomic_inc(&state->count); | 1439 | atomic_inc(&state->count); |
@@ -1430,11 +1466,10 @@ restart: | |||
1430 | * Open state on this file cannot be recovered | 1466 | * Open state on this file cannot be recovered |
1431 | * All we can do is revert to using the zero stateid. | 1467 | * All we can do is revert to using the zero stateid. |
1432 | */ | 1468 | */ |
1433 | memset(&state->stateid, 0, | 1469 | nfs4_state_mark_recovery_failed(state, status); |
1434 | sizeof(state->stateid)); | ||
1435 | /* Mark the file as being 'closed' */ | ||
1436 | state->state = 0; | ||
1437 | break; | 1470 | break; |
1471 | case -EAGAIN: | ||
1472 | ssleep(1); | ||
1438 | case -NFS4ERR_ADMIN_REVOKED: | 1473 | case -NFS4ERR_ADMIN_REVOKED: |
1439 | case -NFS4ERR_STALE_STATEID: | 1474 | case -NFS4ERR_STALE_STATEID: |
1440 | case -NFS4ERR_BAD_STATEID: | 1475 | case -NFS4ERR_BAD_STATEID: |
@@ -1696,6 +1731,10 @@ static int nfs4_check_lease(struct nfs_client *clp) | |||
1696 | } | 1731 | } |
1697 | status = ops->renew_lease(clp, cred); | 1732 | status = ops->renew_lease(clp, cred); |
1698 | put_rpccred(cred); | 1733 | put_rpccred(cred); |
1734 | if (status == -ETIMEDOUT) { | ||
1735 | set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); | ||
1736 | return 0; | ||
1737 | } | ||
1699 | out: | 1738 | out: |
1700 | return nfs4_recovery_handle_error(clp, status); | 1739 | return nfs4_recovery_handle_error(clp, status); |
1701 | } | 1740 | } |
@@ -1725,10 +1764,6 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status) | |||
1725 | clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); | 1764 | clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); |
1726 | return -EPERM; | 1765 | return -EPERM; |
1727 | case -EACCES: | 1766 | case -EACCES: |
1728 | if (clp->cl_machine_cred == NULL) | ||
1729 | return -EACCES; | ||
1730 | /* Handle case where the user hasn't set up machine creds */ | ||
1731 | nfs4_clear_machine_cred(clp); | ||
1732 | case -NFS4ERR_DELAY: | 1767 | case -NFS4ERR_DELAY: |
1733 | case -ETIMEDOUT: | 1768 | case -ETIMEDOUT: |
1734 | case -EAGAIN: | 1769 | case -EAGAIN: |
@@ -1823,31 +1858,18 @@ int nfs4_discover_server_trunking(struct nfs_client *clp, | |||
1823 | { | 1858 | { |
1824 | const struct nfs4_state_recovery_ops *ops = | 1859 | const struct nfs4_state_recovery_ops *ops = |
1825 | clp->cl_mvops->reboot_recovery_ops; | 1860 | clp->cl_mvops->reboot_recovery_ops; |
1826 | rpc_authflavor_t *flavors, flav, save; | ||
1827 | struct rpc_clnt *clnt; | 1861 | struct rpc_clnt *clnt; |
1828 | struct rpc_cred *cred; | 1862 | struct rpc_cred *cred; |
1829 | int i, len, status; | 1863 | int i, status; |
1830 | 1864 | ||
1831 | dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname); | 1865 | dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname); |
1832 | 1866 | ||
1833 | len = NFS_MAX_SECFLAVORS; | ||
1834 | flavors = kcalloc(len, sizeof(*flavors), GFP_KERNEL); | ||
1835 | if (flavors == NULL) { | ||
1836 | status = -ENOMEM; | ||
1837 | goto out; | ||
1838 | } | ||
1839 | len = rpcauth_list_flavors(flavors, len); | ||
1840 | if (len < 0) { | ||
1841 | status = len; | ||
1842 | goto out_free; | ||
1843 | } | ||
1844 | clnt = clp->cl_rpcclient; | 1867 | clnt = clp->cl_rpcclient; |
1845 | save = clnt->cl_auth->au_flavor; | ||
1846 | i = 0; | 1868 | i = 0; |
1847 | 1869 | ||
1848 | mutex_lock(&nfs_clid_init_mutex); | 1870 | mutex_lock(&nfs_clid_init_mutex); |
1849 | status = -ENOENT; | ||
1850 | again: | 1871 | again: |
1872 | status = -ENOENT; | ||
1851 | cred = ops->get_clid_cred(clp); | 1873 | cred = ops->get_clid_cred(clp); |
1852 | if (cred == NULL) | 1874 | if (cred == NULL) |
1853 | goto out_unlock; | 1875 | goto out_unlock; |
@@ -1857,12 +1879,6 @@ again: | |||
1857 | switch (status) { | 1879 | switch (status) { |
1858 | case 0: | 1880 | case 0: |
1859 | break; | 1881 | break; |
1860 | |||
1861 | case -EACCES: | ||
1862 | if (clp->cl_machine_cred == NULL) | ||
1863 | break; | ||
1864 | /* Handle case where the user hasn't set up machine creds */ | ||
1865 | nfs4_clear_machine_cred(clp); | ||
1866 | case -NFS4ERR_DELAY: | 1882 | case -NFS4ERR_DELAY: |
1867 | case -ETIMEDOUT: | 1883 | case -ETIMEDOUT: |
1868 | case -EAGAIN: | 1884 | case -EAGAIN: |
@@ -1871,22 +1887,23 @@ again: | |||
1871 | dprintk("NFS: %s after status %d, retrying\n", | 1887 | dprintk("NFS: %s after status %d, retrying\n", |
1872 | __func__, status); | 1888 | __func__, status); |
1873 | goto again; | 1889 | goto again; |
1874 | 1890 | case -EACCES: | |
1891 | if (i++) | ||
1892 | break; | ||
1875 | case -NFS4ERR_CLID_INUSE: | 1893 | case -NFS4ERR_CLID_INUSE: |
1876 | case -NFS4ERR_WRONGSEC: | 1894 | case -NFS4ERR_WRONGSEC: |
1877 | status = -EPERM; | 1895 | clnt = rpc_clone_client_set_auth(clnt, RPC_AUTH_UNIX); |
1878 | if (i >= len) | ||
1879 | break; | ||
1880 | |||
1881 | flav = flavors[i++]; | ||
1882 | if (flav == save) | ||
1883 | flav = flavors[i++]; | ||
1884 | clnt = rpc_clone_client_set_auth(clnt, flav); | ||
1885 | if (IS_ERR(clnt)) { | 1896 | if (IS_ERR(clnt)) { |
1886 | status = PTR_ERR(clnt); | 1897 | status = PTR_ERR(clnt); |
1887 | break; | 1898 | break; |
1888 | } | 1899 | } |
1889 | clp->cl_rpcclient = clnt; | 1900 | /* Note: this is safe because we haven't yet marked the |
1901 | * client as ready, so we are the only user of | ||
1902 | * clp->cl_rpcclient | ||
1903 | */ | ||
1904 | clnt = xchg(&clp->cl_rpcclient, clnt); | ||
1905 | rpc_shutdown_client(clnt); | ||
1906 | clnt = clp->cl_rpcclient; | ||
1890 | goto again; | 1907 | goto again; |
1891 | 1908 | ||
1892 | case -NFS4ERR_MINOR_VERS_MISMATCH: | 1909 | case -NFS4ERR_MINOR_VERS_MISMATCH: |
@@ -1897,13 +1914,15 @@ again: | |||
1897 | case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery | 1914 | case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery |
1898 | * in nfs4_exchange_id */ | 1915 | * in nfs4_exchange_id */ |
1899 | status = -EKEYEXPIRED; | 1916 | status = -EKEYEXPIRED; |
1917 | break; | ||
1918 | default: | ||
1919 | pr_warn("NFS: %s unhandled error %d. Exiting with error EIO\n", | ||
1920 | __func__, status); | ||
1921 | status = -EIO; | ||
1900 | } | 1922 | } |
1901 | 1923 | ||
1902 | out_unlock: | 1924 | out_unlock: |
1903 | mutex_unlock(&nfs_clid_init_mutex); | 1925 | mutex_unlock(&nfs_clid_init_mutex); |
1904 | out_free: | ||
1905 | kfree(flavors); | ||
1906 | out: | ||
1907 | dprintk("NFS: %s: status = %d\n", __func__, status); | 1926 | dprintk("NFS: %s: status = %d\n", __func__, status); |
1908 | return status; | 1927 | return status; |
1909 | } | 1928 | } |
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 569b166cc050..a5e1a3026d48 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c | |||
@@ -252,6 +252,8 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name, | |||
252 | 252 | ||
253 | dfprintk(MOUNT, "--> nfs4_try_mount()\n"); | 253 | dfprintk(MOUNT, "--> nfs4_try_mount()\n"); |
254 | 254 | ||
255 | if (data->auth_flavors[0] == RPC_AUTH_MAXFLAVOR) | ||
256 | data->auth_flavors[0] = RPC_AUTH_UNIX; | ||
255 | export_path = data->nfs_server.export_path; | 257 | export_path = data->nfs_server.export_path; |
256 | data->nfs_server.export_path = "/"; | 258 | data->nfs_server.export_path = "/"; |
257 | root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, | 259 | root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e3edda554ac7..3c79c5878c6d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -530,14 +530,10 @@ static int nfs4_stat_to_errno(int); | |||
530 | decode_setclientid_maxsz) | 530 | decode_setclientid_maxsz) |
531 | #define NFS4_enc_setclientid_confirm_sz \ | 531 | #define NFS4_enc_setclientid_confirm_sz \ |
532 | (compound_encode_hdr_maxsz + \ | 532 | (compound_encode_hdr_maxsz + \ |
533 | encode_setclientid_confirm_maxsz + \ | 533 | encode_setclientid_confirm_maxsz) |
534 | encode_putrootfh_maxsz + \ | ||
535 | encode_fsinfo_maxsz) | ||
536 | #define NFS4_dec_setclientid_confirm_sz \ | 534 | #define NFS4_dec_setclientid_confirm_sz \ |
537 | (compound_decode_hdr_maxsz + \ | 535 | (compound_decode_hdr_maxsz + \ |
538 | decode_setclientid_confirm_maxsz + \ | 536 | decode_setclientid_confirm_maxsz) |
539 | decode_putrootfh_maxsz + \ | ||
540 | decode_fsinfo_maxsz) | ||
541 | #define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ | 537 | #define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ |
542 | encode_sequence_maxsz + \ | 538 | encode_sequence_maxsz + \ |
543 | encode_putfh_maxsz + \ | 539 | encode_putfh_maxsz + \ |
@@ -1058,8 +1054,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1058 | if (iap->ia_valid & ATTR_ATIME_SET) { | 1054 | if (iap->ia_valid & ATTR_ATIME_SET) { |
1059 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; | 1055 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; |
1060 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); | 1056 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); |
1061 | *p++ = cpu_to_be32(0); | 1057 | p = xdr_encode_hyper(p, (s64)iap->ia_atime.tv_sec); |
1062 | *p++ = cpu_to_be32(iap->ia_atime.tv_sec); | ||
1063 | *p++ = cpu_to_be32(iap->ia_atime.tv_nsec); | 1058 | *p++ = cpu_to_be32(iap->ia_atime.tv_nsec); |
1064 | } | 1059 | } |
1065 | else if (iap->ia_valid & ATTR_ATIME) { | 1060 | else if (iap->ia_valid & ATTR_ATIME) { |
@@ -1069,8 +1064,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1069 | if (iap->ia_valid & ATTR_MTIME_SET) { | 1064 | if (iap->ia_valid & ATTR_MTIME_SET) { |
1070 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; | 1065 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; |
1071 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); | 1066 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); |
1072 | *p++ = cpu_to_be32(0); | 1067 | p = xdr_encode_hyper(p, (s64)iap->ia_mtime.tv_sec); |
1073 | *p++ = cpu_to_be32(iap->ia_mtime.tv_sec); | ||
1074 | *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); | 1068 | *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); |
1075 | } | 1069 | } |
1076 | else if (iap->ia_valid & ATTR_MTIME) { | 1070 | else if (iap->ia_valid & ATTR_MTIME) { |
@@ -1366,33 +1360,28 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena | |||
1366 | 1360 | ||
1367 | static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) | 1361 | static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) |
1368 | { | 1362 | { |
1363 | struct iattr dummy; | ||
1369 | __be32 *p; | 1364 | __be32 *p; |
1370 | struct nfs_client *clp; | ||
1371 | 1365 | ||
1372 | p = reserve_space(xdr, 4); | 1366 | p = reserve_space(xdr, 4); |
1373 | switch(arg->open_flags & O_EXCL) { | 1367 | switch(arg->createmode) { |
1374 | case 0: | 1368 | case NFS4_CREATE_UNCHECKED: |
1375 | *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); | 1369 | *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); |
1376 | encode_attrs(xdr, arg->u.attrs, arg->server); | 1370 | encode_attrs(xdr, arg->u.attrs, arg->server); |
1377 | break; | 1371 | break; |
1378 | default: | 1372 | case NFS4_CREATE_GUARDED: |
1379 | clp = arg->server->nfs_client; | 1373 | *p = cpu_to_be32(NFS4_CREATE_GUARDED); |
1380 | if (clp->cl_mvops->minor_version > 0) { | 1374 | encode_attrs(xdr, arg->u.attrs, arg->server); |
1381 | if (nfs4_has_persistent_session(clp)) { | 1375 | break; |
1382 | *p = cpu_to_be32(NFS4_CREATE_GUARDED); | 1376 | case NFS4_CREATE_EXCLUSIVE: |
1383 | encode_attrs(xdr, arg->u.attrs, arg->server); | 1377 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); |
1384 | } else { | 1378 | encode_nfs4_verifier(xdr, &arg->u.verifier); |
1385 | struct iattr dummy; | 1379 | break; |
1386 | 1380 | case NFS4_CREATE_EXCLUSIVE4_1: | |
1387 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); | 1381 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); |
1388 | encode_nfs4_verifier(xdr, &arg->u.verifier); | 1382 | encode_nfs4_verifier(xdr, &arg->u.verifier); |
1389 | dummy.ia_valid = 0; | 1383 | dummy.ia_valid = 0; |
1390 | encode_attrs(xdr, &dummy, arg->server); | 1384 | encode_attrs(xdr, &dummy, arg->server); |
1391 | } | ||
1392 | } else { | ||
1393 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); | ||
1394 | encode_nfs4_verifier(xdr, &arg->u.verifier); | ||
1395 | } | ||
1396 | } | 1385 | } |
1397 | } | 1386 | } |
1398 | 1387 | ||
@@ -1459,6 +1448,23 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc | |||
1459 | encode_string(xdr, name->len, name->name); | 1448 | encode_string(xdr, name->len, name->name); |
1460 | } | 1449 | } |
1461 | 1450 | ||
1451 | static inline void encode_claim_fh(struct xdr_stream *xdr) | ||
1452 | { | ||
1453 | __be32 *p; | ||
1454 | |||
1455 | p = reserve_space(xdr, 4); | ||
1456 | *p = cpu_to_be32(NFS4_OPEN_CLAIM_FH); | ||
1457 | } | ||
1458 | |||
1459 | static inline void encode_claim_delegate_cur_fh(struct xdr_stream *xdr, const nfs4_stateid *stateid) | ||
1460 | { | ||
1461 | __be32 *p; | ||
1462 | |||
1463 | p = reserve_space(xdr, 4); | ||
1464 | *p = cpu_to_be32(NFS4_OPEN_CLAIM_DELEG_CUR_FH); | ||
1465 | encode_nfs4_stateid(xdr, stateid); | ||
1466 | } | ||
1467 | |||
1462 | static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr) | 1468 | static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr) |
1463 | { | 1469 | { |
1464 | encode_op_hdr(xdr, OP_OPEN, decode_open_maxsz, hdr); | 1470 | encode_op_hdr(xdr, OP_OPEN, decode_open_maxsz, hdr); |
@@ -1474,6 +1480,12 @@ static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, | |||
1474 | case NFS4_OPEN_CLAIM_DELEGATE_CUR: | 1480 | case NFS4_OPEN_CLAIM_DELEGATE_CUR: |
1475 | encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation); | 1481 | encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation); |
1476 | break; | 1482 | break; |
1483 | case NFS4_OPEN_CLAIM_FH: | ||
1484 | encode_claim_fh(xdr); | ||
1485 | break; | ||
1486 | case NFS4_OPEN_CLAIM_DELEG_CUR_FH: | ||
1487 | encode_claim_delegate_cur_fh(xdr, &arg->u.delegation); | ||
1488 | break; | ||
1477 | default: | 1489 | default: |
1478 | BUG(); | 1490 | BUG(); |
1479 | } | 1491 | } |
@@ -1506,35 +1518,12 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
1506 | encode_op_hdr(xdr, OP_PUTROOTFH, decode_putrootfh_maxsz, hdr); | 1518 | encode_op_hdr(xdr, OP_PUTROOTFH, decode_putrootfh_maxsz, hdr); |
1507 | } | 1519 | } |
1508 | 1520 | ||
1509 | static void encode_open_stateid(struct xdr_stream *xdr, | ||
1510 | const struct nfs_open_context *ctx, | ||
1511 | const struct nfs_lock_context *l_ctx, | ||
1512 | fmode_t fmode, | ||
1513 | int zero_seqid) | ||
1514 | { | ||
1515 | nfs4_stateid stateid; | ||
1516 | |||
1517 | if (ctx->state != NULL) { | ||
1518 | const struct nfs_lockowner *lockowner = NULL; | ||
1519 | |||
1520 | if (l_ctx != NULL) | ||
1521 | lockowner = &l_ctx->lockowner; | ||
1522 | nfs4_select_rw_stateid(&stateid, ctx->state, | ||
1523 | fmode, lockowner); | ||
1524 | if (zero_seqid) | ||
1525 | stateid.seqid = 0; | ||
1526 | encode_nfs4_stateid(xdr, &stateid); | ||
1527 | } else | ||
1528 | encode_nfs4_stateid(xdr, &zero_stateid); | ||
1529 | } | ||
1530 | |||
1531 | static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr) | 1521 | static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr) |
1532 | { | 1522 | { |
1533 | __be32 *p; | 1523 | __be32 *p; |
1534 | 1524 | ||
1535 | encode_op_hdr(xdr, OP_READ, decode_read_maxsz, hdr); | 1525 | encode_op_hdr(xdr, OP_READ, decode_read_maxsz, hdr); |
1536 | encode_open_stateid(xdr, args->context, args->lock_context, | 1526 | encode_nfs4_stateid(xdr, &args->stateid); |
1537 | FMODE_READ, hdr->minorversion); | ||
1538 | 1527 | ||
1539 | p = reserve_space(xdr, 12); | 1528 | p = reserve_space(xdr, 12); |
1540 | p = xdr_encode_hyper(p, args->offset); | 1529 | p = xdr_encode_hyper(p, args->offset); |
@@ -1670,8 +1659,7 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg | |||
1670 | __be32 *p; | 1659 | __be32 *p; |
1671 | 1660 | ||
1672 | encode_op_hdr(xdr, OP_WRITE, decode_write_maxsz, hdr); | 1661 | encode_op_hdr(xdr, OP_WRITE, decode_write_maxsz, hdr); |
1673 | encode_open_stateid(xdr, args->context, args->lock_context, | 1662 | encode_nfs4_stateid(xdr, &args->stateid); |
1674 | FMODE_WRITE, hdr->minorversion); | ||
1675 | 1663 | ||
1676 | p = reserve_space(xdr, 16); | 1664 | p = reserve_space(xdr, 16); |
1677 | p = xdr_encode_hyper(p, args->offset); | 1665 | p = xdr_encode_hyper(p, args->offset); |
@@ -2609,12 +2597,9 @@ static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, | |||
2609 | struct compound_hdr hdr = { | 2597 | struct compound_hdr hdr = { |
2610 | .nops = 0, | 2598 | .nops = 0, |
2611 | }; | 2599 | }; |
2612 | const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME }; | ||
2613 | 2600 | ||
2614 | encode_compound_hdr(xdr, req, &hdr); | 2601 | encode_compound_hdr(xdr, req, &hdr); |
2615 | encode_setclientid_confirm(xdr, arg, &hdr); | 2602 | encode_setclientid_confirm(xdr, arg, &hdr); |
2616 | encode_putrootfh(xdr, &hdr); | ||
2617 | encode_fsinfo(xdr, lease_bitmap, &hdr); | ||
2618 | encode_nops(&hdr); | 2603 | encode_nops(&hdr); |
2619 | } | 2604 | } |
2620 | 2605 | ||
@@ -3497,8 +3482,11 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | |||
3497 | if (n == 0) | 3482 | if (n == 0) |
3498 | goto root_path; | 3483 | goto root_path; |
3499 | dprintk("pathname4: "); | 3484 | dprintk("pathname4: "); |
3500 | path->ncomponents = 0; | 3485 | if (n > NFS4_PATHNAME_MAXCOMPONENTS) { |
3501 | while (path->ncomponents < n) { | 3486 | dprintk("cannot parse %d components in path\n", n); |
3487 | goto out_eio; | ||
3488 | } | ||
3489 | for (path->ncomponents = 0; path->ncomponents < n; path->ncomponents++) { | ||
3502 | struct nfs4_string *component = &path->components[path->ncomponents]; | 3490 | struct nfs4_string *component = &path->components[path->ncomponents]; |
3503 | status = decode_opaque_inline(xdr, &component->len, &component->data); | 3491 | status = decode_opaque_inline(xdr, &component->len, &component->data); |
3504 | if (unlikely(status != 0)) | 3492 | if (unlikely(status != 0)) |
@@ -3507,12 +3495,6 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | |||
3507 | pr_cont("%s%.*s ", | 3495 | pr_cont("%s%.*s ", |
3508 | (path->ncomponents != n ? "/ " : ""), | 3496 | (path->ncomponents != n ? "/ " : ""), |
3509 | component->len, component->data); | 3497 | component->len, component->data); |
3510 | if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS) | ||
3511 | path->ncomponents++; | ||
3512 | else { | ||
3513 | dprintk("cannot parse %d components in path\n", n); | ||
3514 | goto out_eio; | ||
3515 | } | ||
3516 | } | 3498 | } |
3517 | out: | 3499 | out: |
3518 | return status; | 3500 | return status; |
@@ -3557,27 +3539,23 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3557 | n = be32_to_cpup(p); | 3539 | n = be32_to_cpup(p); |
3558 | if (n <= 0) | 3540 | if (n <= 0) |
3559 | goto out_eio; | 3541 | goto out_eio; |
3560 | res->nlocations = 0; | 3542 | for (res->nlocations = 0; res->nlocations < n; res->nlocations++) { |
3561 | while (res->nlocations < n) { | ||
3562 | u32 m; | 3543 | u32 m; |
3563 | struct nfs4_fs_location *loc = &res->locations[res->nlocations]; | 3544 | struct nfs4_fs_location *loc; |
3564 | 3545 | ||
3546 | if (res->nlocations == NFS4_FS_LOCATIONS_MAXENTRIES) | ||
3547 | break; | ||
3548 | loc = &res->locations[res->nlocations]; | ||
3565 | p = xdr_inline_decode(xdr, 4); | 3549 | p = xdr_inline_decode(xdr, 4); |
3566 | if (unlikely(!p)) | 3550 | if (unlikely(!p)) |
3567 | goto out_overflow; | 3551 | goto out_overflow; |
3568 | m = be32_to_cpup(p); | 3552 | m = be32_to_cpup(p); |
3569 | 3553 | ||
3570 | loc->nservers = 0; | ||
3571 | dprintk("%s: servers:\n", __func__); | 3554 | dprintk("%s: servers:\n", __func__); |
3572 | while (loc->nservers < m) { | 3555 | for (loc->nservers = 0; loc->nservers < m; loc->nservers++) { |
3573 | struct nfs4_string *server = &loc->servers[loc->nservers]; | 3556 | struct nfs4_string *server; |
3574 | status = decode_opaque_inline(xdr, &server->len, &server->data); | 3557 | |
3575 | if (unlikely(status != 0)) | 3558 | if (loc->nservers == NFS4_FS_LOCATION_MAXSERVERS) { |
3576 | goto out_eio; | ||
3577 | dprintk("%s ", server->data); | ||
3578 | if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS) | ||
3579 | loc->nservers++; | ||
3580 | else { | ||
3581 | unsigned int i; | 3559 | unsigned int i; |
3582 | dprintk("%s: using first %u of %u servers " | 3560 | dprintk("%s: using first %u of %u servers " |
3583 | "returned for location %u\n", | 3561 | "returned for location %u\n", |
@@ -3591,13 +3569,17 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3591 | if (unlikely(status != 0)) | 3569 | if (unlikely(status != 0)) |
3592 | goto out_eio; | 3570 | goto out_eio; |
3593 | } | 3571 | } |
3572 | break; | ||
3594 | } | 3573 | } |
3574 | server = &loc->servers[loc->nservers]; | ||
3575 | status = decode_opaque_inline(xdr, &server->len, &server->data); | ||
3576 | if (unlikely(status != 0)) | ||
3577 | goto out_eio; | ||
3578 | dprintk("%s ", server->data); | ||
3595 | } | 3579 | } |
3596 | status = decode_pathname(xdr, &loc->rootpath); | 3580 | status = decode_pathname(xdr, &loc->rootpath); |
3597 | if (unlikely(status != 0)) | 3581 | if (unlikely(status != 0)) |
3598 | goto out_eio; | 3582 | goto out_eio; |
3599 | if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES) | ||
3600 | res->nlocations++; | ||
3601 | } | 3583 | } |
3602 | if (res->nlocations != 0) | 3584 | if (res->nlocations != 0) |
3603 | status = NFS_ATTR_FATTR_V4_LOCATIONS; | 3585 | status = NFS_ATTR_FATTR_V4_LOCATIONS; |
@@ -5209,27 +5191,30 @@ static int decode_delegreturn(struct xdr_stream *xdr) | |||
5209 | return decode_op_hdr(xdr, OP_DELEGRETURN); | 5191 | return decode_op_hdr(xdr, OP_DELEGRETURN); |
5210 | } | 5192 | } |
5211 | 5193 | ||
5212 | static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor *flavor) | 5194 | static int decode_secinfo_gss(struct xdr_stream *xdr, |
5195 | struct nfs4_secinfo4 *flavor) | ||
5213 | { | 5196 | { |
5197 | u32 oid_len; | ||
5214 | __be32 *p; | 5198 | __be32 *p; |
5215 | 5199 | ||
5216 | p = xdr_inline_decode(xdr, 4); | 5200 | p = xdr_inline_decode(xdr, 4); |
5217 | if (unlikely(!p)) | 5201 | if (unlikely(!p)) |
5218 | goto out_overflow; | 5202 | goto out_overflow; |
5219 | flavor->gss.sec_oid4.len = be32_to_cpup(p); | 5203 | oid_len = be32_to_cpup(p); |
5220 | if (flavor->gss.sec_oid4.len > GSS_OID_MAX_LEN) | 5204 | if (oid_len > GSS_OID_MAX_LEN) |
5221 | goto out_err; | 5205 | goto out_err; |
5222 | 5206 | ||
5223 | p = xdr_inline_decode(xdr, flavor->gss.sec_oid4.len); | 5207 | p = xdr_inline_decode(xdr, oid_len); |
5224 | if (unlikely(!p)) | 5208 | if (unlikely(!p)) |
5225 | goto out_overflow; | 5209 | goto out_overflow; |
5226 | memcpy(flavor->gss.sec_oid4.data, p, flavor->gss.sec_oid4.len); | 5210 | memcpy(flavor->flavor_info.oid.data, p, oid_len); |
5211 | flavor->flavor_info.oid.len = oid_len; | ||
5227 | 5212 | ||
5228 | p = xdr_inline_decode(xdr, 8); | 5213 | p = xdr_inline_decode(xdr, 8); |
5229 | if (unlikely(!p)) | 5214 | if (unlikely(!p)) |
5230 | goto out_overflow; | 5215 | goto out_overflow; |
5231 | flavor->gss.qop4 = be32_to_cpup(p++); | 5216 | flavor->flavor_info.qop = be32_to_cpup(p++); |
5232 | flavor->gss.service = be32_to_cpup(p); | 5217 | flavor->flavor_info.service = be32_to_cpup(p); |
5233 | 5218 | ||
5234 | return 0; | 5219 | return 0; |
5235 | 5220 | ||
@@ -5242,10 +5227,10 @@ out_err: | |||
5242 | 5227 | ||
5243 | static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) | 5228 | static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) |
5244 | { | 5229 | { |
5245 | struct nfs4_secinfo_flavor *sec_flavor; | 5230 | struct nfs4_secinfo4 *sec_flavor; |
5231 | unsigned int i, num_flavors; | ||
5246 | int status; | 5232 | int status; |
5247 | __be32 *p; | 5233 | __be32 *p; |
5248 | int i, num_flavors; | ||
5249 | 5234 | ||
5250 | p = xdr_inline_decode(xdr, 4); | 5235 | p = xdr_inline_decode(xdr, 4); |
5251 | if (unlikely(!p)) | 5236 | if (unlikely(!p)) |
@@ -6648,8 +6633,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, | |||
6648 | * Decode SETCLIENTID_CONFIRM response | 6633 | * Decode SETCLIENTID_CONFIRM response |
6649 | */ | 6634 | */ |
6650 | static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, | 6635 | static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, |
6651 | struct xdr_stream *xdr, | 6636 | struct xdr_stream *xdr) |
6652 | struct nfs_fsinfo *fsinfo) | ||
6653 | { | 6637 | { |
6654 | struct compound_hdr hdr; | 6638 | struct compound_hdr hdr; |
6655 | int status; | 6639 | int status; |
@@ -6657,10 +6641,6 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, | |||
6657 | status = decode_compound_hdr(xdr, &hdr); | 6641 | status = decode_compound_hdr(xdr, &hdr); |
6658 | if (!status) | 6642 | if (!status) |
6659 | status = decode_setclientid_confirm(xdr); | 6643 | status = decode_setclientid_confirm(xdr); |
6660 | if (!status) | ||
6661 | status = decode_putrootfh(xdr); | ||
6662 | if (!status) | ||
6663 | status = decode_fsinfo(xdr, fsinfo); | ||
6664 | return status; | 6644 | return status; |
6665 | } | 6645 | } |
6666 | 6646 | ||
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index 88f9611a945c..5457745dd4f1 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -234,7 +234,7 @@ static int __alloc_objio_seg(unsigned numdevs, gfp_t gfp_flags, | |||
234 | 234 | ||
235 | lseg = kzalloc(lseg_size, gfp_flags); | 235 | lseg = kzalloc(lseg_size, gfp_flags); |
236 | if (unlikely(!lseg)) { | 236 | if (unlikely(!lseg)) { |
237 | dprintk("%s: Faild allocation numdevs=%d size=%zd\n", __func__, | 237 | dprintk("%s: Failed allocation numdevs=%d size=%zd\n", __func__, |
238 | numdevs, lseg_size); | 238 | numdevs, lseg_size); |
239 | return -ENOMEM; | 239 | return -ENOMEM; |
240 | } | 240 | } |
diff --git a/fs/nfs/objlayout/objlayout.h b/fs/nfs/objlayout/objlayout.h index 880ba086be94..87aa1dec6120 100644 --- a/fs/nfs/objlayout/objlayout.h +++ b/fs/nfs/objlayout/objlayout.h | |||
@@ -114,7 +114,7 @@ extern int objio_alloc_lseg(struct pnfs_layout_segment **outp, | |||
114 | gfp_t gfp_flags); | 114 | gfp_t gfp_flags); |
115 | extern void objio_free_lseg(struct pnfs_layout_segment *lseg); | 115 | extern void objio_free_lseg(struct pnfs_layout_segment *lseg); |
116 | 116 | ||
117 | /* objio_free_result will free these @oir structs recieved from | 117 | /* objio_free_result will free these @oir structs received from |
118 | * objlayout_{read,write}_done | 118 | * objlayout_{read,write}_done |
119 | */ | 119 | */ |
120 | extern void objio_free_result(struct objlayout_io_res *oir); | 120 | extern void objio_free_result(struct objlayout_io_res *oir); |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index e56e846e9d2d..29cfb7ade121 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -84,6 +84,55 @@ nfs_page_free(struct nfs_page *p) | |||
84 | kmem_cache_free(nfs_page_cachep, p); | 84 | kmem_cache_free(nfs_page_cachep, p); |
85 | } | 85 | } |
86 | 86 | ||
87 | static void | ||
88 | nfs_iocounter_inc(struct nfs_io_counter *c) | ||
89 | { | ||
90 | atomic_inc(&c->io_count); | ||
91 | } | ||
92 | |||
93 | static void | ||
94 | nfs_iocounter_dec(struct nfs_io_counter *c) | ||
95 | { | ||
96 | if (atomic_dec_and_test(&c->io_count)) { | ||
97 | clear_bit(NFS_IO_INPROGRESS, &c->flags); | ||
98 | smp_mb__after_clear_bit(); | ||
99 | wake_up_bit(&c->flags, NFS_IO_INPROGRESS); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static int | ||
104 | __nfs_iocounter_wait(struct nfs_io_counter *c) | ||
105 | { | ||
106 | wait_queue_head_t *wq = bit_waitqueue(&c->flags, NFS_IO_INPROGRESS); | ||
107 | DEFINE_WAIT_BIT(q, &c->flags, NFS_IO_INPROGRESS); | ||
108 | int ret = 0; | ||
109 | |||
110 | do { | ||
111 | prepare_to_wait(wq, &q.wait, TASK_KILLABLE); | ||
112 | set_bit(NFS_IO_INPROGRESS, &c->flags); | ||
113 | if (atomic_read(&c->io_count) == 0) | ||
114 | break; | ||
115 | ret = nfs_wait_bit_killable(&c->flags); | ||
116 | } while (atomic_read(&c->io_count) != 0); | ||
117 | finish_wait(wq, &q.wait); | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * nfs_iocounter_wait - wait for i/o to complete | ||
123 | * @c: nfs_io_counter to use | ||
124 | * | ||
125 | * returns -ERESTARTSYS if interrupted by a fatal signal. | ||
126 | * Otherwise returns 0 once the io_count hits 0. | ||
127 | */ | ||
128 | int | ||
129 | nfs_iocounter_wait(struct nfs_io_counter *c) | ||
130 | { | ||
131 | if (atomic_read(&c->io_count) == 0) | ||
132 | return 0; | ||
133 | return __nfs_iocounter_wait(c); | ||
134 | } | ||
135 | |||
87 | /** | 136 | /** |
88 | * nfs_create_request - Create an NFS read/write request. | 137 | * nfs_create_request - Create an NFS read/write request. |
89 | * @ctx: open context to use | 138 | * @ctx: open context to use |
@@ -104,6 +153,8 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode, | |||
104 | struct nfs_page *req; | 153 | struct nfs_page *req; |
105 | struct nfs_lock_context *l_ctx; | 154 | struct nfs_lock_context *l_ctx; |
106 | 155 | ||
156 | if (test_bit(NFS_CONTEXT_BAD, &ctx->flags)) | ||
157 | return ERR_PTR(-EBADF); | ||
107 | /* try to allocate the request struct */ | 158 | /* try to allocate the request struct */ |
108 | req = nfs_page_alloc(); | 159 | req = nfs_page_alloc(); |
109 | if (req == NULL) | 160 | if (req == NULL) |
@@ -116,6 +167,7 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode, | |||
116 | return ERR_CAST(l_ctx); | 167 | return ERR_CAST(l_ctx); |
117 | } | 168 | } |
118 | req->wb_lock_context = l_ctx; | 169 | req->wb_lock_context = l_ctx; |
170 | nfs_iocounter_inc(&l_ctx->io_count); | ||
119 | 171 | ||
120 | /* Initialize the request struct. Initially, we assume a | 172 | /* Initialize the request struct. Initially, we assume a |
121 | * long write-back delay. This will be adjusted in | 173 | * long write-back delay. This will be adjusted in |
@@ -175,6 +227,7 @@ static void nfs_clear_request(struct nfs_page *req) | |||
175 | req->wb_page = NULL; | 227 | req->wb_page = NULL; |
176 | } | 228 | } |
177 | if (l_ctx != NULL) { | 229 | if (l_ctx != NULL) { |
230 | nfs_iocounter_dec(&l_ctx->io_count); | ||
178 | nfs_put_lock_context(l_ctx); | 231 | nfs_put_lock_context(l_ctx); |
179 | req->wb_lock_context = NULL; | 232 | req->wb_lock_context = NULL; |
180 | } | 233 | } |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 4bdffe0ba025..c5bd758e5637 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -718,6 +718,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, | |||
718 | spin_lock(&lo->plh_inode->i_lock); | 718 | spin_lock(&lo->plh_inode->i_lock); |
719 | if (pnfs_layoutgets_blocked(lo, 1)) { | 719 | if (pnfs_layoutgets_blocked(lo, 1)) { |
720 | status = -EAGAIN; | 720 | status = -EAGAIN; |
721 | } else if (!nfs4_valid_open_stateid(open_state)) { | ||
722 | status = -EBADF; | ||
721 | } else if (list_empty(&lo->plh_segs)) { | 723 | } else if (list_empty(&lo->plh_segs)) { |
722 | int seq; | 724 | int seq; |
723 | 725 | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index a5e5d9899d56..70a26c651f09 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -514,6 +514,8 @@ void nfs_read_prepare(struct rpc_task *task, void *calldata) | |||
514 | { | 514 | { |
515 | struct nfs_read_data *data = calldata; | 515 | struct nfs_read_data *data = calldata; |
516 | NFS_PROTO(data->header->inode)->read_rpc_prepare(task, data); | 516 | NFS_PROTO(data->header->inode)->read_rpc_prepare(task, data); |
517 | if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags))) | ||
518 | rpc_exit(task, -EIO); | ||
517 | } | 519 | } |
518 | 520 | ||
519 | static const struct rpc_call_ops nfs_read_common_ops = { | 521 | static const struct rpc_call_ops nfs_read_common_ops = { |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2f8a29db0f1b..1bb071dca9ab 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -920,7 +920,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) | |||
920 | data->mount_server.port = NFS_UNSPEC_PORT; | 920 | data->mount_server.port = NFS_UNSPEC_PORT; |
921 | data->nfs_server.port = NFS_UNSPEC_PORT; | 921 | data->nfs_server.port = NFS_UNSPEC_PORT; |
922 | data->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 922 | data->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
923 | data->auth_flavors[0] = RPC_AUTH_UNIX; | 923 | data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR; |
924 | data->auth_flavor_len = 1; | 924 | data->auth_flavor_len = 1; |
925 | data->minorversion = 0; | 925 | data->minorversion = 0; |
926 | data->need_mount = true; | 926 | data->need_mount = true; |
@@ -1608,49 +1608,57 @@ out_security_failure: | |||
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | /* | 1610 | /* |
1611 | * Match the requested auth flavors with the list returned by | 1611 | * Select a security flavor for this mount. The selected flavor |
1612 | * the server. Returns zero and sets the mount's authentication | 1612 | * is planted in args->auth_flavors[0]. |
1613 | * flavor on success; returns -EACCES if server does not support | ||
1614 | * the requested flavor. | ||
1615 | */ | 1613 | */ |
1616 | static int nfs_walk_authlist(struct nfs_parsed_mount_data *args, | 1614 | static void nfs_select_flavor(struct nfs_parsed_mount_data *args, |
1617 | struct nfs_mount_request *request) | 1615 | struct nfs_mount_request *request) |
1618 | { | 1616 | { |
1619 | unsigned int i, j, server_authlist_len = *(request->auth_flav_len); | 1617 | unsigned int i, count = *(request->auth_flav_len); |
1618 | rpc_authflavor_t flavor; | ||
1619 | |||
1620 | if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) | ||
1621 | goto out; | ||
1622 | |||
1623 | /* | ||
1624 | * The NFSv2 MNT operation does not return a flavor list. | ||
1625 | */ | ||
1626 | if (args->mount_server.version != NFS_MNT3_VERSION) | ||
1627 | goto out_default; | ||
1620 | 1628 | ||
1621 | /* | 1629 | /* |
1622 | * Certain releases of Linux's mountd return an empty | 1630 | * Certain releases of Linux's mountd return an empty |
1623 | * flavor list. To prevent behavioral regression with | 1631 | * flavor list in some cases. |
1624 | * these servers (ie. rejecting mounts that used to | ||
1625 | * succeed), revert to pre-2.6.32 behavior (no checking) | ||
1626 | * if the returned flavor list is empty. | ||
1627 | */ | 1632 | */ |
1628 | if (server_authlist_len == 0) | 1633 | if (count == 0) |
1629 | return 0; | 1634 | goto out_default; |
1630 | 1635 | ||
1631 | /* | 1636 | /* |
1632 | * We avoid sophisticated negotiating here, as there are | ||
1633 | * plenty of cases where we can get it wrong, providing | ||
1634 | * either too little or too much security. | ||
1635 | * | ||
1636 | * RFC 2623, section 2.7 suggests we SHOULD prefer the | 1637 | * RFC 2623, section 2.7 suggests we SHOULD prefer the |
1637 | * flavor listed first. However, some servers list | 1638 | * flavor listed first. However, some servers list |
1638 | * AUTH_NULL first. Our caller plants AUTH_SYS, the | 1639 | * AUTH_NULL first. Avoid ever choosing AUTH_NULL. |
1639 | * preferred default, in args->auth_flavors[0] if user | ||
1640 | * didn't specify sec= mount option. | ||
1641 | */ | 1640 | */ |
1642 | for (i = 0; i < args->auth_flavor_len; i++) | 1641 | for (i = 0; i < count; i++) { |
1643 | for (j = 0; j < server_authlist_len; j++) | 1642 | struct rpcsec_gss_info info; |
1644 | if (args->auth_flavors[i] == request->auth_flavs[j]) { | 1643 | |
1645 | dfprintk(MOUNT, "NFS: using auth flavor %d\n", | 1644 | flavor = request->auth_flavs[i]; |
1646 | request->auth_flavs[j]); | 1645 | switch (flavor) { |
1647 | args->auth_flavors[0] = request->auth_flavs[j]; | 1646 | case RPC_AUTH_UNIX: |
1648 | return 0; | 1647 | goto out_set; |
1649 | } | 1648 | case RPC_AUTH_NULL: |
1649 | continue; | ||
1650 | default: | ||
1651 | if (rpcauth_get_gssinfo(flavor, &info) == 0) | ||
1652 | goto out_set; | ||
1653 | } | ||
1654 | } | ||
1650 | 1655 | ||
1651 | dfprintk(MOUNT, "NFS: server does not support requested auth flavor\n"); | 1656 | out_default: |
1652 | nfs_umount(request); | 1657 | flavor = RPC_AUTH_UNIX; |
1653 | return -EACCES; | 1658 | out_set: |
1659 | args->auth_flavors[0] = flavor; | ||
1660 | out: | ||
1661 | dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]); | ||
1654 | } | 1662 | } |
1655 | 1663 | ||
1656 | /* | 1664 | /* |
@@ -1713,12 +1721,8 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args, | |||
1713 | return status; | 1721 | return status; |
1714 | } | 1722 | } |
1715 | 1723 | ||
1716 | /* | 1724 | nfs_select_flavor(args, &request); |
1717 | * MNTv1 (NFSv2) does not support auth flavor negotiation. | 1725 | return 0; |
1718 | */ | ||
1719 | if (args->mount_server.version != NFS_MNT3_VERSION) | ||
1720 | return 0; | ||
1721 | return nfs_walk_authlist(args, &request); | ||
1722 | } | 1726 | } |
1723 | 1727 | ||
1724 | struct dentry *nfs_try_mount(int flags, const char *dev_name, | 1728 | struct dentry *nfs_try_mount(int flags, const char *dev_name, |
@@ -2381,10 +2385,9 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, | |||
2381 | struct nfs_mount_info *mount_info) | 2385 | struct nfs_mount_info *mount_info) |
2382 | { | 2386 | { |
2383 | /* clone any lsm security options from the parent to the new sb */ | 2387 | /* clone any lsm security options from the parent to the new sb */ |
2384 | security_sb_clone_mnt_opts(mount_info->cloned->sb, s); | ||
2385 | if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) | 2388 | if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) |
2386 | return -ESTALE; | 2389 | return -ESTALE; |
2387 | return 0; | 2390 | return security_sb_clone_mnt_opts(mount_info->cloned->sb, s); |
2388 | } | 2391 | } |
2389 | EXPORT_SYMBOL_GPL(nfs_clone_sb_security); | 2392 | EXPORT_SYMBOL_GPL(nfs_clone_sb_security); |
2390 | 2393 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index c483cc50b82e..a2c7c28049d5 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1251,6 +1251,8 @@ void nfs_write_prepare(struct rpc_task *task, void *calldata) | |||
1251 | { | 1251 | { |
1252 | struct nfs_write_data *data = calldata; | 1252 | struct nfs_write_data *data = calldata; |
1253 | NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data); | 1253 | NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data); |
1254 | if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags))) | ||
1255 | rpc_exit(task, -EIO); | ||
1254 | } | 1256 | } |
1255 | 1257 | ||
1256 | void nfs_commit_prepare(struct rpc_task *task, void *calldata) | 1258 | void nfs_commit_prepare(struct rpc_task *task, void *calldata) |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2e27430b9070..417c84877742 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -234,7 +234,6 @@ static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct | |||
234 | kmem_cache *slab) | 234 | kmem_cache *slab) |
235 | { | 235 | { |
236 | struct idr *stateids = &cl->cl_stateids; | 236 | struct idr *stateids = &cl->cl_stateids; |
237 | static int min_stateid = 0; | ||
238 | struct nfs4_stid *stid; | 237 | struct nfs4_stid *stid; |
239 | int new_id; | 238 | int new_id; |
240 | 239 | ||
@@ -242,7 +241,7 @@ kmem_cache *slab) | |||
242 | if (!stid) | 241 | if (!stid) |
243 | return NULL; | 242 | return NULL; |
244 | 243 | ||
245 | new_id = idr_alloc(stateids, stid, min_stateid, 0, GFP_KERNEL); | 244 | new_id = idr_alloc_cyclic(stateids, stid, 0, 0, GFP_KERNEL); |
246 | if (new_id < 0) | 245 | if (new_id < 0) |
247 | goto out_free; | 246 | goto out_free; |
248 | stid->sc_client = cl; | 247 | stid->sc_client = cl; |
@@ -261,10 +260,6 @@ kmem_cache *slab) | |||
261 | * amount of time until an id is reused, by ensuring they always | 260 | * amount of time until an id is reused, by ensuring they always |
262 | * "increase" (mod INT_MAX): | 261 | * "increase" (mod INT_MAX): |
263 | */ | 262 | */ |
264 | |||
265 | min_stateid = new_id+1; | ||
266 | if (min_stateid == INT_MAX) | ||
267 | min_stateid = 0; | ||
268 | return stid; | 263 | return stid; |
269 | out_free: | 264 | out_free: |
270 | kfree(stid); | 265 | kfree(stid); |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 01168865dd37..2502951714b1 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -264,7 +264,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, | |||
264 | iattr->ia_valid |= ATTR_SIZE; | 264 | iattr->ia_valid |= ATTR_SIZE; |
265 | } | 265 | } |
266 | if (bmval[0] & FATTR4_WORD0_ACL) { | 266 | if (bmval[0] & FATTR4_WORD0_ACL) { |
267 | int nace; | 267 | u32 nace; |
268 | struct nfs4_ace *ace; | 268 | struct nfs4_ace *ace; |
269 | 269 | ||
270 | READ_BUF(4); len += 4; | 270 | READ_BUF(4); len += 4; |
@@ -3138,10 +3138,9 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ | |||
3138 | 3138 | ||
3139 | static __be32 | 3139 | static __be32 |
3140 | nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, | 3140 | nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, |
3141 | __be32 nfserr,struct svc_export *exp) | 3141 | __be32 nfserr, struct svc_export *exp) |
3142 | { | 3142 | { |
3143 | int i = 0; | 3143 | u32 i, nflavs; |
3144 | u32 nflavs; | ||
3145 | struct exp_flavor_info *flavs; | 3144 | struct exp_flavor_info *flavs; |
3146 | struct exp_flavor_info def_flavs[2]; | 3145 | struct exp_flavor_info def_flavs[2]; |
3147 | __be32 *p; | 3146 | __be32 *p; |
@@ -3172,30 +3171,29 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, | |||
3172 | WRITE32(nflavs); | 3171 | WRITE32(nflavs); |
3173 | ADJUST_ARGS(); | 3172 | ADJUST_ARGS(); |
3174 | for (i = 0; i < nflavs; i++) { | 3173 | for (i = 0; i < nflavs; i++) { |
3175 | u32 flav = flavs[i].pseudoflavor; | 3174 | struct rpcsec_gss_info info; |
3176 | struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav); | ||
3177 | 3175 | ||
3178 | if (gm) { | 3176 | if (rpcauth_get_gssinfo(flavs[i].pseudoflavor, &info) == 0) { |
3179 | RESERVE_SPACE(4); | 3177 | RESERVE_SPACE(4); |
3180 | WRITE32(RPC_AUTH_GSS); | 3178 | WRITE32(RPC_AUTH_GSS); |
3181 | ADJUST_ARGS(); | 3179 | ADJUST_ARGS(); |
3182 | RESERVE_SPACE(4 + gm->gm_oid.len); | 3180 | RESERVE_SPACE(4 + info.oid.len); |
3183 | WRITE32(gm->gm_oid.len); | 3181 | WRITE32(info.oid.len); |
3184 | WRITEMEM(gm->gm_oid.data, gm->gm_oid.len); | 3182 | WRITEMEM(info.oid.data, info.oid.len); |
3185 | ADJUST_ARGS(); | 3183 | ADJUST_ARGS(); |
3186 | RESERVE_SPACE(4); | 3184 | RESERVE_SPACE(4); |
3187 | WRITE32(0); /* qop */ | 3185 | WRITE32(info.qop); |
3188 | ADJUST_ARGS(); | 3186 | ADJUST_ARGS(); |
3189 | RESERVE_SPACE(4); | 3187 | RESERVE_SPACE(4); |
3190 | WRITE32(gss_pseudoflavor_to_service(gm, flav)); | 3188 | WRITE32(info.service); |
3191 | ADJUST_ARGS(); | 3189 | ADJUST_ARGS(); |
3192 | gss_mech_put(gm); | ||
3193 | } else { | 3190 | } else { |
3194 | RESERVE_SPACE(4); | 3191 | RESERVE_SPACE(4); |
3195 | WRITE32(flav); | 3192 | WRITE32(flavs[i].pseudoflavor); |
3196 | ADJUST_ARGS(); | 3193 | ADJUST_ARGS(); |
3197 | } | 3194 | } |
3198 | } | 3195 | } |
3196 | |||
3199 | out: | 3197 | out: |
3200 | if (exp) | 3198 | if (exp) |
3201 | exp_put(exp); | 3199 | exp_put(exp); |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 6b49f14eac8c..cf02f5530713 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -175,6 +175,11 @@ static int nilfs_writepages(struct address_space *mapping, | |||
175 | struct inode *inode = mapping->host; | 175 | struct inode *inode = mapping->host; |
176 | int err = 0; | 176 | int err = 0; |
177 | 177 | ||
178 | if (inode->i_sb->s_flags & MS_RDONLY) { | ||
179 | nilfs_clear_dirty_pages(mapping, false); | ||
180 | return -EROFS; | ||
181 | } | ||
182 | |||
178 | if (wbc->sync_mode == WB_SYNC_ALL) | 183 | if (wbc->sync_mode == WB_SYNC_ALL) |
179 | err = nilfs_construct_dsync_segment(inode->i_sb, inode, | 184 | err = nilfs_construct_dsync_segment(inode->i_sb, inode, |
180 | wbc->range_start, | 185 | wbc->range_start, |
@@ -187,6 +192,18 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc) | |||
187 | struct inode *inode = page->mapping->host; | 192 | struct inode *inode = page->mapping->host; |
188 | int err; | 193 | int err; |
189 | 194 | ||
195 | if (inode->i_sb->s_flags & MS_RDONLY) { | ||
196 | /* | ||
197 | * It means that filesystem was remounted in read-only | ||
198 | * mode because of error or metadata corruption. But we | ||
199 | * have dirty pages that try to be flushed in background. | ||
200 | * So, here we simply discard this dirty page. | ||
201 | */ | ||
202 | nilfs_clear_dirty_page(page, false); | ||
203 | unlock_page(page); | ||
204 | return -EROFS; | ||
205 | } | ||
206 | |||
190 | redirty_page_for_writepage(wbc, page); | 207 | redirty_page_for_writepage(wbc, page); |
191 | unlock_page(page); | 208 | unlock_page(page); |
192 | 209 | ||
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index f9897d09c693..c4dcd1db57ee 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -375,14 +375,25 @@ int nilfs_mdt_fetch_dirty(struct inode *inode) | |||
375 | static int | 375 | static int |
376 | nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | 376 | nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) |
377 | { | 377 | { |
378 | struct inode *inode; | 378 | struct inode *inode = page->mapping->host; |
379 | struct super_block *sb; | 379 | struct super_block *sb; |
380 | int err = 0; | 380 | int err = 0; |
381 | 381 | ||
382 | if (inode && (inode->i_sb->s_flags & MS_RDONLY)) { | ||
383 | /* | ||
384 | * It means that filesystem was remounted in read-only | ||
385 | * mode because of error or metadata corruption. But we | ||
386 | * have dirty pages that try to be flushed in background. | ||
387 | * So, here we simply discard this dirty page. | ||
388 | */ | ||
389 | nilfs_clear_dirty_page(page, false); | ||
390 | unlock_page(page); | ||
391 | return -EROFS; | ||
392 | } | ||
393 | |||
382 | redirty_page_for_writepage(wbc, page); | 394 | redirty_page_for_writepage(wbc, page); |
383 | unlock_page(page); | 395 | unlock_page(page); |
384 | 396 | ||
385 | inode = page->mapping->host; | ||
386 | if (!inode) | 397 | if (!inode) |
387 | return 0; | 398 | return 0; |
388 | 399 | ||
@@ -561,10 +572,10 @@ void nilfs_mdt_restore_from_shadow_map(struct inode *inode) | |||
561 | if (mi->mi_palloc_cache) | 572 | if (mi->mi_palloc_cache) |
562 | nilfs_palloc_clear_cache(inode); | 573 | nilfs_palloc_clear_cache(inode); |
563 | 574 | ||
564 | nilfs_clear_dirty_pages(inode->i_mapping); | 575 | nilfs_clear_dirty_pages(inode->i_mapping, true); |
565 | nilfs_copy_back_pages(inode->i_mapping, &shadow->frozen_data); | 576 | nilfs_copy_back_pages(inode->i_mapping, &shadow->frozen_data); |
566 | 577 | ||
567 | nilfs_clear_dirty_pages(&ii->i_btnode_cache); | 578 | nilfs_clear_dirty_pages(&ii->i_btnode_cache, true); |
568 | nilfs_copy_back_pages(&ii->i_btnode_cache, &shadow->frozen_btnodes); | 579 | nilfs_copy_back_pages(&ii->i_btnode_cache, &shadow->frozen_btnodes); |
569 | 580 | ||
570 | nilfs_bmap_restore(ii->i_bmap, &shadow->bmap_store); | 581 | nilfs_bmap_restore(ii->i_bmap, &shadow->bmap_store); |
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index 07f76db04ec7..0ba679866e50 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c | |||
@@ -370,7 +370,12 @@ repeat: | |||
370 | goto repeat; | 370 | goto repeat; |
371 | } | 371 | } |
372 | 372 | ||
373 | void nilfs_clear_dirty_pages(struct address_space *mapping) | 373 | /** |
374 | * nilfs_clear_dirty_pages - discard dirty pages in address space | ||
375 | * @mapping: address space with dirty pages for discarding | ||
376 | * @silent: suppress [true] or print [false] warning messages | ||
377 | */ | ||
378 | void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent) | ||
374 | { | 379 | { |
375 | struct pagevec pvec; | 380 | struct pagevec pvec; |
376 | unsigned int i; | 381 | unsigned int i; |
@@ -382,25 +387,9 @@ void nilfs_clear_dirty_pages(struct address_space *mapping) | |||
382 | PAGEVEC_SIZE)) { | 387 | PAGEVEC_SIZE)) { |
383 | for (i = 0; i < pagevec_count(&pvec); i++) { | 388 | for (i = 0; i < pagevec_count(&pvec); i++) { |
384 | struct page *page = pvec.pages[i]; | 389 | struct page *page = pvec.pages[i]; |
385 | struct buffer_head *bh, *head; | ||
386 | 390 | ||
387 | lock_page(page); | 391 | lock_page(page); |
388 | ClearPageUptodate(page); | 392 | nilfs_clear_dirty_page(page, silent); |
389 | ClearPageMappedToDisk(page); | ||
390 | bh = head = page_buffers(page); | ||
391 | do { | ||
392 | lock_buffer(bh); | ||
393 | clear_buffer_dirty(bh); | ||
394 | clear_buffer_nilfs_volatile(bh); | ||
395 | clear_buffer_nilfs_checked(bh); | ||
396 | clear_buffer_nilfs_redirected(bh); | ||
397 | clear_buffer_uptodate(bh); | ||
398 | clear_buffer_mapped(bh); | ||
399 | unlock_buffer(bh); | ||
400 | bh = bh->b_this_page; | ||
401 | } while (bh != head); | ||
402 | |||
403 | __nilfs_clear_page_dirty(page); | ||
404 | unlock_page(page); | 393 | unlock_page(page); |
405 | } | 394 | } |
406 | pagevec_release(&pvec); | 395 | pagevec_release(&pvec); |
@@ -408,6 +397,51 @@ void nilfs_clear_dirty_pages(struct address_space *mapping) | |||
408 | } | 397 | } |
409 | } | 398 | } |
410 | 399 | ||
400 | /** | ||
401 | * nilfs_clear_dirty_page - discard dirty page | ||
402 | * @page: dirty page that will be discarded | ||
403 | * @silent: suppress [true] or print [false] warning messages | ||
404 | */ | ||
405 | void nilfs_clear_dirty_page(struct page *page, bool silent) | ||
406 | { | ||
407 | struct inode *inode = page->mapping->host; | ||
408 | struct super_block *sb = inode->i_sb; | ||
409 | |||
410 | BUG_ON(!PageLocked(page)); | ||
411 | |||
412 | if (!silent) { | ||
413 | nilfs_warning(sb, __func__, | ||
414 | "discard page: offset %lld, ino %lu", | ||
415 | page_offset(page), inode->i_ino); | ||
416 | } | ||
417 | |||
418 | ClearPageUptodate(page); | ||
419 | ClearPageMappedToDisk(page); | ||
420 | |||
421 | if (page_has_buffers(page)) { | ||
422 | struct buffer_head *bh, *head; | ||
423 | |||
424 | bh = head = page_buffers(page); | ||
425 | do { | ||
426 | lock_buffer(bh); | ||
427 | if (!silent) { | ||
428 | nilfs_warning(sb, __func__, | ||
429 | "discard block %llu, size %zu", | ||
430 | (u64)bh->b_blocknr, bh->b_size); | ||
431 | } | ||
432 | clear_buffer_dirty(bh); | ||
433 | clear_buffer_nilfs_volatile(bh); | ||
434 | clear_buffer_nilfs_checked(bh); | ||
435 | clear_buffer_nilfs_redirected(bh); | ||
436 | clear_buffer_uptodate(bh); | ||
437 | clear_buffer_mapped(bh); | ||
438 | unlock_buffer(bh); | ||
439 | } while (bh = bh->b_this_page, bh != head); | ||
440 | } | ||
441 | |||
442 | __nilfs_clear_page_dirty(page); | ||
443 | } | ||
444 | |||
411 | unsigned nilfs_page_count_clean_buffers(struct page *page, | 445 | unsigned nilfs_page_count_clean_buffers(struct page *page, |
412 | unsigned from, unsigned to) | 446 | unsigned from, unsigned to) |
413 | { | 447 | { |
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h index fb7de71605a0..ef30c5c2426f 100644 --- a/fs/nilfs2/page.h +++ b/fs/nilfs2/page.h | |||
@@ -55,7 +55,8 @@ void nilfs_page_bug(struct page *); | |||
55 | 55 | ||
56 | int nilfs_copy_dirty_pages(struct address_space *, struct address_space *); | 56 | int nilfs_copy_dirty_pages(struct address_space *, struct address_space *); |
57 | void nilfs_copy_back_pages(struct address_space *, struct address_space *); | 57 | void nilfs_copy_back_pages(struct address_space *, struct address_space *); |
58 | void nilfs_clear_dirty_pages(struct address_space *); | 58 | void nilfs_clear_dirty_page(struct page *, bool); |
59 | void nilfs_clear_dirty_pages(struct address_space *, bool); | ||
59 | void nilfs_mapping_init(struct address_space *mapping, struct inode *inode, | 60 | void nilfs_mapping_init(struct address_space *mapping, struct inode *inode, |
60 | struct backing_dev_info *bdi); | 61 | struct backing_dev_info *bdi); |
61 | unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); | 62 | unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 5d8444268a16..d0be29fa94cf 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -755,9 +755,9 @@ out_destroy_group: | |||
755 | return fd; | 755 | return fd; |
756 | } | 756 | } |
757 | 757 | ||
758 | SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | 758 | SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags, |
759 | __u64 mask, int dfd, | 759 | __u64, mask, int, dfd, |
760 | const char __user * pathname) | 760 | const char __user *, pathname) |
761 | { | 761 | { |
762 | struct inode *inode = NULL; | 762 | struct inode *inode = NULL; |
763 | struct vfsmount *mnt = NULL; | 763 | struct vfsmount *mnt = NULL; |
@@ -857,17 +857,6 @@ fput_and_out: | |||
857 | return ret; | 857 | return ret; |
858 | } | 858 | } |
859 | 859 | ||
860 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
861 | asmlinkage long SyS_fanotify_mark(long fanotify_fd, long flags, __u64 mask, | ||
862 | long dfd, long pathname) | ||
863 | { | ||
864 | return SYSC_fanotify_mark((int) fanotify_fd, (unsigned int) flags, | ||
865 | mask, (int) dfd, | ||
866 | (const char __user *) pathname); | ||
867 | } | ||
868 | SYSCALL_ALIAS(sys_fanotify_mark, SyS_fanotify_mark); | ||
869 | #endif | ||
870 | |||
871 | /* | 860 | /* |
872 | * fanotify_user_setup - Our initialization function. Note that we cannot return | 861 | * fanotify_user_setup - Our initialization function. Note that we cannot return |
873 | * error because we have compiled-in VFS hooks. So an (unlikely) failure here | 862 | * error because we have compiled-in VFS hooks. So an (unlikely) failure here |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index e0f7c1241a6a..c616a70e8cf9 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -359,7 +359,6 @@ static int inotify_find_inode(const char __user *dirname, struct path *path, uns | |||
359 | } | 359 | } |
360 | 360 | ||
361 | static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock, | 361 | static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock, |
362 | int *last_wd, | ||
363 | struct inotify_inode_mark *i_mark) | 362 | struct inotify_inode_mark *i_mark) |
364 | { | 363 | { |
365 | int ret; | 364 | int ret; |
@@ -367,11 +366,10 @@ static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock, | |||
367 | idr_preload(GFP_KERNEL); | 366 | idr_preload(GFP_KERNEL); |
368 | spin_lock(idr_lock); | 367 | spin_lock(idr_lock); |
369 | 368 | ||
370 | ret = idr_alloc(idr, i_mark, *last_wd + 1, 0, GFP_NOWAIT); | 369 | ret = idr_alloc_cyclic(idr, i_mark, 1, 0, GFP_NOWAIT); |
371 | if (ret >= 0) { | 370 | if (ret >= 0) { |
372 | /* we added the mark to the idr, take a reference */ | 371 | /* we added the mark to the idr, take a reference */ |
373 | i_mark->wd = ret; | 372 | i_mark->wd = ret; |
374 | *last_wd = i_mark->wd; | ||
375 | fsnotify_get_mark(&i_mark->fsn_mark); | 373 | fsnotify_get_mark(&i_mark->fsn_mark); |
376 | } | 374 | } |
377 | 375 | ||
@@ -572,7 +570,6 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, | |||
572 | int add = (arg & IN_MASK_ADD); | 570 | int add = (arg & IN_MASK_ADD); |
573 | int ret; | 571 | int ret; |
574 | 572 | ||
575 | /* don't allow invalid bits: we don't want flags set */ | ||
576 | mask = inotify_arg_to_mask(arg); | 573 | mask = inotify_arg_to_mask(arg); |
577 | 574 | ||
578 | fsn_mark = fsnotify_find_inode_mark(group, inode); | 575 | fsn_mark = fsnotify_find_inode_mark(group, inode); |
@@ -623,7 +620,6 @@ static int inotify_new_watch(struct fsnotify_group *group, | |||
623 | struct idr *idr = &group->inotify_data.idr; | 620 | struct idr *idr = &group->inotify_data.idr; |
624 | spinlock_t *idr_lock = &group->inotify_data.idr_lock; | 621 | spinlock_t *idr_lock = &group->inotify_data.idr_lock; |
625 | 622 | ||
626 | /* don't allow invalid bits: we don't want flags set */ | ||
627 | mask = inotify_arg_to_mask(arg); | 623 | mask = inotify_arg_to_mask(arg); |
628 | 624 | ||
629 | tmp_i_mark = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL); | 625 | tmp_i_mark = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL); |
@@ -638,8 +634,7 @@ static int inotify_new_watch(struct fsnotify_group *group, | |||
638 | if (atomic_read(&group->inotify_data.user->inotify_watches) >= inotify_max_user_watches) | 634 | if (atomic_read(&group->inotify_data.user->inotify_watches) >= inotify_max_user_watches) |
639 | goto out_err; | 635 | goto out_err; |
640 | 636 | ||
641 | ret = inotify_add_to_idr(idr, idr_lock, &group->inotify_data.last_wd, | 637 | ret = inotify_add_to_idr(idr, idr_lock, tmp_i_mark); |
642 | tmp_i_mark); | ||
643 | if (ret) | 638 | if (ret) |
644 | goto out_err; | 639 | goto out_err; |
645 | 640 | ||
@@ -697,7 +692,6 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events) | |||
697 | 692 | ||
698 | spin_lock_init(&group->inotify_data.idr_lock); | 693 | spin_lock_init(&group->inotify_data.idr_lock); |
699 | idr_init(&group->inotify_data.idr); | 694 | idr_init(&group->inotify_data.idr); |
700 | group->inotify_data.last_wd = 0; | ||
701 | group->inotify_data.user = get_current_user(); | 695 | group->inotify_data.user = get_current_user(); |
702 | 696 | ||
703 | if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > | 697 | if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > |
@@ -751,6 +745,10 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, | |||
751 | int ret; | 745 | int ret; |
752 | unsigned flags = 0; | 746 | unsigned flags = 0; |
753 | 747 | ||
748 | /* don't allow invalid bits: we don't want flags set */ | ||
749 | if (unlikely(!(mask & ALL_INOTIFY_BITS))) | ||
750 | return -EINVAL; | ||
751 | |||
754 | f = fdget(fd); | 752 | f = fdget(fd); |
755 | if (unlikely(!f.file)) | 753 | if (unlikely(!f.file)) |
756 | return -EBADF; | 754 | return -EBADF; |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index eeac97bb3bfa..b3fdd1a323d6 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -1498,10 +1498,8 @@ leave: | |||
1498 | 1498 | ||
1499 | dlm_put(dlm); | 1499 | dlm_put(dlm); |
1500 | if (ret < 0) { | 1500 | if (ret < 0) { |
1501 | if (buf) | 1501 | kfree(buf); |
1502 | kfree(buf); | 1502 | kfree(item); |
1503 | if (item) | ||
1504 | kfree(item); | ||
1505 | mlog_errno(ret); | 1503 | mlog_errno(ret); |
1506 | } | 1504 | } |
1507 | 1505 | ||
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 752f0b26221d..0c60ef2d8056 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -101,13 +101,6 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
101 | if (!S_ISDIR(inode->i_mode)) | 101 | if (!S_ISDIR(inode->i_mode)) |
102 | flags &= ~OCFS2_DIRSYNC_FL; | 102 | flags &= ~OCFS2_DIRSYNC_FL; |
103 | 103 | ||
104 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
105 | if (IS_ERR(handle)) { | ||
106 | status = PTR_ERR(handle); | ||
107 | mlog_errno(status); | ||
108 | goto bail_unlock; | ||
109 | } | ||
110 | |||
111 | oldflags = ocfs2_inode->ip_attr; | 104 | oldflags = ocfs2_inode->ip_attr; |
112 | flags = flags & mask; | 105 | flags = flags & mask; |
113 | flags |= oldflags & ~mask; | 106 | flags |= oldflags & ~mask; |
@@ -120,7 +113,14 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
120 | if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) & | 113 | if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) & |
121 | (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) { | 114 | (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) { |
122 | if (!capable(CAP_LINUX_IMMUTABLE)) | 115 | if (!capable(CAP_LINUX_IMMUTABLE)) |
123 | goto bail_commit; | 116 | goto bail_unlock; |
117 | } | ||
118 | |||
119 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
120 | if (IS_ERR(handle)) { | ||
121 | status = PTR_ERR(handle); | ||
122 | mlog_errno(status); | ||
123 | goto bail_unlock; | ||
124 | } | 124 | } |
125 | 125 | ||
126 | ocfs2_inode->ip_attr = flags; | 126 | ocfs2_inode->ip_attr = flags; |
@@ -130,8 +130,8 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
130 | if (status < 0) | 130 | if (status < 0) |
131 | mlog_errno(status); | 131 | mlog_errno(status); |
132 | 132 | ||
133 | bail_commit: | ||
134 | ocfs2_commit_trans(osb, handle); | 133 | ocfs2_commit_trans(osb, handle); |
134 | |||
135 | bail_unlock: | 135 | bail_unlock: |
136 | ocfs2_inode_unlock(inode, 1); | 136 | ocfs2_inode_unlock(inode, 1); |
137 | bail: | 137 | bail: |
@@ -706,8 +706,10 @@ int ocfs2_info_handle_freefrag(struct inode *inode, | |||
706 | 706 | ||
707 | o2info_set_request_filled(&oiff->iff_req); | 707 | o2info_set_request_filled(&oiff->iff_req); |
708 | 708 | ||
709 | if (o2info_to_user(*oiff, req)) | 709 | if (o2info_to_user(*oiff, req)) { |
710 | status = -EFAULT; | ||
710 | goto bail; | 711 | goto bail; |
712 | } | ||
711 | 713 | ||
712 | status = 0; | 714 | status = 0; |
713 | bail: | 715 | bail: |
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index 9f8dcadd9a50..f1fc172175b6 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c | |||
@@ -471,7 +471,7 @@ static int ocfs2_validate_and_adjust_move_goal(struct inode *inode, | |||
471 | int ret, goal_bit = 0; | 471 | int ret, goal_bit = 0; |
472 | 472 | ||
473 | struct buffer_head *gd_bh = NULL; | 473 | struct buffer_head *gd_bh = NULL; |
474 | struct ocfs2_group_desc *bg = NULL; | 474 | struct ocfs2_group_desc *bg; |
475 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 475 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
476 | int c_to_b = 1 << (osb->s_clustersize_bits - | 476 | int c_to_b = 1 << (osb->s_clustersize_bits - |
477 | inode->i_sb->s_blocksize_bits); | 477 | inode->i_sb->s_blocksize_bits); |
@@ -482,13 +482,6 @@ static int ocfs2_validate_and_adjust_move_goal(struct inode *inode, | |||
482 | range->me_goal = ocfs2_block_to_cluster_start(inode->i_sb, | 482 | range->me_goal = ocfs2_block_to_cluster_start(inode->i_sb, |
483 | range->me_goal); | 483 | range->me_goal); |
484 | /* | 484 | /* |
485 | * moving goal is not allowd to start with a group desc blok(#0 blk) | ||
486 | * let's compromise to the latter cluster. | ||
487 | */ | ||
488 | if (range->me_goal == le64_to_cpu(bg->bg_blkno)) | ||
489 | range->me_goal += c_to_b; | ||
490 | |||
491 | /* | ||
492 | * validate goal sits within global_bitmap, and return the victim | 485 | * validate goal sits within global_bitmap, and return the victim |
493 | * group desc | 486 | * group desc |
494 | */ | 487 | */ |
@@ -502,6 +495,13 @@ static int ocfs2_validate_and_adjust_move_goal(struct inode *inode, | |||
502 | bg = (struct ocfs2_group_desc *)gd_bh->b_data; | 495 | bg = (struct ocfs2_group_desc *)gd_bh->b_data; |
503 | 496 | ||
504 | /* | 497 | /* |
498 | * moving goal is not allowd to start with a group desc blok(#0 blk) | ||
499 | * let's compromise to the latter cluster. | ||
500 | */ | ||
501 | if (range->me_goal == le64_to_cpu(bg->bg_blkno)) | ||
502 | range->me_goal += c_to_b; | ||
503 | |||
504 | /* | ||
505 | * movement is not gonna cross two groups. | 505 | * movement is not gonna cross two groups. |
506 | */ | 506 | */ |
507 | if ((le16_to_cpu(bg->bg_bits) - goal_bit) * osb->s_clustersize < | 507 | if ((le16_to_cpu(bg->bg_bits) - goal_bit) * osb->s_clustersize < |
@@ -1057,42 +1057,40 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp) | |||
1057 | 1057 | ||
1058 | struct inode *inode = file_inode(filp); | 1058 | struct inode *inode = file_inode(filp); |
1059 | struct ocfs2_move_extents range; | 1059 | struct ocfs2_move_extents range; |
1060 | struct ocfs2_move_extents_context *context = NULL; | 1060 | struct ocfs2_move_extents_context *context; |
1061 | |||
1062 | if (!argp) | ||
1063 | return -EINVAL; | ||
1061 | 1064 | ||
1062 | status = mnt_want_write_file(filp); | 1065 | status = mnt_want_write_file(filp); |
1063 | if (status) | 1066 | if (status) |
1064 | return status; | 1067 | return status; |
1065 | 1068 | ||
1066 | if ((!S_ISREG(inode->i_mode)) || !(filp->f_mode & FMODE_WRITE)) | 1069 | if ((!S_ISREG(inode->i_mode)) || !(filp->f_mode & FMODE_WRITE)) |
1067 | goto out; | 1070 | goto out_drop; |
1068 | 1071 | ||
1069 | if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) { | 1072 | if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) { |
1070 | status = -EPERM; | 1073 | status = -EPERM; |
1071 | goto out; | 1074 | goto out_drop; |
1072 | } | 1075 | } |
1073 | 1076 | ||
1074 | context = kzalloc(sizeof(struct ocfs2_move_extents_context), GFP_NOFS); | 1077 | context = kzalloc(sizeof(struct ocfs2_move_extents_context), GFP_NOFS); |
1075 | if (!context) { | 1078 | if (!context) { |
1076 | status = -ENOMEM; | 1079 | status = -ENOMEM; |
1077 | mlog_errno(status); | 1080 | mlog_errno(status); |
1078 | goto out; | 1081 | goto out_drop; |
1079 | } | 1082 | } |
1080 | 1083 | ||
1081 | context->inode = inode; | 1084 | context->inode = inode; |
1082 | context->file = filp; | 1085 | context->file = filp; |
1083 | 1086 | ||
1084 | if (argp) { | 1087 | if (copy_from_user(&range, argp, sizeof(range))) { |
1085 | if (copy_from_user(&range, argp, sizeof(range))) { | 1088 | status = -EFAULT; |
1086 | status = -EFAULT; | 1089 | goto out_free; |
1087 | goto out; | ||
1088 | } | ||
1089 | } else { | ||
1090 | status = -EINVAL; | ||
1091 | goto out; | ||
1092 | } | 1090 | } |
1093 | 1091 | ||
1094 | if (range.me_start > i_size_read(inode)) | 1092 | if (range.me_start > i_size_read(inode)) |
1095 | goto out; | 1093 | goto out_free; |
1096 | 1094 | ||
1097 | if (range.me_start + range.me_len > i_size_read(inode)) | 1095 | if (range.me_start + range.me_len > i_size_read(inode)) |
1098 | range.me_len = i_size_read(inode) - range.me_start; | 1096 | range.me_len = i_size_read(inode) - range.me_start; |
@@ -1124,25 +1122,24 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp) | |||
1124 | 1122 | ||
1125 | status = ocfs2_validate_and_adjust_move_goal(inode, &range); | 1123 | status = ocfs2_validate_and_adjust_move_goal(inode, &range); |
1126 | if (status) | 1124 | if (status) |
1127 | goto out; | 1125 | goto out_copy; |
1128 | } | 1126 | } |
1129 | 1127 | ||
1130 | status = ocfs2_move_extents(context); | 1128 | status = ocfs2_move_extents(context); |
1131 | if (status) | 1129 | if (status) |
1132 | mlog_errno(status); | 1130 | mlog_errno(status); |
1133 | out: | 1131 | out_copy: |
1134 | /* | 1132 | /* |
1135 | * movement/defragmentation may end up being partially completed, | 1133 | * movement/defragmentation may end up being partially completed, |
1136 | * that's the reason why we need to return userspace the finished | 1134 | * that's the reason why we need to return userspace the finished |
1137 | * length and new_offset even if failure happens somewhere. | 1135 | * length and new_offset even if failure happens somewhere. |
1138 | */ | 1136 | */ |
1139 | if (argp) { | 1137 | if (copy_to_user(argp, &range, sizeof(range))) |
1140 | if (copy_to_user(argp, &range, sizeof(range))) | 1138 | status = -EFAULT; |
1141 | status = -EFAULT; | ||
1142 | } | ||
1143 | 1139 | ||
1140 | out_free: | ||
1144 | kfree(context); | 1141 | kfree(context); |
1145 | 1142 | out_drop: | |
1146 | mnt_drop_write_file(filp); | 1143 | mnt_drop_write_file(filp); |
1147 | 1144 | ||
1148 | return status; | 1145 | return status; |
@@ -197,10 +197,7 @@ out: | |||
197 | 197 | ||
198 | SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) | 198 | SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) |
199 | { | 199 | { |
200 | long ret = do_sys_ftruncate(fd, length, 1); | 200 | return do_sys_ftruncate(fd, length, 1); |
201 | /* avoid REGPARM breakage on x86: */ | ||
202 | asmlinkage_protect(2, ret, fd, length); | ||
203 | return ret; | ||
204 | } | 201 | } |
205 | 202 | ||
206 | #ifdef CONFIG_COMPAT | 203 | #ifdef CONFIG_COMPAT |
@@ -212,32 +209,15 @@ COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length) | |||
212 | 209 | ||
213 | /* LFS versions of truncate are only needed on 32 bit machines */ | 210 | /* LFS versions of truncate are only needed on 32 bit machines */ |
214 | #if BITS_PER_LONG == 32 | 211 | #if BITS_PER_LONG == 32 |
215 | SYSCALL_DEFINE(truncate64)(const char __user * path, loff_t length) | 212 | SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length) |
216 | { | 213 | { |
217 | return do_sys_truncate(path, length); | 214 | return do_sys_truncate(path, length); |
218 | } | 215 | } |
219 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
220 | asmlinkage long SyS_truncate64(long path, loff_t length) | ||
221 | { | ||
222 | return SYSC_truncate64((const char __user *) path, length); | ||
223 | } | ||
224 | SYSCALL_ALIAS(sys_truncate64, SyS_truncate64); | ||
225 | #endif | ||
226 | 216 | ||
227 | SYSCALL_DEFINE(ftruncate64)(unsigned int fd, loff_t length) | 217 | SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length) |
228 | { | 218 | { |
229 | long ret = do_sys_ftruncate(fd, length, 0); | 219 | return do_sys_ftruncate(fd, length, 0); |
230 | /* avoid REGPARM breakage on x86: */ | ||
231 | asmlinkage_protect(2, ret, fd, length); | ||
232 | return ret; | ||
233 | } | ||
234 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
235 | asmlinkage long SyS_ftruncate64(long fd, loff_t length) | ||
236 | { | ||
237 | return SYSC_ftruncate64((unsigned int) fd, length); | ||
238 | } | 220 | } |
239 | SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64); | ||
240 | #endif | ||
241 | #endif /* BITS_PER_LONG == 32 */ | 221 | #endif /* BITS_PER_LONG == 32 */ |
242 | 222 | ||
243 | 223 | ||
@@ -299,7 +279,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
299 | return ret; | 279 | return ret; |
300 | } | 280 | } |
301 | 281 | ||
302 | SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) | 282 | SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) |
303 | { | 283 | { |
304 | struct fd f = fdget(fd); | 284 | struct fd f = fdget(fd); |
305 | int error = -EBADF; | 285 | int error = -EBADF; |
@@ -311,14 +291,6 @@ SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) | |||
311 | return error; | 291 | return error; |
312 | } | 292 | } |
313 | 293 | ||
314 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
315 | asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) | ||
316 | { | ||
317 | return SYSC_fallocate((int)fd, (int)mode, offset, len); | ||
318 | } | ||
319 | SYSCALL_ALIAS(sys_fallocate, SyS_fallocate); | ||
320 | #endif | ||
321 | |||
322 | /* | 294 | /* |
323 | * access() needs to use the real uid/gid, not the effective uid/gid. | 295 | * access() needs to use the real uid/gid, not the effective uid/gid. |
324 | * We do this by temporarily clearing all FS-related capabilities and | 296 | * We do this by temporarily clearing all FS-related capabilities and |
@@ -983,29 +955,19 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) | |||
983 | 955 | ||
984 | SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode) | 956 | SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode) |
985 | { | 957 | { |
986 | long ret; | ||
987 | |||
988 | if (force_o_largefile()) | 958 | if (force_o_largefile()) |
989 | flags |= O_LARGEFILE; | 959 | flags |= O_LARGEFILE; |
990 | 960 | ||
991 | ret = do_sys_open(AT_FDCWD, filename, flags, mode); | 961 | return do_sys_open(AT_FDCWD, filename, flags, mode); |
992 | /* avoid REGPARM breakage on x86: */ | ||
993 | asmlinkage_protect(3, ret, filename, flags, mode); | ||
994 | return ret; | ||
995 | } | 962 | } |
996 | 963 | ||
997 | SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, | 964 | SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, |
998 | umode_t, mode) | 965 | umode_t, mode) |
999 | { | 966 | { |
1000 | long ret; | ||
1001 | |||
1002 | if (force_o_largefile()) | 967 | if (force_o_largefile()) |
1003 | flags |= O_LARGEFILE; | 968 | flags |= O_LARGEFILE; |
1004 | 969 | ||
1005 | ret = do_sys_open(dfd, filename, flags, mode); | 970 | return do_sys_open(dfd, filename, flags, mode); |
1006 | /* avoid REGPARM breakage on x86: */ | ||
1007 | asmlinkage_protect(4, ret, dfd, filename, flags, mode); | ||
1008 | return ret; | ||
1009 | } | 971 | } |
1010 | 972 | ||
1011 | #ifndef __alpha__ | 973 | #ifndef __alpha__ |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 712f24db9600..ab30716584f5 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-y += proc.o | 5 | obj-y += proc.o |
6 | 6 | ||
7 | proc-y := nommu.o task_nommu.o | 7 | proc-y := nommu.o task_nommu.o |
8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o | 8 | proc-$(CONFIG_MMU) := task_mmu.o |
9 | 9 | ||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | fd.o | 11 | fd.o |
diff --git a/fs/proc/array.c b/fs/proc/array.c index f7ed9ee46eb9..cbd0f1b324b9 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -143,6 +143,7 @@ static const char * const task_state_array[] = { | |||
143 | "x (dead)", /* 64 */ | 143 | "x (dead)", /* 64 */ |
144 | "K (wakekill)", /* 128 */ | 144 | "K (wakekill)", /* 128 */ |
145 | "W (waking)", /* 256 */ | 145 | "W (waking)", /* 256 */ |
146 | "P (parked)", /* 512 */ | ||
146 | }; | 147 | }; |
147 | 148 | ||
148 | static inline const char *get_task_state(struct task_struct *tsk) | 149 | static inline const char *get_task_state(struct task_struct *tsk) |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 69078c7cef1f..3861bcec41ff 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #include <linux/fs_struct.h> | 86 | #include <linux/fs_struct.h> |
87 | #include <linux/slab.h> | 87 | #include <linux/slab.h> |
88 | #include <linux/flex_array.h> | 88 | #include <linux/flex_array.h> |
89 | #include <linux/posix-timers.h> | ||
89 | #ifdef CONFIG_HARDWALL | 90 | #ifdef CONFIG_HARDWALL |
90 | #include <asm/hardwall.h> | 91 | #include <asm/hardwall.h> |
91 | #endif | 92 | #endif |
@@ -1347,11 +1348,10 @@ static ssize_t comm_write(struct file *file, const char __user *buf, | |||
1347 | struct inode *inode = file_inode(file); | 1348 | struct inode *inode = file_inode(file); |
1348 | struct task_struct *p; | 1349 | struct task_struct *p; |
1349 | char buffer[TASK_COMM_LEN]; | 1350 | char buffer[TASK_COMM_LEN]; |
1351 | const size_t maxlen = sizeof(buffer) - 1; | ||
1350 | 1352 | ||
1351 | memset(buffer, 0, sizeof(buffer)); | 1353 | memset(buffer, 0, sizeof(buffer)); |
1352 | if (count > sizeof(buffer) - 1) | 1354 | if (copy_from_user(buffer, buf, count > maxlen ? maxlen : count)) |
1353 | count = sizeof(buffer) - 1; | ||
1354 | if (copy_from_user(buffer, buf, count)) | ||
1355 | return -EFAULT; | 1355 | return -EFAULT; |
1356 | 1356 | ||
1357 | p = get_proc_task(inode); | 1357 | p = get_proc_task(inode); |
@@ -2013,6 +2013,102 @@ static const struct file_operations proc_map_files_operations = { | |||
2013 | .llseek = default_llseek, | 2013 | .llseek = default_llseek, |
2014 | }; | 2014 | }; |
2015 | 2015 | ||
2016 | struct timers_private { | ||
2017 | struct pid *pid; | ||
2018 | struct task_struct *task; | ||
2019 | struct sighand_struct *sighand; | ||
2020 | struct pid_namespace *ns; | ||
2021 | unsigned long flags; | ||
2022 | }; | ||
2023 | |||
2024 | static void *timers_start(struct seq_file *m, loff_t *pos) | ||
2025 | { | ||
2026 | struct timers_private *tp = m->private; | ||
2027 | |||
2028 | tp->task = get_pid_task(tp->pid, PIDTYPE_PID); | ||
2029 | if (!tp->task) | ||
2030 | return ERR_PTR(-ESRCH); | ||
2031 | |||
2032 | tp->sighand = lock_task_sighand(tp->task, &tp->flags); | ||
2033 | if (!tp->sighand) | ||
2034 | return ERR_PTR(-ESRCH); | ||
2035 | |||
2036 | return seq_list_start(&tp->task->signal->posix_timers, *pos); | ||
2037 | } | ||
2038 | |||
2039 | static void *timers_next(struct seq_file *m, void *v, loff_t *pos) | ||
2040 | { | ||
2041 | struct timers_private *tp = m->private; | ||
2042 | return seq_list_next(v, &tp->task->signal->posix_timers, pos); | ||
2043 | } | ||
2044 | |||
2045 | static void timers_stop(struct seq_file *m, void *v) | ||
2046 | { | ||
2047 | struct timers_private *tp = m->private; | ||
2048 | |||
2049 | if (tp->sighand) { | ||
2050 | unlock_task_sighand(tp->task, &tp->flags); | ||
2051 | tp->sighand = NULL; | ||
2052 | } | ||
2053 | |||
2054 | if (tp->task) { | ||
2055 | put_task_struct(tp->task); | ||
2056 | tp->task = NULL; | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2060 | static int show_timer(struct seq_file *m, void *v) | ||
2061 | { | ||
2062 | struct k_itimer *timer; | ||
2063 | struct timers_private *tp = m->private; | ||
2064 | int notify; | ||
2065 | static char *nstr[] = { | ||
2066 | [SIGEV_SIGNAL] = "signal", | ||
2067 | [SIGEV_NONE] = "none", | ||
2068 | [SIGEV_THREAD] = "thread", | ||
2069 | }; | ||
2070 | |||
2071 | timer = list_entry((struct list_head *)v, struct k_itimer, list); | ||
2072 | notify = timer->it_sigev_notify; | ||
2073 | |||
2074 | seq_printf(m, "ID: %d\n", timer->it_id); | ||
2075 | seq_printf(m, "signal: %d/%p\n", timer->sigq->info.si_signo, | ||
2076 | timer->sigq->info.si_value.sival_ptr); | ||
2077 | seq_printf(m, "notify: %s/%s.%d\n", | ||
2078 | nstr[notify & ~SIGEV_THREAD_ID], | ||
2079 | (notify & SIGEV_THREAD_ID) ? "tid" : "pid", | ||
2080 | pid_nr_ns(timer->it_pid, tp->ns)); | ||
2081 | |||
2082 | return 0; | ||
2083 | } | ||
2084 | |||
2085 | static const struct seq_operations proc_timers_seq_ops = { | ||
2086 | .start = timers_start, | ||
2087 | .next = timers_next, | ||
2088 | .stop = timers_stop, | ||
2089 | .show = show_timer, | ||
2090 | }; | ||
2091 | |||
2092 | static int proc_timers_open(struct inode *inode, struct file *file) | ||
2093 | { | ||
2094 | struct timers_private *tp; | ||
2095 | |||
2096 | tp = __seq_open_private(file, &proc_timers_seq_ops, | ||
2097 | sizeof(struct timers_private)); | ||
2098 | if (!tp) | ||
2099 | return -ENOMEM; | ||
2100 | |||
2101 | tp->pid = proc_pid(inode); | ||
2102 | tp->ns = inode->i_sb->s_fs_info; | ||
2103 | return 0; | ||
2104 | } | ||
2105 | |||
2106 | static const struct file_operations proc_timers_operations = { | ||
2107 | .open = proc_timers_open, | ||
2108 | .read = seq_read, | ||
2109 | .llseek = seq_lseek, | ||
2110 | .release = seq_release_private, | ||
2111 | }; | ||
2016 | #endif /* CONFIG_CHECKPOINT_RESTORE */ | 2112 | #endif /* CONFIG_CHECKPOINT_RESTORE */ |
2017 | 2113 | ||
2018 | static struct dentry *proc_pident_instantiate(struct inode *dir, | 2114 | static struct dentry *proc_pident_instantiate(struct inode *dir, |
@@ -2583,6 +2679,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2583 | REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), | 2679 | REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), |
2584 | REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations), | 2680 | REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations), |
2585 | #endif | 2681 | #endif |
2682 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
2683 | REG("timers", S_IRUGO, proc_timers_operations), | ||
2684 | #endif | ||
2586 | }; | 2685 | }; |
2587 | 2686 | ||
2588 | static int proc_tgid_base_readdir(struct file * filp, | 2687 | static int proc_tgid_base_readdir(struct file * filp, |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 4b3b3ffb52f1..21e1a8f1659d 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -755,37 +755,8 @@ void pde_put(struct proc_dir_entry *pde) | |||
755 | free_proc_entry(pde); | 755 | free_proc_entry(pde); |
756 | } | 756 | } |
757 | 757 | ||
758 | /* | 758 | static void entry_rundown(struct proc_dir_entry *de) |
759 | * Remove a /proc entry and free it if it's not currently in use. | ||
760 | */ | ||
761 | void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | ||
762 | { | 759 | { |
763 | struct proc_dir_entry **p; | ||
764 | struct proc_dir_entry *de = NULL; | ||
765 | const char *fn = name; | ||
766 | unsigned int len; | ||
767 | |||
768 | spin_lock(&proc_subdir_lock); | ||
769 | if (__xlate_proc_name(name, &parent, &fn) != 0) { | ||
770 | spin_unlock(&proc_subdir_lock); | ||
771 | return; | ||
772 | } | ||
773 | len = strlen(fn); | ||
774 | |||
775 | for (p = &parent->subdir; *p; p=&(*p)->next ) { | ||
776 | if (proc_match(len, fn, *p)) { | ||
777 | de = *p; | ||
778 | *p = de->next; | ||
779 | de->next = NULL; | ||
780 | break; | ||
781 | } | ||
782 | } | ||
783 | spin_unlock(&proc_subdir_lock); | ||
784 | if (!de) { | ||
785 | WARN(1, "name '%s'\n", name); | ||
786 | return; | ||
787 | } | ||
788 | |||
789 | spin_lock(&de->pde_unload_lock); | 760 | spin_lock(&de->pde_unload_lock); |
790 | /* | 761 | /* |
791 | * Stop accepting new callers into module. If you're | 762 | * Stop accepting new callers into module. If you're |
@@ -817,6 +788,40 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | |||
817 | spin_lock(&de->pde_unload_lock); | 788 | spin_lock(&de->pde_unload_lock); |
818 | } | 789 | } |
819 | spin_unlock(&de->pde_unload_lock); | 790 | spin_unlock(&de->pde_unload_lock); |
791 | } | ||
792 | |||
793 | /* | ||
794 | * Remove a /proc entry and free it if it's not currently in use. | ||
795 | */ | ||
796 | void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | ||
797 | { | ||
798 | struct proc_dir_entry **p; | ||
799 | struct proc_dir_entry *de = NULL; | ||
800 | const char *fn = name; | ||
801 | unsigned int len; | ||
802 | |||
803 | spin_lock(&proc_subdir_lock); | ||
804 | if (__xlate_proc_name(name, &parent, &fn) != 0) { | ||
805 | spin_unlock(&proc_subdir_lock); | ||
806 | return; | ||
807 | } | ||
808 | len = strlen(fn); | ||
809 | |||
810 | for (p = &parent->subdir; *p; p=&(*p)->next ) { | ||
811 | if (proc_match(len, fn, *p)) { | ||
812 | de = *p; | ||
813 | *p = de->next; | ||
814 | de->next = NULL; | ||
815 | break; | ||
816 | } | ||
817 | } | ||
818 | spin_unlock(&proc_subdir_lock); | ||
819 | if (!de) { | ||
820 | WARN(1, "name '%s'\n", name); | ||
821 | return; | ||
822 | } | ||
823 | |||
824 | entry_rundown(de); | ||
820 | 825 | ||
821 | if (S_ISDIR(de->mode)) | 826 | if (S_ISDIR(de->mode)) |
822 | parent->nlink--; | 827 | parent->nlink--; |
@@ -827,3 +832,57 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | |||
827 | pde_put(de); | 832 | pde_put(de); |
828 | } | 833 | } |
829 | EXPORT_SYMBOL(remove_proc_entry); | 834 | EXPORT_SYMBOL(remove_proc_entry); |
835 | |||
836 | int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) | ||
837 | { | ||
838 | struct proc_dir_entry **p; | ||
839 | struct proc_dir_entry *root = NULL, *de, *next; | ||
840 | const char *fn = name; | ||
841 | unsigned int len; | ||
842 | |||
843 | spin_lock(&proc_subdir_lock); | ||
844 | if (__xlate_proc_name(name, &parent, &fn) != 0) { | ||
845 | spin_unlock(&proc_subdir_lock); | ||
846 | return -ENOENT; | ||
847 | } | ||
848 | len = strlen(fn); | ||
849 | |||
850 | for (p = &parent->subdir; *p; p=&(*p)->next ) { | ||
851 | if (proc_match(len, fn, *p)) { | ||
852 | root = *p; | ||
853 | *p = root->next; | ||
854 | root->next = NULL; | ||
855 | break; | ||
856 | } | ||
857 | } | ||
858 | if (!root) { | ||
859 | spin_unlock(&proc_subdir_lock); | ||
860 | return -ENOENT; | ||
861 | } | ||
862 | de = root; | ||
863 | while (1) { | ||
864 | next = de->subdir; | ||
865 | if (next) { | ||
866 | de->subdir = next->next; | ||
867 | next->next = NULL; | ||
868 | de = next; | ||
869 | continue; | ||
870 | } | ||
871 | spin_unlock(&proc_subdir_lock); | ||
872 | |||
873 | entry_rundown(de); | ||
874 | next = de->parent; | ||
875 | if (S_ISDIR(de->mode)) | ||
876 | next->nlink--; | ||
877 | de->nlink = 0; | ||
878 | if (de == root) | ||
879 | break; | ||
880 | pde_put(de); | ||
881 | |||
882 | spin_lock(&proc_subdir_lock); | ||
883 | de = next; | ||
884 | } | ||
885 | pde_put(root); | ||
886 | return 0; | ||
887 | } | ||
888 | EXPORT_SYMBOL(remove_proc_subtree); | ||
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 85ff3a4598b3..75710357a517 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -30,24 +30,6 @@ extern int proc_net_init(void); | |||
30 | static inline int proc_net_init(void) { return 0; } | 30 | static inline int proc_net_init(void) { return 0; } |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | struct vmalloc_info { | ||
34 | unsigned long used; | ||
35 | unsigned long largest_chunk; | ||
36 | }; | ||
37 | |||
38 | #ifdef CONFIG_MMU | ||
39 | #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START) | ||
40 | extern void get_vmalloc_info(struct vmalloc_info *vmi); | ||
41 | #else | ||
42 | |||
43 | #define VMALLOC_TOTAL 0UL | ||
44 | #define get_vmalloc_info(vmi) \ | ||
45 | do { \ | ||
46 | (vmi)->used = 0; \ | ||
47 | (vmi)->largest_chunk = 0; \ | ||
48 | } while(0) | ||
49 | #endif | ||
50 | |||
51 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, | 33 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, |
52 | struct pid *pid, struct task_struct *task); | 34 | struct pid *pid, struct task_struct *task); |
53 | extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, | 35 | extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, |
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index eda6f017f272..f6a13f489e30 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/capability.h> | 15 | #include <linux/capability.h> |
16 | #include <linux/elf.h> | 16 | #include <linux/elf.h> |
17 | #include <linux/elfcore.h> | 17 | #include <linux/elfcore.h> |
18 | #include <linux/notifier.h> | ||
18 | #include <linux/vmalloc.h> | 19 | #include <linux/vmalloc.h> |
19 | #include <linux/highmem.h> | 20 | #include <linux/highmem.h> |
20 | #include <linux/printk.h> | 21 | #include <linux/printk.h> |
@@ -564,7 +565,6 @@ static const struct file_operations proc_kcore_operations = { | |||
564 | .llseek = default_llseek, | 565 | .llseek = default_llseek, |
565 | }; | 566 | }; |
566 | 567 | ||
567 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
568 | /* just remember that we have to update kcore */ | 568 | /* just remember that we have to update kcore */ |
569 | static int __meminit kcore_callback(struct notifier_block *self, | 569 | static int __meminit kcore_callback(struct notifier_block *self, |
570 | unsigned long action, void *arg) | 570 | unsigned long action, void *arg) |
@@ -578,8 +578,11 @@ static int __meminit kcore_callback(struct notifier_block *self, | |||
578 | } | 578 | } |
579 | return NOTIFY_OK; | 579 | return NOTIFY_OK; |
580 | } | 580 | } |
581 | #endif | ||
582 | 581 | ||
582 | static struct notifier_block kcore_callback_nb __meminitdata = { | ||
583 | .notifier_call = kcore_callback, | ||
584 | .priority = 0, | ||
585 | }; | ||
583 | 586 | ||
584 | static struct kcore_list kcore_vmalloc; | 587 | static struct kcore_list kcore_vmalloc; |
585 | 588 | ||
@@ -631,7 +634,7 @@ static int __init proc_kcore_init(void) | |||
631 | add_modules_range(); | 634 | add_modules_range(); |
632 | /* Store direct-map area from physical memory map */ | 635 | /* Store direct-map area from physical memory map */ |
633 | kcore_update_ram(); | 636 | kcore_update_ram(); |
634 | hotplug_memory_notifier(kcore_callback, 0); | 637 | register_hotmemory_notifier(&kcore_callback_nb); |
635 | 638 | ||
636 | return 0; | 639 | return 0; |
637 | } | 640 | } |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 1efaaa19c4f3..5aa847a603c0 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/swap.h> | 11 | #include <linux/swap.h> |
12 | #include <linux/vmstat.h> | 12 | #include <linux/vmstat.h> |
13 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
14 | #include <linux/vmalloc.h> | ||
14 | #include <asm/page.h> | 15 | #include <asm/page.h> |
15 | #include <asm/pgtable.h> | 16 | #include <asm/pgtable.h> |
16 | #include "internal.h" | 17 | #include "internal.h" |
diff --git a/fs/proc/mmu.c b/fs/proc/mmu.c deleted file mode 100644 index 8ae221dfd010..000000000000 --- a/fs/proc/mmu.c +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* mmu.c: mmu memory info files | ||
2 | * | ||
3 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/vmalloc.h> | ||
13 | #include <linux/highmem.h> | ||
14 | #include <asm/pgtable.h> | ||
15 | #include "internal.h" | ||
16 | |||
17 | void get_vmalloc_info(struct vmalloc_info *vmi) | ||
18 | { | ||
19 | struct vm_struct *vma; | ||
20 | unsigned long free_area_size; | ||
21 | unsigned long prev_end; | ||
22 | |||
23 | vmi->used = 0; | ||
24 | |||
25 | if (!vmlist) { | ||
26 | vmi->largest_chunk = VMALLOC_TOTAL; | ||
27 | } | ||
28 | else { | ||
29 | vmi->largest_chunk = 0; | ||
30 | |||
31 | prev_end = VMALLOC_START; | ||
32 | |||
33 | read_lock(&vmlist_lock); | ||
34 | |||
35 | for (vma = vmlist; vma; vma = vma->next) { | ||
36 | unsigned long addr = (unsigned long) vma->addr; | ||
37 | |||
38 | /* | ||
39 | * Some archs keep another range for modules in vmlist | ||
40 | */ | ||
41 | if (addr < VMALLOC_START) | ||
42 | continue; | ||
43 | if (addr >= VMALLOC_END) | ||
44 | break; | ||
45 | |||
46 | vmi->used += vma->size; | ||
47 | |||
48 | free_area_size = addr - prev_end; | ||
49 | if (vmi->largest_chunk < free_area_size) | ||
50 | vmi->largest_chunk = free_area_size; | ||
51 | |||
52 | prev_end = vma->size + addr; | ||
53 | } | ||
54 | |||
55 | if (VMALLOC_END - prev_end > vmi->largest_chunk) | ||
56 | vmi->largest_chunk = VMALLOC_END - prev_end; | ||
57 | |||
58 | read_unlock(&vmlist_lock); | ||
59 | } | ||
60 | } | ||
diff --git a/fs/read_write.c b/fs/read_write.c index e6ddc8dceb96..8274a794253b 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -128,7 +128,7 @@ EXPORT_SYMBOL(generic_file_llseek_size); | |||
128 | * | 128 | * |
129 | * This is a generic implemenation of ->llseek useable for all normal local | 129 | * This is a generic implemenation of ->llseek useable for all normal local |
130 | * filesystems. It just updates the file offset to the value specified by | 130 | * filesystems. It just updates the file offset to the value specified by |
131 | * @offset and @whence under i_mutex. | 131 | * @offset and @whence. |
132 | */ | 132 | */ |
133 | loff_t generic_file_llseek(struct file *file, loff_t offset, int whence) | 133 | loff_t generic_file_llseek(struct file *file, loff_t offset, int whence) |
134 | { | 134 | { |
@@ -515,8 +515,8 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, | |||
515 | return ret; | 515 | return ret; |
516 | } | 516 | } |
517 | 517 | ||
518 | SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, | 518 | SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf, |
519 | size_t count, loff_t pos) | 519 | size_t, count, loff_t, pos) |
520 | { | 520 | { |
521 | struct fd f; | 521 | struct fd f; |
522 | ssize_t ret = -EBADF; | 522 | ssize_t ret = -EBADF; |
@@ -534,17 +534,9 @@ SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, | |||
534 | 534 | ||
535 | return ret; | 535 | return ret; |
536 | } | 536 | } |
537 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
538 | asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos) | ||
539 | { | ||
540 | return SYSC_pread64((unsigned int) fd, (char __user *) buf, | ||
541 | (size_t) count, pos); | ||
542 | } | ||
543 | SYSCALL_ALIAS(sys_pread64, SyS_pread64); | ||
544 | #endif | ||
545 | 537 | ||
546 | SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, | 538 | SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf, |
547 | size_t count, loff_t pos) | 539 | size_t, count, loff_t, pos) |
548 | { | 540 | { |
549 | struct fd f; | 541 | struct fd f; |
550 | ssize_t ret = -EBADF; | 542 | ssize_t ret = -EBADF; |
@@ -562,14 +554,6 @@ SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, | |||
562 | 554 | ||
563 | return ret; | 555 | return ret; |
564 | } | 556 | } |
565 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
566 | asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos) | ||
567 | { | ||
568 | return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf, | ||
569 | (size_t) count, pos); | ||
570 | } | ||
571 | SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64); | ||
572 | #endif | ||
573 | 557 | ||
574 | /* | 558 | /* |
575 | * Reduce an iovec's length in-place. Return the resulting number of segments | 559 | * Reduce an iovec's length in-place. Return the resulting number of segments |
@@ -897,8 +881,8 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
897 | return ret; | 881 | return ret; |
898 | } | 882 | } |
899 | 883 | ||
900 | ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count, | 884 | static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, |
901 | loff_t max) | 885 | size_t count, loff_t max) |
902 | { | 886 | { |
903 | struct fd in, out; | 887 | struct fd in, out; |
904 | struct inode *in_inode, *out_inode; | 888 | struct inode *in_inode, *out_inode; |
@@ -1022,3 +1006,43 @@ SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, si | |||
1022 | 1006 | ||
1023 | return do_sendfile(out_fd, in_fd, NULL, count, 0); | 1007 | return do_sendfile(out_fd, in_fd, NULL, count, 0); |
1024 | } | 1008 | } |
1009 | |||
1010 | #ifdef CONFIG_COMPAT | ||
1011 | COMPAT_SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, | ||
1012 | compat_off_t __user *, offset, compat_size_t, count) | ||
1013 | { | ||
1014 | loff_t pos; | ||
1015 | off_t off; | ||
1016 | ssize_t ret; | ||
1017 | |||
1018 | if (offset) { | ||
1019 | if (unlikely(get_user(off, offset))) | ||
1020 | return -EFAULT; | ||
1021 | pos = off; | ||
1022 | ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS); | ||
1023 | if (unlikely(put_user(pos, offset))) | ||
1024 | return -EFAULT; | ||
1025 | return ret; | ||
1026 | } | ||
1027 | |||
1028 | return do_sendfile(out_fd, in_fd, NULL, count, 0); | ||
1029 | } | ||
1030 | |||
1031 | COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, | ||
1032 | compat_loff_t __user *, offset, compat_size_t, count) | ||
1033 | { | ||
1034 | loff_t pos; | ||
1035 | ssize_t ret; | ||
1036 | |||
1037 | if (offset) { | ||
1038 | if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t)))) | ||
1039 | return -EFAULT; | ||
1040 | ret = do_sendfile(out_fd, in_fd, &pos, count, 0); | ||
1041 | if (unlikely(put_user(pos, offset))) | ||
1042 | return -EFAULT; | ||
1043 | return ret; | ||
1044 | } | ||
1045 | |||
1046 | return do_sendfile(out_fd, in_fd, NULL, count, 0); | ||
1047 | } | ||
1048 | #endif | ||
diff --git a/fs/read_write.h b/fs/read_write.h index d3e00ef67420..d07b954c6e0c 100644 --- a/fs/read_write.h +++ b/fs/read_write.h | |||
@@ -12,5 +12,3 @@ ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, | |||
12 | unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); | 12 | unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); |
13 | ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, | 13 | ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, |
14 | unsigned long nr_segs, loff_t *ppos, io_fn_t fn); | 14 | unsigned long nr_segs, loff_t *ppos, io_fn_t fn); |
15 | ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count, | ||
16 | loff_t max); | ||
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index c196369fe408..4cce1d9552fb 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -187,8 +187,8 @@ fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset, | |||
187 | if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) | 187 | if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) |
188 | return -ENOSPC; | 188 | return -ENOSPC; |
189 | 189 | ||
190 | if (name[0] == '.' && (name[1] == '\0' || | 190 | if (name[0] == '.' && (namelen < 2 || |
191 | (name[1] == '.' && name[2] == '\0'))) | 191 | (namelen == 2 && name[1] == '.'))) |
192 | return 0; | 192 | return 0; |
193 | 193 | ||
194 | dentry = lookup_one_len(name, dbuf->xadir, namelen); | 194 | dentry = lookup_one_len(name, dbuf->xadir, namelen); |
diff --git a/fs/signalfd.c b/fs/signalfd.c index b53486961735..424b7b65321f 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/signalfd.h> | 30 | #include <linux/signalfd.h> |
31 | #include <linux/syscalls.h> | 31 | #include <linux/syscalls.h> |
32 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
33 | #include <linux/compat.h> | ||
33 | 34 | ||
34 | void signalfd_cleanup(struct sighand_struct *sighand) | 35 | void signalfd_cleanup(struct sighand_struct *sighand) |
35 | { | 36 | { |
@@ -311,3 +312,33 @@ SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask, | |||
311 | { | 312 | { |
312 | return sys_signalfd4(ufd, user_mask, sizemask, 0); | 313 | return sys_signalfd4(ufd, user_mask, sizemask, 0); |
313 | } | 314 | } |
315 | |||
316 | #ifdef CONFIG_COMPAT | ||
317 | COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd, | ||
318 | const compat_sigset_t __user *,sigmask, | ||
319 | compat_size_t, sigsetsize, | ||
320 | int, flags) | ||
321 | { | ||
322 | compat_sigset_t ss32; | ||
323 | sigset_t tmp; | ||
324 | sigset_t __user *ksigmask; | ||
325 | |||
326 | if (sigsetsize != sizeof(compat_sigset_t)) | ||
327 | return -EINVAL; | ||
328 | if (copy_from_user(&ss32, sigmask, sizeof(ss32))) | ||
329 | return -EFAULT; | ||
330 | sigset_from_compat(&tmp, &ss32); | ||
331 | ksigmask = compat_alloc_user_space(sizeof(sigset_t)); | ||
332 | if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t))) | ||
333 | return -EFAULT; | ||
334 | |||
335 | return sys_signalfd4(ufd, ksigmask, sizeof(sigset_t), flags); | ||
336 | } | ||
337 | |||
338 | COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd, | ||
339 | const compat_sigset_t __user *,sigmask, | ||
340 | compat_size_t, sigsetsize) | ||
341 | { | ||
342 | return compat_sys_signalfd4(ufd, sigmask, sigsetsize, 0); | ||
343 | } | ||
344 | #endif | ||
diff --git a/fs/splice.c b/fs/splice.c index 29e394e49ddd..6b485b8753bd 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/security.h> | 31 | #include <linux/security.h> |
32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
33 | #include <linux/socket.h> | 33 | #include <linux/socket.h> |
34 | #include <linux/compat.h> | ||
34 | #include "internal.h" | 35 | #include "internal.h" |
35 | 36 | ||
36 | /* | 37 | /* |
@@ -1690,6 +1691,27 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, | |||
1690 | return error; | 1691 | return error; |
1691 | } | 1692 | } |
1692 | 1693 | ||
1694 | #ifdef CONFIG_COMPAT | ||
1695 | COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd, const struct compat_iovec __user *, iov32, | ||
1696 | unsigned int, nr_segs, unsigned int, flags) | ||
1697 | { | ||
1698 | unsigned i; | ||
1699 | struct iovec __user *iov; | ||
1700 | if (nr_segs > UIO_MAXIOV) | ||
1701 | return -EINVAL; | ||
1702 | iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec)); | ||
1703 | for (i = 0; i < nr_segs; i++) { | ||
1704 | struct compat_iovec v; | ||
1705 | if (get_user(v.iov_base, &iov32[i].iov_base) || | ||
1706 | get_user(v.iov_len, &iov32[i].iov_len) || | ||
1707 | put_user(compat_ptr(v.iov_base), &iov[i].iov_base) || | ||
1708 | put_user(v.iov_len, &iov[i].iov_len)) | ||
1709 | return -EFAULT; | ||
1710 | } | ||
1711 | return sys_vmsplice(fd, iov, nr_segs, flags); | ||
1712 | } | ||
1713 | #endif | ||
1714 | |||
1693 | SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, | 1715 | SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, |
1694 | int, fd_out, loff_t __user *, off_out, | 1716 | int, fd_out, loff_t __user *, off_out, |
1695 | size_t, len, unsigned int, flags) | 1717 | size_t, len, unsigned int, flags) |
@@ -283,8 +283,8 @@ EXPORT_SYMBOL(generic_write_sync); | |||
283 | * already-instantiated disk blocks, there are no guarantees here that the data | 283 | * already-instantiated disk blocks, there are no guarantees here that the data |
284 | * will be available after a crash. | 284 | * will be available after a crash. |
285 | */ | 285 | */ |
286 | SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, | 286 | SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes, |
287 | unsigned int flags) | 287 | unsigned int, flags) |
288 | { | 288 | { |
289 | int ret; | 289 | int ret; |
290 | struct fd f; | 290 | struct fd f; |
@@ -365,29 +365,11 @@ out_put: | |||
365 | out: | 365 | out: |
366 | return ret; | 366 | return ret; |
367 | } | 367 | } |
368 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
369 | asmlinkage long SyS_sync_file_range(long fd, loff_t offset, loff_t nbytes, | ||
370 | long flags) | ||
371 | { | ||
372 | return SYSC_sync_file_range((int) fd, offset, nbytes, | ||
373 | (unsigned int) flags); | ||
374 | } | ||
375 | SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range); | ||
376 | #endif | ||
377 | 368 | ||
378 | /* It would be nice if people remember that not all the world's an i386 | 369 | /* It would be nice if people remember that not all the world's an i386 |
379 | when they introduce new system calls */ | 370 | when they introduce new system calls */ |
380 | SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags, | 371 | SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags, |
381 | loff_t offset, loff_t nbytes) | 372 | loff_t, offset, loff_t, nbytes) |
382 | { | 373 | { |
383 | return sys_sync_file_range(fd, offset, nbytes, flags); | 374 | return sys_sync_file_range(fd, offset, nbytes, flags); |
384 | } | 375 | } |
385 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | ||
386 | asmlinkage long SyS_sync_file_range2(long fd, long flags, | ||
387 | loff_t offset, loff_t nbytes) | ||
388 | { | ||
389 | return SYSC_sync_file_range2((int) fd, (unsigned int) flags, | ||
390 | offset, nbytes); | ||
391 | } | ||
392 | SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2); | ||
393 | #endif | ||
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index e14512678c9b..e8e0e71b29d5 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -165,21 +165,8 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) | |||
165 | if (unlikely(!sd)) | 165 | if (unlikely(!sd)) |
166 | return NULL; | 166 | return NULL; |
167 | 167 | ||
168 | while (1) { | 168 | if (!atomic_inc_unless_negative(&sd->s_active)) |
169 | int v, t; | 169 | return NULL; |
170 | |||
171 | v = atomic_read(&sd->s_active); | ||
172 | if (unlikely(v < 0)) | ||
173 | return NULL; | ||
174 | |||
175 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); | ||
176 | if (likely(t == v)) | ||
177 | break; | ||
178 | if (t < 0) | ||
179 | return NULL; | ||
180 | |||
181 | cpu_relax(); | ||
182 | } | ||
183 | 170 | ||
184 | if (likely(!ignore_lockdep(sd))) | 171 | if (likely(!ignore_lockdep(sd))) |
185 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | 172 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); |
@@ -281,6 +268,10 @@ void release_sysfs_dirent(struct sysfs_dirent * sd) | |||
281 | */ | 268 | */ |
282 | parent_sd = sd->s_parent; | 269 | parent_sd = sd->s_parent; |
283 | 270 | ||
271 | WARN(!(sd->s_flags & SYSFS_FLAG_REMOVED), | ||
272 | "sysfs: free using entry: %s/%s\n", | ||
273 | parent_sd ? parent_sd->s_name : "", sd->s_name); | ||
274 | |||
284 | if (sysfs_type(sd) == SYSFS_KOBJ_LINK) | 275 | if (sysfs_type(sd) == SYSFS_KOBJ_LINK) |
285 | sysfs_put(sd->s_symlink.target_sd); | 276 | sysfs_put(sd->s_symlink.target_sd); |
286 | if (sysfs_type(sd) & SYSFS_COPY_NAME) | 277 | if (sysfs_type(sd) & SYSFS_COPY_NAME) |
@@ -399,7 +390,7 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) | |||
399 | 390 | ||
400 | sd->s_name = name; | 391 | sd->s_name = name; |
401 | sd->s_mode = mode; | 392 | sd->s_mode = mode; |
402 | sd->s_flags = type; | 393 | sd->s_flags = type | SYSFS_FLAG_REMOVED; |
403 | 394 | ||
404 | return sd; | 395 | return sd; |
405 | 396 | ||
@@ -479,6 +470,9 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | |||
479 | ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; | 470 | ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; |
480 | } | 471 | } |
481 | 472 | ||
473 | /* Mark the entry added into directory tree */ | ||
474 | sd->s_flags &= ~SYSFS_FLAG_REMOVED; | ||
475 | |||
482 | return 0; | 476 | return 0; |
483 | } | 477 | } |
484 | 478 | ||
@@ -1012,6 +1006,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
1012 | enum kobj_ns_type type; | 1006 | enum kobj_ns_type type; |
1013 | const void *ns; | 1007 | const void *ns; |
1014 | ino_t ino; | 1008 | ino_t ino; |
1009 | loff_t off; | ||
1015 | 1010 | ||
1016 | type = sysfs_ns_type(parent_sd); | 1011 | type = sysfs_ns_type(parent_sd); |
1017 | ns = sysfs_info(dentry->d_sb)->ns[type]; | 1012 | ns = sysfs_info(dentry->d_sb)->ns[type]; |
@@ -1034,6 +1029,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
1034 | return 0; | 1029 | return 0; |
1035 | } | 1030 | } |
1036 | mutex_lock(&sysfs_mutex); | 1031 | mutex_lock(&sysfs_mutex); |
1032 | off = filp->f_pos; | ||
1037 | for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); | 1033 | for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); |
1038 | pos; | 1034 | pos; |
1039 | pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) { | 1035 | pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) { |
@@ -1045,19 +1041,24 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
1045 | len = strlen(name); | 1041 | len = strlen(name); |
1046 | ino = pos->s_ino; | 1042 | ino = pos->s_ino; |
1047 | type = dt_type(pos); | 1043 | type = dt_type(pos); |
1048 | filp->f_pos = pos->s_hash; | 1044 | off = filp->f_pos = pos->s_hash; |
1049 | filp->private_data = sysfs_get(pos); | 1045 | filp->private_data = sysfs_get(pos); |
1050 | 1046 | ||
1051 | mutex_unlock(&sysfs_mutex); | 1047 | mutex_unlock(&sysfs_mutex); |
1052 | ret = filldir(dirent, name, len, filp->f_pos, ino, type); | 1048 | ret = filldir(dirent, name, len, off, ino, type); |
1053 | mutex_lock(&sysfs_mutex); | 1049 | mutex_lock(&sysfs_mutex); |
1054 | if (ret < 0) | 1050 | if (ret < 0) |
1055 | break; | 1051 | break; |
1056 | } | 1052 | } |
1057 | mutex_unlock(&sysfs_mutex); | 1053 | mutex_unlock(&sysfs_mutex); |
1058 | if ((filp->f_pos > 1) && !pos) { /* EOF */ | 1054 | |
1059 | filp->f_pos = INT_MAX; | 1055 | /* don't reference last entry if its refcount is dropped */ |
1056 | if (!pos) { | ||
1060 | filp->private_data = NULL; | 1057 | filp->private_data = NULL; |
1058 | |||
1059 | /* EOF and not changed as 0 or 1 in read/write path */ | ||
1060 | if (off == filp->f_pos && off > 1) | ||
1061 | filp->f_pos = INT_MAX; | ||
1061 | } | 1062 | } |
1062 | return 0; | 1063 | return 0; |
1063 | } | 1064 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index ac838b844936..f21acf0ef01f 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1568,6 +1568,12 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1568 | c->remounting_rw = 1; | 1568 | c->remounting_rw = 1; |
1569 | c->ro_mount = 0; | 1569 | c->ro_mount = 0; |
1570 | 1570 | ||
1571 | if (c->space_fixup) { | ||
1572 | err = ubifs_fixup_free_space(c); | ||
1573 | if (err) | ||
1574 | return err; | ||
1575 | } | ||
1576 | |||
1571 | err = check_free_space(c); | 1577 | err = check_free_space(c); |
1572 | if (err) | 1578 | if (err) |
1573 | goto out; | 1579 | goto out; |
@@ -1684,12 +1690,6 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1684 | err = dbg_check_space_info(c); | 1690 | err = dbg_check_space_info(c); |
1685 | } | 1691 | } |
1686 | 1692 | ||
1687 | if (c->space_fixup) { | ||
1688 | err = ubifs_fixup_free_space(c); | ||
1689 | if (err) | ||
1690 | goto out; | ||
1691 | } | ||
1692 | |||
1693 | mutex_unlock(&c->umount_mutex); | 1693 | mutex_unlock(&c->umount_mutex); |
1694 | return err; | 1694 | return err; |
1695 | 1695 | ||
diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 95425b59ce0a..b6c2f94e041e 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c | |||
@@ -26,8 +26,7 @@ struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, | |||
26 | count = size >> uspi->s_fshift; | 26 | count = size >> uspi->s_fshift; |
27 | if (count > UFS_MAXFRAG) | 27 | if (count > UFS_MAXFRAG) |
28 | return NULL; | 28 | return NULL; |
29 | ubh = (struct ufs_buffer_head *) | 29 | ubh = kmalloc (sizeof (struct ufs_buffer_head), GFP_NOFS); |
30 | kmalloc (sizeof (struct ufs_buffer_head), GFP_NOFS); | ||
31 | if (!ubh) | 30 | if (!ubh) |
32 | return NULL; | 31 | return NULL; |
33 | ubh->fragment = fragment; | 32 | ubh->fragment = fragment; |