diff options
Diffstat (limited to 'fs')
55 files changed, 679 insertions, 541 deletions
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 798cb071d132..3f57ce4bee5d 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c | |||
@@ -19,9 +19,6 @@ static int | |||
19 | adfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, | 19 | adfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, |
20 | int create) | 20 | int create) |
21 | { | 21 | { |
22 | if (block < 0) | ||
23 | goto abort_negative; | ||
24 | |||
25 | if (!create) { | 22 | if (!create) { |
26 | if (block >= inode->i_blocks) | 23 | if (block >= inode->i_blocks) |
27 | goto abort_toobig; | 24 | goto abort_toobig; |
@@ -34,10 +31,6 @@ adfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, | |||
34 | /* don't support allocation of blocks yet */ | 31 | /* don't support allocation of blocks yet */ |
35 | return -EIO; | 32 | return -EIO; |
36 | 33 | ||
37 | abort_negative: | ||
38 | adfs_error(inode->i_sb, "block %d < 0", block); | ||
39 | return -EIO; | ||
40 | |||
41 | abort_toobig: | 34 | abort_toobig: |
42 | return 0; | 35 | return 0; |
43 | } | 36 | } |
@@ -18,7 +18,7 @@ | |||
18 | /* Taken over from the old code... */ | 18 | /* Taken over from the old code... */ |
19 | 19 | ||
20 | /* POSIX UID/GID verification for setting inode attributes. */ | 20 | /* POSIX UID/GID verification for setting inode attributes. */ |
21 | int inode_change_ok(struct inode *inode, struct iattr *attr) | 21 | int inode_change_ok(const struct inode *inode, struct iattr *attr) |
22 | { | 22 | { |
23 | int retval = -EPERM; | 23 | int retval = -EPERM; |
24 | unsigned int ia_valid = attr->ia_valid; | 24 | unsigned int ia_valid = attr->ia_valid; |
@@ -60,9 +60,51 @@ fine: | |||
60 | error: | 60 | error: |
61 | return retval; | 61 | return retval; |
62 | } | 62 | } |
63 | |||
64 | EXPORT_SYMBOL(inode_change_ok); | 63 | EXPORT_SYMBOL(inode_change_ok); |
65 | 64 | ||
65 | /** | ||
66 | * inode_newsize_ok - may this inode be truncated to a given size | ||
67 | * @inode: the inode to be truncated | ||
68 | * @offset: the new size to assign to the inode | ||
69 | * @Returns: 0 on success, -ve errno on failure | ||
70 | * | ||
71 | * inode_newsize_ok will check filesystem limits and ulimits to check that the | ||
72 | * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ | ||
73 | * when necessary. Caller must not proceed with inode size change if failure is | ||
74 | * returned. @inode must be a file (not directory), with appropriate | ||
75 | * permissions to allow truncate (inode_newsize_ok does NOT check these | ||
76 | * conditions). | ||
77 | * | ||
78 | * inode_newsize_ok must be called with i_mutex held. | ||
79 | */ | ||
80 | int inode_newsize_ok(const struct inode *inode, loff_t offset) | ||
81 | { | ||
82 | if (inode->i_size < offset) { | ||
83 | unsigned long limit; | ||
84 | |||
85 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
86 | if (limit != RLIM_INFINITY && offset > limit) | ||
87 | goto out_sig; | ||
88 | if (offset > inode->i_sb->s_maxbytes) | ||
89 | goto out_big; | ||
90 | } else { | ||
91 | /* | ||
92 | * truncation of in-use swapfiles is disallowed - it would | ||
93 | * cause subsequent swapout to scribble on the now-freed | ||
94 | * blocks. | ||
95 | */ | ||
96 | if (IS_SWAPFILE(inode)) | ||
97 | return -ETXTBSY; | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | out_sig: | ||
102 | send_sig(SIGXFSZ, current, 0); | ||
103 | out_big: | ||
104 | return -EFBIG; | ||
105 | } | ||
106 | EXPORT_SYMBOL(inode_newsize_ok); | ||
107 | |||
66 | int inode_setattr(struct inode * inode, struct iattr * attr) | 108 | int inode_setattr(struct inode * inode, struct iattr * attr) |
67 | { | 109 | { |
68 | unsigned int ia_valid = attr->ia_valid; | 110 | unsigned int ia_valid = attr->ia_valid; |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index dd376c124e71..33baf27fac78 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -737,12 +737,7 @@ befs_put_super(struct super_block *sb) | |||
737 | { | 737 | { |
738 | kfree(BEFS_SB(sb)->mount_opts.iocharset); | 738 | kfree(BEFS_SB(sb)->mount_opts.iocharset); |
739 | BEFS_SB(sb)->mount_opts.iocharset = NULL; | 739 | BEFS_SB(sb)->mount_opts.iocharset = NULL; |
740 | 740 | unload_nls(BEFS_SB(sb)->nls); | |
741 | if (BEFS_SB(sb)->nls) { | ||
742 | unload_nls(BEFS_SB(sb)->nls); | ||
743 | BEFS_SB(sb)->nls = NULL; | ||
744 | } | ||
745 | |||
746 | kfree(sb->s_fs_info); | 741 | kfree(sb->s_fs_info); |
747 | sb->s_fs_info = NULL; | 742 | sb->s_fs_info = NULL; |
748 | } | 743 | } |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 442d94fe255c..b9b3bb51b1e4 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1711,42 +1711,52 @@ struct elf_note_info { | |||
1711 | int numnote; | 1711 | int numnote; |
1712 | }; | 1712 | }; |
1713 | 1713 | ||
1714 | static int fill_note_info(struct elfhdr *elf, int phdrs, | 1714 | static int elf_note_info_init(struct elf_note_info *info) |
1715 | struct elf_note_info *info, | ||
1716 | long signr, struct pt_regs *regs) | ||
1717 | { | 1715 | { |
1718 | #define NUM_NOTES 6 | 1716 | memset(info, 0, sizeof(*info)); |
1719 | struct list_head *t; | ||
1720 | |||
1721 | info->notes = NULL; | ||
1722 | info->prstatus = NULL; | ||
1723 | info->psinfo = NULL; | ||
1724 | info->fpu = NULL; | ||
1725 | #ifdef ELF_CORE_COPY_XFPREGS | ||
1726 | info->xfpu = NULL; | ||
1727 | #endif | ||
1728 | INIT_LIST_HEAD(&info->thread_list); | 1717 | INIT_LIST_HEAD(&info->thread_list); |
1729 | 1718 | ||
1730 | info->notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote), | 1719 | /* Allocate space for six ELF notes */ |
1731 | GFP_KERNEL); | 1720 | info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL); |
1732 | if (!info->notes) | 1721 | if (!info->notes) |
1733 | return 0; | 1722 | return 0; |
1734 | info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); | 1723 | info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); |
1735 | if (!info->psinfo) | 1724 | if (!info->psinfo) |
1736 | return 0; | 1725 | goto notes_free; |
1737 | info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL); | 1726 | info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL); |
1738 | if (!info->prstatus) | 1727 | if (!info->prstatus) |
1739 | return 0; | 1728 | goto psinfo_free; |
1740 | info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL); | 1729 | info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL); |
1741 | if (!info->fpu) | 1730 | if (!info->fpu) |
1742 | return 0; | 1731 | goto prstatus_free; |
1743 | #ifdef ELF_CORE_COPY_XFPREGS | 1732 | #ifdef ELF_CORE_COPY_XFPREGS |
1744 | info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL); | 1733 | info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL); |
1745 | if (!info->xfpu) | 1734 | if (!info->xfpu) |
1746 | return 0; | 1735 | goto fpu_free; |
1736 | #endif | ||
1737 | return 1; | ||
1738 | #ifdef ELF_CORE_COPY_XFPREGS | ||
1739 | fpu_free: | ||
1740 | kfree(info->fpu); | ||
1747 | #endif | 1741 | #endif |
1742 | prstatus_free: | ||
1743 | kfree(info->prstatus); | ||
1744 | psinfo_free: | ||
1745 | kfree(info->psinfo); | ||
1746 | notes_free: | ||
1747 | kfree(info->notes); | ||
1748 | return 0; | ||
1749 | } | ||
1750 | |||
1751 | static int fill_note_info(struct elfhdr *elf, int phdrs, | ||
1752 | struct elf_note_info *info, | ||
1753 | long signr, struct pt_regs *regs) | ||
1754 | { | ||
1755 | struct list_head *t; | ||
1756 | |||
1757 | if (!elf_note_info_init(info)) | ||
1758 | return 0; | ||
1748 | 1759 | ||
1749 | info->thread_status_size = 0; | ||
1750 | if (signr) { | 1760 | if (signr) { |
1751 | struct core_thread *ct; | 1761 | struct core_thread *ct; |
1752 | struct elf_thread_status *ets; | 1762 | struct elf_thread_status *ets; |
@@ -1806,8 +1816,6 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1806 | #endif | 1816 | #endif |
1807 | 1817 | ||
1808 | return 1; | 1818 | return 1; |
1809 | |||
1810 | #undef NUM_NOTES | ||
1811 | } | 1819 | } |
1812 | 1820 | ||
1813 | static size_t get_note_info_size(struct elf_note_info *info) | 1821 | static size_t get_note_info_size(struct elf_note_info *info) |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 76285471073e..38502c67987c 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -283,20 +283,23 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
283 | } | 283 | } |
284 | 284 | ||
285 | stack_size = exec_params.stack_size; | 285 | stack_size = exec_params.stack_size; |
286 | if (stack_size < interp_params.stack_size) | ||
287 | stack_size = interp_params.stack_size; | ||
288 | |||
289 | if (exec_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) | 286 | if (exec_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) |
290 | executable_stack = EXSTACK_ENABLE_X; | 287 | executable_stack = EXSTACK_ENABLE_X; |
291 | else if (exec_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK) | 288 | else if (exec_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK) |
292 | executable_stack = EXSTACK_DISABLE_X; | 289 | executable_stack = EXSTACK_DISABLE_X; |
293 | else if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) | ||
294 | executable_stack = EXSTACK_ENABLE_X; | ||
295 | else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK) | ||
296 | executable_stack = EXSTACK_DISABLE_X; | ||
297 | else | 290 | else |
298 | executable_stack = EXSTACK_DEFAULT; | 291 | executable_stack = EXSTACK_DEFAULT; |
299 | 292 | ||
293 | if (stack_size == 0) { | ||
294 | stack_size = interp_params.stack_size; | ||
295 | if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) | ||
296 | executable_stack = EXSTACK_ENABLE_X; | ||
297 | else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK) | ||
298 | executable_stack = EXSTACK_DISABLE_X; | ||
299 | else | ||
300 | executable_stack = EXSTACK_DEFAULT; | ||
301 | } | ||
302 | |||
300 | retval = -ENOEXEC; | 303 | retval = -ENOEXEC; |
301 | if (stack_size == 0) | 304 | if (stack_size == 0) |
302 | goto error; | 305 | goto error; |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index e92f229e3c6e..a2796651e756 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -278,8 +278,6 @@ static int decompress_exec( | |||
278 | ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); | 278 | ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); |
279 | if (ret <= 0) | 279 | if (ret <= 0) |
280 | break; | 280 | break; |
281 | if (ret >= (unsigned long) -4096) | ||
282 | break; | ||
283 | len -= ret; | 281 | len -= ret; |
284 | 282 | ||
285 | strm.next_in = buf; | 283 | strm.next_in = buf; |
@@ -335,7 +333,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp) | |||
335 | "(%d != %d)", (unsigned) r, curid, id); | 333 | "(%d != %d)", (unsigned) r, curid, id); |
336 | goto failed; | 334 | goto failed; |
337 | } else if ( ! p->lib_list[id].loaded && | 335 | } else if ( ! p->lib_list[id].loaded && |
338 | load_flat_shared_library(id, p) > (unsigned long) -4096) { | 336 | IS_ERR_VALUE(load_flat_shared_library(id, p))) { |
339 | printk("BINFMT_FLAT: failed to load library %d", id); | 337 | printk("BINFMT_FLAT: failed to load library %d", id); |
340 | goto failed; | 338 | goto failed; |
341 | } | 339 | } |
@@ -545,7 +543,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
545 | textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, | 543 | textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, |
546 | MAP_PRIVATE|MAP_EXECUTABLE, 0); | 544 | MAP_PRIVATE|MAP_EXECUTABLE, 0); |
547 | up_write(¤t->mm->mmap_sem); | 545 | up_write(¤t->mm->mmap_sem); |
548 | if (!textpos || textpos >= (unsigned long) -4096) { | 546 | if (!textpos || IS_ERR_VALUE(textpos)) { |
549 | if (!textpos) | 547 | if (!textpos) |
550 | textpos = (unsigned long) -ENOMEM; | 548 | textpos = (unsigned long) -ENOMEM; |
551 | printk("Unable to mmap process text, errno %d\n", (int)-textpos); | 549 | printk("Unable to mmap process text, errno %d\n", (int)-textpos); |
@@ -560,7 +558,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
560 | PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); | 558 | PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); |
561 | up_write(¤t->mm->mmap_sem); | 559 | up_write(¤t->mm->mmap_sem); |
562 | 560 | ||
563 | if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { | 561 | if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { |
564 | if (!realdatastart) | 562 | if (!realdatastart) |
565 | realdatastart = (unsigned long) -ENOMEM; | 563 | realdatastart = (unsigned long) -ENOMEM; |
566 | printk("Unable to allocate RAM for process data, errno %d\n", | 564 | printk("Unable to allocate RAM for process data, errno %d\n", |
@@ -587,7 +585,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
587 | result = bprm->file->f_op->read(bprm->file, (char *) datapos, | 585 | result = bprm->file->f_op->read(bprm->file, (char *) datapos, |
588 | data_len + (relocs * sizeof(unsigned long)), &fpos); | 586 | data_len + (relocs * sizeof(unsigned long)), &fpos); |
589 | } | 587 | } |
590 | if (result >= (unsigned long)-4096) { | 588 | if (IS_ERR_VALUE(result)) { |
591 | printk("Unable to read data+bss, errno %d\n", (int)-result); | 589 | printk("Unable to read data+bss, errno %d\n", (int)-result); |
592 | do_munmap(current->mm, textpos, text_len); | 590 | do_munmap(current->mm, textpos, text_len); |
593 | do_munmap(current->mm, realdatastart, data_len + extra); | 591 | do_munmap(current->mm, realdatastart, data_len + extra); |
@@ -607,7 +605,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
607 | PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); | 605 | PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); |
608 | up_write(¤t->mm->mmap_sem); | 606 | up_write(¤t->mm->mmap_sem); |
609 | 607 | ||
610 | if (!textpos || textpos >= (unsigned long) -4096) { | 608 | if (!textpos || IS_ERR_VALUE(textpos)) { |
611 | if (!textpos) | 609 | if (!textpos) |
612 | textpos = (unsigned long) -ENOMEM; | 610 | textpos = (unsigned long) -ENOMEM; |
613 | printk("Unable to allocate RAM for process text/data, errno %d\n", | 611 | printk("Unable to allocate RAM for process text/data, errno %d\n", |
@@ -641,7 +639,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
641 | fpos = 0; | 639 | fpos = 0; |
642 | result = bprm->file->f_op->read(bprm->file, | 640 | result = bprm->file->f_op->read(bprm->file, |
643 | (char *) textpos, text_len, &fpos); | 641 | (char *) textpos, text_len, &fpos); |
644 | if (result < (unsigned long) -4096) | 642 | if (!IS_ERR_VALUE(result)) |
645 | result = decompress_exec(bprm, text_len, (char *) datapos, | 643 | result = decompress_exec(bprm, text_len, (char *) datapos, |
646 | data_len + (relocs * sizeof(unsigned long)), 0); | 644 | data_len + (relocs * sizeof(unsigned long)), 0); |
647 | } | 645 | } |
@@ -651,13 +649,13 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
651 | fpos = 0; | 649 | fpos = 0; |
652 | result = bprm->file->f_op->read(bprm->file, | 650 | result = bprm->file->f_op->read(bprm->file, |
653 | (char *) textpos, text_len, &fpos); | 651 | (char *) textpos, text_len, &fpos); |
654 | if (result < (unsigned long) -4096) { | 652 | if (!IS_ERR_VALUE(result)) { |
655 | fpos = ntohl(hdr->data_start); | 653 | fpos = ntohl(hdr->data_start); |
656 | result = bprm->file->f_op->read(bprm->file, (char *) datapos, | 654 | result = bprm->file->f_op->read(bprm->file, (char *) datapos, |
657 | data_len + (relocs * sizeof(unsigned long)), &fpos); | 655 | data_len + (relocs * sizeof(unsigned long)), &fpos); |
658 | } | 656 | } |
659 | } | 657 | } |
660 | if (result >= (unsigned long)-4096) { | 658 | if (IS_ERR_VALUE(result)) { |
661 | printk("Unable to read code+data+bss, errno %d\n",(int)-result); | 659 | printk("Unable to read code+data+bss, errno %d\n",(int)-result); |
662 | do_munmap(current->mm, textpos, text_len + data_len + extra + | 660 | do_munmap(current->mm, textpos, text_len + data_len + extra + |
663 | MAX_SHARED_LIBS * sizeof(unsigned long)); | 661 | MAX_SHARED_LIBS * sizeof(unsigned long)); |
@@ -835,7 +833,7 @@ static int load_flat_shared_library(int id, struct lib_info *libs) | |||
835 | 833 | ||
836 | res = prepare_binprm(&bprm); | 834 | res = prepare_binprm(&bprm); |
837 | 835 | ||
838 | if (res <= (unsigned long)-4096) | 836 | if (!IS_ERR_VALUE(res)) |
839 | res = load_flat_file(&bprm, libs, id, NULL); | 837 | res = load_flat_file(&bprm, libs, id, NULL); |
840 | 838 | ||
841 | abort_creds(bprm.cred); | 839 | abort_creds(bprm.cred); |
@@ -880,7 +878,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
880 | stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */ | 878 | stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */ |
881 | 879 | ||
882 | res = load_flat_file(bprm, &libinfo, 0, &stack_len); | 880 | res = load_flat_file(bprm, &libinfo, 0, &stack_len); |
883 | if (res > (unsigned long)-4096) | 881 | if (IS_ERR_VALUE(res)) |
884 | return res; | 882 | return res; |
885 | 883 | ||
886 | /* Update data segment pointers for all libraries */ | 884 | /* Update data segment pointers for all libraries */ |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 5d1ed50bd46c..9cf4b926f8e4 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -216,8 +216,6 @@ EXPORT_SYMBOL(fsync_bdev); | |||
216 | * freeze_bdev -- lock a filesystem and force it into a consistent state | 216 | * freeze_bdev -- lock a filesystem and force it into a consistent state |
217 | * @bdev: blockdevice to lock | 217 | * @bdev: blockdevice to lock |
218 | * | 218 | * |
219 | * This takes the block device bd_mount_sem to make sure no new mounts | ||
220 | * happen on bdev until thaw_bdev() is called. | ||
221 | * If a superblock is found on this device, we take the s_umount semaphore | 219 | * If a superblock is found on this device, we take the s_umount semaphore |
222 | * on it to make sure nobody unmounts until the snapshot creation is done. | 220 | * on it to make sure nobody unmounts until the snapshot creation is done. |
223 | * The reference counter (bd_fsfreeze_count) guarantees that only the last | 221 | * The reference counter (bd_fsfreeze_count) guarantees that only the last |
@@ -232,46 +230,55 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
232 | int error = 0; | 230 | int error = 0; |
233 | 231 | ||
234 | mutex_lock(&bdev->bd_fsfreeze_mutex); | 232 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
235 | if (bdev->bd_fsfreeze_count > 0) { | 233 | if (++bdev->bd_fsfreeze_count > 1) { |
236 | bdev->bd_fsfreeze_count++; | 234 | /* |
235 | * We don't even need to grab a reference - the first call | ||
236 | * to freeze_bdev grab an active reference and only the last | ||
237 | * thaw_bdev drops it. | ||
238 | */ | ||
237 | sb = get_super(bdev); | 239 | sb = get_super(bdev); |
240 | drop_super(sb); | ||
238 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 241 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
239 | return sb; | 242 | return sb; |
240 | } | 243 | } |
241 | bdev->bd_fsfreeze_count++; | 244 | |
242 | 245 | sb = get_active_super(bdev); | |
243 | down(&bdev->bd_mount_sem); | 246 | if (!sb) |
244 | sb = get_super(bdev); | 247 | goto out; |
245 | if (sb && !(sb->s_flags & MS_RDONLY)) { | 248 | if (sb->s_flags & MS_RDONLY) { |
246 | sb->s_frozen = SB_FREEZE_WRITE; | 249 | deactivate_locked_super(sb); |
247 | smp_wmb(); | 250 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
248 | 251 | return sb; | |
249 | sync_filesystem(sb); | 252 | } |
250 | 253 | ||
251 | sb->s_frozen = SB_FREEZE_TRANS; | 254 | sb->s_frozen = SB_FREEZE_WRITE; |
252 | smp_wmb(); | 255 | smp_wmb(); |
253 | 256 | ||
254 | sync_blockdev(sb->s_bdev); | 257 | sync_filesystem(sb); |
255 | 258 | ||
256 | if (sb->s_op->freeze_fs) { | 259 | sb->s_frozen = SB_FREEZE_TRANS; |
257 | error = sb->s_op->freeze_fs(sb); | 260 | smp_wmb(); |
258 | if (error) { | 261 | |
259 | printk(KERN_ERR | 262 | sync_blockdev(sb->s_bdev); |
260 | "VFS:Filesystem freeze failed\n"); | 263 | |
261 | sb->s_frozen = SB_UNFROZEN; | 264 | if (sb->s_op->freeze_fs) { |
262 | drop_super(sb); | 265 | error = sb->s_op->freeze_fs(sb); |
263 | up(&bdev->bd_mount_sem); | 266 | if (error) { |
264 | bdev->bd_fsfreeze_count--; | 267 | printk(KERN_ERR |
265 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 268 | "VFS:Filesystem freeze failed\n"); |
266 | return ERR_PTR(error); | 269 | sb->s_frozen = SB_UNFROZEN; |
267 | } | 270 | deactivate_locked_super(sb); |
271 | bdev->bd_fsfreeze_count--; | ||
272 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
273 | return ERR_PTR(error); | ||
268 | } | 274 | } |
269 | } | 275 | } |
276 | up_write(&sb->s_umount); | ||
270 | 277 | ||
278 | out: | ||
271 | sync_blockdev(bdev); | 279 | sync_blockdev(bdev); |
272 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 280 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
273 | 281 | return sb; /* thaw_bdev releases s->s_umount */ | |
274 | return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */ | ||
275 | } | 282 | } |
276 | EXPORT_SYMBOL(freeze_bdev); | 283 | EXPORT_SYMBOL(freeze_bdev); |
277 | 284 | ||
@@ -284,44 +291,44 @@ EXPORT_SYMBOL(freeze_bdev); | |||
284 | */ | 291 | */ |
285 | int thaw_bdev(struct block_device *bdev, struct super_block *sb) | 292 | int thaw_bdev(struct block_device *bdev, struct super_block *sb) |
286 | { | 293 | { |
287 | int error = 0; | 294 | int error = -EINVAL; |
288 | 295 | ||
289 | mutex_lock(&bdev->bd_fsfreeze_mutex); | 296 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
290 | if (!bdev->bd_fsfreeze_count) { | 297 | if (!bdev->bd_fsfreeze_count) |
291 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 298 | goto out_unlock; |
292 | return -EINVAL; | 299 | |
293 | } | 300 | error = 0; |
294 | 301 | if (--bdev->bd_fsfreeze_count > 0) | |
295 | bdev->bd_fsfreeze_count--; | 302 | goto out_unlock; |
296 | if (bdev->bd_fsfreeze_count > 0) { | 303 | |
297 | if (sb) | 304 | if (!sb) |
298 | drop_super(sb); | 305 | goto out_unlock; |
299 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 306 | |
300 | return 0; | 307 | BUG_ON(sb->s_bdev != bdev); |
301 | } | 308 | down_write(&sb->s_umount); |
302 | 309 | if (sb->s_flags & MS_RDONLY) | |
303 | if (sb) { | 310 | goto out_deactivate; |
304 | BUG_ON(sb->s_bdev != bdev); | 311 | |
305 | if (!(sb->s_flags & MS_RDONLY)) { | 312 | if (sb->s_op->unfreeze_fs) { |
306 | if (sb->s_op->unfreeze_fs) { | 313 | error = sb->s_op->unfreeze_fs(sb); |
307 | error = sb->s_op->unfreeze_fs(sb); | 314 | if (error) { |
308 | if (error) { | 315 | printk(KERN_ERR |
309 | printk(KERN_ERR | 316 | "VFS:Filesystem thaw failed\n"); |
310 | "VFS:Filesystem thaw failed\n"); | 317 | sb->s_frozen = SB_FREEZE_TRANS; |
311 | sb->s_frozen = SB_FREEZE_TRANS; | 318 | bdev->bd_fsfreeze_count++; |
312 | bdev->bd_fsfreeze_count++; | 319 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
313 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 320 | return error; |
314 | return error; | ||
315 | } | ||
316 | } | ||
317 | sb->s_frozen = SB_UNFROZEN; | ||
318 | smp_wmb(); | ||
319 | wake_up(&sb->s_wait_unfrozen); | ||
320 | } | 321 | } |
321 | drop_super(sb); | ||
322 | } | 322 | } |
323 | 323 | ||
324 | up(&bdev->bd_mount_sem); | 324 | sb->s_frozen = SB_UNFROZEN; |
325 | smp_wmb(); | ||
326 | wake_up(&sb->s_wait_unfrozen); | ||
327 | |||
328 | out_deactivate: | ||
329 | if (sb) | ||
330 | deactivate_locked_super(sb); | ||
331 | out_unlock: | ||
325 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 332 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
326 | return 0; | 333 | return 0; |
327 | } | 334 | } |
@@ -430,7 +437,6 @@ static void init_once(void *foo) | |||
430 | 437 | ||
431 | memset(bdev, 0, sizeof(*bdev)); | 438 | memset(bdev, 0, sizeof(*bdev)); |
432 | mutex_init(&bdev->bd_mutex); | 439 | mutex_init(&bdev->bd_mutex); |
433 | sema_init(&bdev->bd_mount_sem, 1); | ||
434 | INIT_LIST_HEAD(&bdev->bd_inodes); | 440 | INIT_LIST_HEAD(&bdev->bd_inodes); |
435 | INIT_LIST_HEAD(&bdev->bd_list); | 441 | INIT_LIST_HEAD(&bdev->bd_list); |
436 | #ifdef CONFIG_SYSFS | 442 | #ifdef CONFIG_SYSFS |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 976bfda032e0..e9b76bcd1c12 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -5590,6 +5590,7 @@ static const struct address_space_operations btrfs_aops = { | |||
5590 | .invalidatepage = btrfs_invalidatepage, | 5590 | .invalidatepage = btrfs_invalidatepage, |
5591 | .releasepage = btrfs_releasepage, | 5591 | .releasepage = btrfs_releasepage, |
5592 | .set_page_dirty = btrfs_set_page_dirty, | 5592 | .set_page_dirty = btrfs_set_page_dirty, |
5593 | .error_remove_page = generic_error_remove_page, | ||
5593 | }; | 5594 | }; |
5594 | 5595 | ||
5595 | static const struct address_space_operations btrfs_symlink_aops = { | 5596 | static const struct address_space_operations btrfs_symlink_aops = { |
diff --git a/fs/buffer.c b/fs/buffer.c index 209f7f15f5f8..24afd7422ae8 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2239,16 +2239,10 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size) | |||
2239 | struct address_space *mapping = inode->i_mapping; | 2239 | struct address_space *mapping = inode->i_mapping; |
2240 | struct page *page; | 2240 | struct page *page; |
2241 | void *fsdata; | 2241 | void *fsdata; |
2242 | unsigned long limit; | ||
2243 | int err; | 2242 | int err; |
2244 | 2243 | ||
2245 | err = -EFBIG; | 2244 | err = inode_newsize_ok(inode, size); |
2246 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | 2245 | if (err) |
2247 | if (limit != RLIM_INFINITY && size > (loff_t)limit) { | ||
2248 | send_sig(SIGXFSZ, current, 0); | ||
2249 | goto out; | ||
2250 | } | ||
2251 | if (size > inode->i_sb->s_maxbytes) | ||
2252 | goto out; | 2246 | goto out; |
2253 | 2247 | ||
2254 | err = pagecache_write_begin(NULL, mapping, size, 0, | 2248 | err = pagecache_write_begin(NULL, mapping, size, 0, |
diff --git a/fs/char_dev.c b/fs/char_dev.c index 3cbc57f932d2..d6db933df2b2 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -264,7 +264,6 @@ int __register_chrdev(unsigned int major, unsigned int baseminor, | |||
264 | { | 264 | { |
265 | struct char_device_struct *cd; | 265 | struct char_device_struct *cd; |
266 | struct cdev *cdev; | 266 | struct cdev *cdev; |
267 | char *s; | ||
268 | int err = -ENOMEM; | 267 | int err = -ENOMEM; |
269 | 268 | ||
270 | cd = __register_chrdev_region(major, baseminor, count, name); | 269 | cd = __register_chrdev_region(major, baseminor, count, name); |
@@ -278,8 +277,6 @@ int __register_chrdev(unsigned int major, unsigned int baseminor, | |||
278 | cdev->owner = fops->owner; | 277 | cdev->owner = fops->owner; |
279 | cdev->ops = fops; | 278 | cdev->ops = fops; |
280 | kobject_set_name(&cdev->kobj, "%s", name); | 279 | kobject_set_name(&cdev->kobj, "%s", name); |
281 | for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) | ||
282 | *s = '!'; | ||
283 | 280 | ||
284 | err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); | 281 | err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); |
285 | if (err) | 282 | if (err) |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d79ce2e95c23..90c5b39f0313 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -185,8 +185,7 @@ out_mount_failed: | |||
185 | cifs_sb->mountdata = NULL; | 185 | cifs_sb->mountdata = NULL; |
186 | } | 186 | } |
187 | #endif | 187 | #endif |
188 | if (cifs_sb->local_nls) | 188 | unload_nls(cifs_sb->local_nls); |
189 | unload_nls(cifs_sb->local_nls); | ||
190 | kfree(cifs_sb); | 189 | kfree(cifs_sb); |
191 | } | 190 | } |
192 | return rc; | 191 | return rc; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 1f09c7619319..5e2492535daa 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1557,57 +1557,24 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from) | |||
1557 | 1557 | ||
1558 | static int cifs_vmtruncate(struct inode *inode, loff_t offset) | 1558 | static int cifs_vmtruncate(struct inode *inode, loff_t offset) |
1559 | { | 1559 | { |
1560 | struct address_space *mapping = inode->i_mapping; | 1560 | loff_t oldsize; |
1561 | unsigned long limit; | 1561 | int err; |
1562 | 1562 | ||
1563 | spin_lock(&inode->i_lock); | 1563 | spin_lock(&inode->i_lock); |
1564 | if (inode->i_size < offset) | 1564 | err = inode_newsize_ok(inode, offset); |
1565 | goto do_expand; | 1565 | if (err) { |
1566 | /* | ||
1567 | * truncation of in-use swapfiles is disallowed - it would cause | ||
1568 | * subsequent swapout to scribble on the now-freed blocks. | ||
1569 | */ | ||
1570 | if (IS_SWAPFILE(inode)) { | ||
1571 | spin_unlock(&inode->i_lock); | ||
1572 | goto out_busy; | ||
1573 | } | ||
1574 | i_size_write(inode, offset); | ||
1575 | spin_unlock(&inode->i_lock); | ||
1576 | /* | ||
1577 | * unmap_mapping_range is called twice, first simply for efficiency | ||
1578 | * so that truncate_inode_pages does fewer single-page unmaps. However | ||
1579 | * after this first call, and before truncate_inode_pages finishes, | ||
1580 | * it is possible for private pages to be COWed, which remain after | ||
1581 | * truncate_inode_pages finishes, hence the second unmap_mapping_range | ||
1582 | * call must be made for correctness. | ||
1583 | */ | ||
1584 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
1585 | truncate_inode_pages(mapping, offset); | ||
1586 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
1587 | goto out_truncate; | ||
1588 | |||
1589 | do_expand: | ||
1590 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
1591 | if (limit != RLIM_INFINITY && offset > limit) { | ||
1592 | spin_unlock(&inode->i_lock); | 1566 | spin_unlock(&inode->i_lock); |
1593 | goto out_sig; | 1567 | goto out; |
1594 | } | ||
1595 | if (offset > inode->i_sb->s_maxbytes) { | ||
1596 | spin_unlock(&inode->i_lock); | ||
1597 | goto out_big; | ||
1598 | } | 1568 | } |
1569 | |||
1570 | oldsize = inode->i_size; | ||
1599 | i_size_write(inode, offset); | 1571 | i_size_write(inode, offset); |
1600 | spin_unlock(&inode->i_lock); | 1572 | spin_unlock(&inode->i_lock); |
1601 | out_truncate: | 1573 | truncate_pagecache(inode, oldsize, offset); |
1602 | if (inode->i_op->truncate) | 1574 | if (inode->i_op->truncate) |
1603 | inode->i_op->truncate(inode); | 1575 | inode->i_op->truncate(inode); |
1604 | return 0; | 1576 | out: |
1605 | out_sig: | 1577 | return err; |
1606 | send_sig(SIGXFSZ, current, 0); | ||
1607 | out_big: | ||
1608 | return -EFBIG; | ||
1609 | out_busy: | ||
1610 | return -ETXTBSY; | ||
1611 | } | 1578 | } |
1612 | 1579 | ||
1613 | static int | 1580 | static int |
diff --git a/fs/coda/coda_int.h b/fs/coda/coda_int.h index 8ccd5ed81d9c..d99860a33890 100644 --- a/fs/coda/coda_int.h +++ b/fs/coda/coda_int.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _CODA_INT_ | 2 | #define _CODA_INT_ |
3 | 3 | ||
4 | struct dentry; | 4 | struct dentry; |
5 | struct file; | ||
5 | 6 | ||
6 | extern struct file_system_type coda_fs_type; | 7 | extern struct file_system_type coda_fs_type; |
7 | extern unsigned long coda_timeout; | 8 | extern unsigned long coda_timeout; |
diff --git a/fs/compat.c b/fs/compat.c index 3aa48834a222..d576b552e8e2 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -768,13 +768,13 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | |||
768 | char __user * type, unsigned long flags, | 768 | char __user * type, unsigned long flags, |
769 | void __user * data) | 769 | void __user * data) |
770 | { | 770 | { |
771 | unsigned long type_page; | 771 | char *kernel_type; |
772 | unsigned long data_page; | 772 | unsigned long data_page; |
773 | unsigned long dev_page; | 773 | char *kernel_dev; |
774 | char *dir_page; | 774 | char *dir_page; |
775 | int retval; | 775 | int retval; |
776 | 776 | ||
777 | retval = copy_mount_options (type, &type_page); | 777 | retval = copy_mount_string(type, &kernel_type); |
778 | if (retval < 0) | 778 | if (retval < 0) |
779 | goto out; | 779 | goto out; |
780 | 780 | ||
@@ -783,38 +783,38 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | |||
783 | if (IS_ERR(dir_page)) | 783 | if (IS_ERR(dir_page)) |
784 | goto out1; | 784 | goto out1; |
785 | 785 | ||
786 | retval = copy_mount_options (dev_name, &dev_page); | 786 | retval = copy_mount_string(dev_name, &kernel_dev); |
787 | if (retval < 0) | 787 | if (retval < 0) |
788 | goto out2; | 788 | goto out2; |
789 | 789 | ||
790 | retval = copy_mount_options (data, &data_page); | 790 | retval = copy_mount_options(data, &data_page); |
791 | if (retval < 0) | 791 | if (retval < 0) |
792 | goto out3; | 792 | goto out3; |
793 | 793 | ||
794 | retval = -EINVAL; | 794 | retval = -EINVAL; |
795 | 795 | ||
796 | if (type_page && data_page) { | 796 | if (kernel_type && data_page) { |
797 | if (!strcmp((char *)type_page, SMBFS_NAME)) { | 797 | if (!strcmp(kernel_type, SMBFS_NAME)) { |
798 | do_smb_super_data_conv((void *)data_page); | 798 | do_smb_super_data_conv((void *)data_page); |
799 | } else if (!strcmp((char *)type_page, NCPFS_NAME)) { | 799 | } else if (!strcmp(kernel_type, NCPFS_NAME)) { |
800 | do_ncp_super_data_conv((void *)data_page); | 800 | do_ncp_super_data_conv((void *)data_page); |
801 | } else if (!strcmp((char *)type_page, NFS4_NAME)) { | 801 | } else if (!strcmp(kernel_type, NFS4_NAME)) { |
802 | if (do_nfs4_super_data_conv((void *) data_page)) | 802 | if (do_nfs4_super_data_conv((void *) data_page)) |
803 | goto out4; | 803 | goto out4; |
804 | } | 804 | } |
805 | } | 805 | } |
806 | 806 | ||
807 | retval = do_mount((char*)dev_page, dir_page, (char*)type_page, | 807 | retval = do_mount(kernel_dev, dir_page, kernel_type, |
808 | flags, (void*)data_page); | 808 | flags, (void*)data_page); |
809 | 809 | ||
810 | out4: | 810 | out4: |
811 | free_page(data_page); | 811 | free_page(data_page); |
812 | out3: | 812 | out3: |
813 | free_page(dev_page); | 813 | kfree(kernel_dev); |
814 | out2: | 814 | out2: |
815 | putname(dir_page); | 815 | putname(dir_page); |
816 | out1: | 816 | out1: |
817 | free_page(type_page); | 817 | kfree(kernel_type); |
818 | out: | 818 | out: |
819 | return retval; | 819 | return retval; |
820 | } | 820 | } |
diff --git a/fs/drop_caches.c b/fs/drop_caches.c index a2edb7913447..31f4b0e6d72c 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c | |||
@@ -63,9 +63,9 @@ static void drop_slab(void) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | int drop_caches_sysctl_handler(ctl_table *table, int write, | 65 | int drop_caches_sysctl_handler(ctl_table *table, int write, |
66 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 66 | void __user *buffer, size_t *length, loff_t *ppos) |
67 | { | 67 | { |
68 | proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 68 | proc_dointvec_minmax(table, write, buffer, length, ppos); |
69 | if (write) { | 69 | if (write) { |
70 | if (sysctl_drop_caches & 1) | 70 | if (sysctl_drop_caches & 1) |
71 | drop_pagecache(); | 71 | drop_pagecache(); |
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/kmod.h> | 55 | #include <linux/kmod.h> |
56 | #include <linux/fsnotify.h> | 56 | #include <linux/fsnotify.h> |
57 | #include <linux/fs_struct.h> | 57 | #include <linux/fs_struct.h> |
58 | #include <linux/pipe_fs_i.h> | ||
58 | 59 | ||
59 | #include <asm/uaccess.h> | 60 | #include <asm/uaccess.h> |
60 | #include <asm/mmu_context.h> | 61 | #include <asm/mmu_context.h> |
@@ -63,6 +64,7 @@ | |||
63 | 64 | ||
64 | int core_uses_pid; | 65 | int core_uses_pid; |
65 | char core_pattern[CORENAME_MAX_SIZE] = "core"; | 66 | char core_pattern[CORENAME_MAX_SIZE] = "core"; |
67 | unsigned int core_pipe_limit; | ||
66 | int suid_dumpable = 0; | 68 | int suid_dumpable = 0; |
67 | 69 | ||
68 | /* The maximal length of core_pattern is also specified in sysctl.c */ | 70 | /* The maximal length of core_pattern is also specified in sysctl.c */ |
@@ -1393,18 +1395,16 @@ out_ret: | |||
1393 | return retval; | 1395 | return retval; |
1394 | } | 1396 | } |
1395 | 1397 | ||
1396 | int set_binfmt(struct linux_binfmt *new) | 1398 | void set_binfmt(struct linux_binfmt *new) |
1397 | { | 1399 | { |
1398 | struct linux_binfmt *old = current->binfmt; | 1400 | struct mm_struct *mm = current->mm; |
1399 | 1401 | ||
1400 | if (new) { | 1402 | if (mm->binfmt) |
1401 | if (!try_module_get(new->module)) | 1403 | module_put(mm->binfmt->module); |
1402 | return -1; | 1404 | |
1403 | } | 1405 | mm->binfmt = new; |
1404 | current->binfmt = new; | 1406 | if (new) |
1405 | if (old) | 1407 | __module_get(new->module); |
1406 | module_put(old->module); | ||
1407 | return 0; | ||
1408 | } | 1408 | } |
1409 | 1409 | ||
1410 | EXPORT_SYMBOL(set_binfmt); | 1410 | EXPORT_SYMBOL(set_binfmt); |
@@ -1728,6 +1728,29 @@ int get_dumpable(struct mm_struct *mm) | |||
1728 | return (ret >= 2) ? 2 : ret; | 1728 | return (ret >= 2) ? 2 : ret; |
1729 | } | 1729 | } |
1730 | 1730 | ||
1731 | static void wait_for_dump_helpers(struct file *file) | ||
1732 | { | ||
1733 | struct pipe_inode_info *pipe; | ||
1734 | |||
1735 | pipe = file->f_path.dentry->d_inode->i_pipe; | ||
1736 | |||
1737 | pipe_lock(pipe); | ||
1738 | pipe->readers++; | ||
1739 | pipe->writers--; | ||
1740 | |||
1741 | while ((pipe->readers > 1) && (!signal_pending(current))) { | ||
1742 | wake_up_interruptible_sync(&pipe->wait); | ||
1743 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | ||
1744 | pipe_wait(pipe); | ||
1745 | } | ||
1746 | |||
1747 | pipe->readers--; | ||
1748 | pipe->writers++; | ||
1749 | pipe_unlock(pipe); | ||
1750 | |||
1751 | } | ||
1752 | |||
1753 | |||
1731 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) | 1754 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
1732 | { | 1755 | { |
1733 | struct core_state core_state; | 1756 | struct core_state core_state; |
@@ -1744,11 +1767,12 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1744 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | 1767 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; |
1745 | char **helper_argv = NULL; | 1768 | char **helper_argv = NULL; |
1746 | int helper_argc = 0; | 1769 | int helper_argc = 0; |
1747 | char *delimit; | 1770 | int dump_count = 0; |
1771 | static atomic_t core_dump_count = ATOMIC_INIT(0); | ||
1748 | 1772 | ||
1749 | audit_core_dumps(signr); | 1773 | audit_core_dumps(signr); |
1750 | 1774 | ||
1751 | binfmt = current->binfmt; | 1775 | binfmt = mm->binfmt; |
1752 | if (!binfmt || !binfmt->core_dump) | 1776 | if (!binfmt || !binfmt->core_dump) |
1753 | goto fail; | 1777 | goto fail; |
1754 | 1778 | ||
@@ -1799,54 +1823,63 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1799 | lock_kernel(); | 1823 | lock_kernel(); |
1800 | ispipe = format_corename(corename, signr); | 1824 | ispipe = format_corename(corename, signr); |
1801 | unlock_kernel(); | 1825 | unlock_kernel(); |
1802 | /* | 1826 | |
1803 | * Don't bother to check the RLIMIT_CORE value if core_pattern points | ||
1804 | * to a pipe. Since we're not writing directly to the filesystem | ||
1805 | * RLIMIT_CORE doesn't really apply, as no actual core file will be | ||
1806 | * created unless the pipe reader choses to write out the core file | ||
1807 | * at which point file size limits and permissions will be imposed | ||
1808 | * as it does with any other process | ||
1809 | */ | ||
1810 | if ((!ispipe) && (core_limit < binfmt->min_coredump)) | 1827 | if ((!ispipe) && (core_limit < binfmt->min_coredump)) |
1811 | goto fail_unlock; | 1828 | goto fail_unlock; |
1812 | 1829 | ||
1813 | if (ispipe) { | 1830 | if (ispipe) { |
1831 | if (core_limit == 0) { | ||
1832 | /* | ||
1833 | * Normally core limits are irrelevant to pipes, since | ||
1834 | * we're not writing to the file system, but we use | ||
1835 | * core_limit of 0 here as a speacial value. Any | ||
1836 | * non-zero limit gets set to RLIM_INFINITY below, but | ||
1837 | * a limit of 0 skips the dump. This is a consistent | ||
1838 | * way to catch recursive crashes. We can still crash | ||
1839 | * if the core_pattern binary sets RLIM_CORE = !0 | ||
1840 | * but it runs as root, and can do lots of stupid things | ||
1841 | * Note that we use task_tgid_vnr here to grab the pid | ||
1842 | * of the process group leader. That way we get the | ||
1843 | * right pid if a thread in a multi-threaded | ||
1844 | * core_pattern process dies. | ||
1845 | */ | ||
1846 | printk(KERN_WARNING | ||
1847 | "Process %d(%s) has RLIMIT_CORE set to 0\n", | ||
1848 | task_tgid_vnr(current), current->comm); | ||
1849 | printk(KERN_WARNING "Aborting core\n"); | ||
1850 | goto fail_unlock; | ||
1851 | } | ||
1852 | |||
1853 | dump_count = atomic_inc_return(&core_dump_count); | ||
1854 | if (core_pipe_limit && (core_pipe_limit < dump_count)) { | ||
1855 | printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", | ||
1856 | task_tgid_vnr(current), current->comm); | ||
1857 | printk(KERN_WARNING "Skipping core dump\n"); | ||
1858 | goto fail_dropcount; | ||
1859 | } | ||
1860 | |||
1814 | helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); | 1861 | helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); |
1815 | if (!helper_argv) { | 1862 | if (!helper_argv) { |
1816 | printk(KERN_WARNING "%s failed to allocate memory\n", | 1863 | printk(KERN_WARNING "%s failed to allocate memory\n", |
1817 | __func__); | 1864 | __func__); |
1818 | goto fail_unlock; | 1865 | goto fail_dropcount; |
1819 | } | ||
1820 | /* Terminate the string before the first option */ | ||
1821 | delimit = strchr(corename, ' '); | ||
1822 | if (delimit) | ||
1823 | *delimit = '\0'; | ||
1824 | delimit = strrchr(helper_argv[0], '/'); | ||
1825 | if (delimit) | ||
1826 | delimit++; | ||
1827 | else | ||
1828 | delimit = helper_argv[0]; | ||
1829 | if (!strcmp(delimit, current->comm)) { | ||
1830 | printk(KERN_NOTICE "Recursive core dump detected, " | ||
1831 | "aborting\n"); | ||
1832 | goto fail_unlock; | ||
1833 | } | 1866 | } |
1834 | 1867 | ||
1835 | core_limit = RLIM_INFINITY; | 1868 | core_limit = RLIM_INFINITY; |
1836 | 1869 | ||
1837 | /* SIGPIPE can happen, but it's just never processed */ | 1870 | /* SIGPIPE can happen, but it's just never processed */ |
1838 | if (call_usermodehelper_pipe(corename+1, helper_argv, NULL, | 1871 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, |
1839 | &file)) { | 1872 | &file)) { |
1840 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1873 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1841 | corename); | 1874 | corename); |
1842 | goto fail_unlock; | 1875 | goto fail_dropcount; |
1843 | } | 1876 | } |
1844 | } else | 1877 | } else |
1845 | file = filp_open(corename, | 1878 | file = filp_open(corename, |
1846 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, | 1879 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1847 | 0600); | 1880 | 0600); |
1848 | if (IS_ERR(file)) | 1881 | if (IS_ERR(file)) |
1849 | goto fail_unlock; | 1882 | goto fail_dropcount; |
1850 | inode = file->f_path.dentry->d_inode; | 1883 | inode = file->f_path.dentry->d_inode; |
1851 | if (inode->i_nlink > 1) | 1884 | if (inode->i_nlink > 1) |
1852 | goto close_fail; /* multiple links - don't dump */ | 1885 | goto close_fail; /* multiple links - don't dump */ |
@@ -1875,7 +1908,12 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1875 | if (retval) | 1908 | if (retval) |
1876 | current->signal->group_exit_code |= 0x80; | 1909 | current->signal->group_exit_code |= 0x80; |
1877 | close_fail: | 1910 | close_fail: |
1911 | if (ispipe && core_pipe_limit) | ||
1912 | wait_for_dump_helpers(file); | ||
1878 | filp_close(file, NULL); | 1913 | filp_close(file, NULL); |
1914 | fail_dropcount: | ||
1915 | if (dump_count) | ||
1916 | atomic_dec(&core_dump_count); | ||
1879 | fail_unlock: | 1917 | fail_unlock: |
1880 | if (helper_argv) | 1918 | if (helper_argv) |
1881 | argv_free(helper_argv); | 1919 | argv_free(helper_argv); |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 5ab10c3bbebe..9f500dec3b59 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -214,7 +214,6 @@ int exofs_sync_fs(struct super_block *sb, int wait) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | lock_super(sb); | 216 | lock_super(sb); |
217 | lock_kernel(); | ||
218 | sbi = sb->s_fs_info; | 217 | sbi = sb->s_fs_info; |
219 | fscb->s_nextid = cpu_to_le64(sbi->s_nextid); | 218 | fscb->s_nextid = cpu_to_le64(sbi->s_nextid); |
220 | fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles); | 219 | fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles); |
@@ -245,7 +244,6 @@ int exofs_sync_fs(struct super_block *sb, int wait) | |||
245 | out: | 244 | out: |
246 | if (or) | 245 | if (or) |
247 | osd_end_request(or); | 246 | osd_end_request(or); |
248 | unlock_kernel(); | ||
249 | unlock_super(sb); | 247 | unlock_super(sb); |
250 | kfree(fscb); | 248 | kfree(fscb); |
251 | return ret; | 249 | return ret; |
@@ -268,8 +266,6 @@ static void exofs_put_super(struct super_block *sb) | |||
268 | int num_pend; | 266 | int num_pend; |
269 | struct exofs_sb_info *sbi = sb->s_fs_info; | 267 | struct exofs_sb_info *sbi = sb->s_fs_info; |
270 | 268 | ||
271 | lock_kernel(); | ||
272 | |||
273 | if (sb->s_dirt) | 269 | if (sb->s_dirt) |
274 | exofs_write_super(sb); | 270 | exofs_write_super(sb); |
275 | 271 | ||
@@ -286,8 +282,6 @@ static void exofs_put_super(struct super_block *sb) | |||
286 | osduld_put_device(sbi->s_dev); | 282 | osduld_put_device(sbi->s_dev); |
287 | kfree(sb->s_fs_info); | 283 | kfree(sb->s_fs_info); |
288 | sb->s_fs_info = NULL; | 284 | sb->s_fs_info = NULL; |
289 | |||
290 | unlock_kernel(); | ||
291 | } | 285 | } |
292 | 286 | ||
293 | /* | 287 | /* |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 1c1638f873a4..ade634076d0a 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -819,6 +819,7 @@ const struct address_space_operations ext2_aops = { | |||
819 | .writepages = ext2_writepages, | 819 | .writepages = ext2_writepages, |
820 | .migratepage = buffer_migrate_page, | 820 | .migratepage = buffer_migrate_page, |
821 | .is_partially_uptodate = block_is_partially_uptodate, | 821 | .is_partially_uptodate = block_is_partially_uptodate, |
822 | .error_remove_page = generic_error_remove_page, | ||
822 | }; | 823 | }; |
823 | 824 | ||
824 | const struct address_space_operations ext2_aops_xip = { | 825 | const struct address_space_operations ext2_aops_xip = { |
@@ -837,6 +838,7 @@ const struct address_space_operations ext2_nobh_aops = { | |||
837 | .direct_IO = ext2_direct_IO, | 838 | .direct_IO = ext2_direct_IO, |
838 | .writepages = ext2_writepages, | 839 | .writepages = ext2_writepages, |
839 | .migratepage = buffer_migrate_page, | 840 | .migratepage = buffer_migrate_page, |
841 | .error_remove_page = generic_error_remove_page, | ||
840 | }; | 842 | }; |
841 | 843 | ||
842 | /* | 844 | /* |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index cd098a7b77fc..acf1b1423327 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1830,6 +1830,7 @@ static const struct address_space_operations ext3_ordered_aops = { | |||
1830 | .direct_IO = ext3_direct_IO, | 1830 | .direct_IO = ext3_direct_IO, |
1831 | .migratepage = buffer_migrate_page, | 1831 | .migratepage = buffer_migrate_page, |
1832 | .is_partially_uptodate = block_is_partially_uptodate, | 1832 | .is_partially_uptodate = block_is_partially_uptodate, |
1833 | .error_remove_page = generic_error_remove_page, | ||
1833 | }; | 1834 | }; |
1834 | 1835 | ||
1835 | static const struct address_space_operations ext3_writeback_aops = { | 1836 | static const struct address_space_operations ext3_writeback_aops = { |
@@ -1845,6 +1846,7 @@ static const struct address_space_operations ext3_writeback_aops = { | |||
1845 | .direct_IO = ext3_direct_IO, | 1846 | .direct_IO = ext3_direct_IO, |
1846 | .migratepage = buffer_migrate_page, | 1847 | .migratepage = buffer_migrate_page, |
1847 | .is_partially_uptodate = block_is_partially_uptodate, | 1848 | .is_partially_uptodate = block_is_partially_uptodate, |
1849 | .error_remove_page = generic_error_remove_page, | ||
1848 | }; | 1850 | }; |
1849 | 1851 | ||
1850 | static const struct address_space_operations ext3_journalled_aops = { | 1852 | static const struct address_space_operations ext3_journalled_aops = { |
@@ -1859,6 +1861,7 @@ static const struct address_space_operations ext3_journalled_aops = { | |||
1859 | .invalidatepage = ext3_invalidatepage, | 1861 | .invalidatepage = ext3_invalidatepage, |
1860 | .releasepage = ext3_releasepage, | 1862 | .releasepage = ext3_releasepage, |
1861 | .is_partially_uptodate = block_is_partially_uptodate, | 1863 | .is_partially_uptodate = block_is_partially_uptodate, |
1864 | .error_remove_page = generic_error_remove_page, | ||
1862 | }; | 1865 | }; |
1863 | 1866 | ||
1864 | void ext3_set_aops(struct inode *inode) | 1867 | void ext3_set_aops(struct inode *inode) |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 3a798737e305..064746fad581 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -3386,6 +3386,7 @@ static const struct address_space_operations ext4_ordered_aops = { | |||
3386 | .direct_IO = ext4_direct_IO, | 3386 | .direct_IO = ext4_direct_IO, |
3387 | .migratepage = buffer_migrate_page, | 3387 | .migratepage = buffer_migrate_page, |
3388 | .is_partially_uptodate = block_is_partially_uptodate, | 3388 | .is_partially_uptodate = block_is_partially_uptodate, |
3389 | .error_remove_page = generic_error_remove_page, | ||
3389 | }; | 3390 | }; |
3390 | 3391 | ||
3391 | static const struct address_space_operations ext4_writeback_aops = { | 3392 | static const struct address_space_operations ext4_writeback_aops = { |
@@ -3401,6 +3402,7 @@ static const struct address_space_operations ext4_writeback_aops = { | |||
3401 | .direct_IO = ext4_direct_IO, | 3402 | .direct_IO = ext4_direct_IO, |
3402 | .migratepage = buffer_migrate_page, | 3403 | .migratepage = buffer_migrate_page, |
3403 | .is_partially_uptodate = block_is_partially_uptodate, | 3404 | .is_partially_uptodate = block_is_partially_uptodate, |
3405 | .error_remove_page = generic_error_remove_page, | ||
3404 | }; | 3406 | }; |
3405 | 3407 | ||
3406 | static const struct address_space_operations ext4_journalled_aops = { | 3408 | static const struct address_space_operations ext4_journalled_aops = { |
@@ -3415,6 +3417,7 @@ static const struct address_space_operations ext4_journalled_aops = { | |||
3415 | .invalidatepage = ext4_invalidatepage, | 3417 | .invalidatepage = ext4_invalidatepage, |
3416 | .releasepage = ext4_releasepage, | 3418 | .releasepage = ext4_releasepage, |
3417 | .is_partially_uptodate = block_is_partially_uptodate, | 3419 | .is_partially_uptodate = block_is_partially_uptodate, |
3420 | .error_remove_page = generic_error_remove_page, | ||
3418 | }; | 3421 | }; |
3419 | 3422 | ||
3420 | static const struct address_space_operations ext4_da_aops = { | 3423 | static const struct address_space_operations ext4_da_aops = { |
@@ -3431,6 +3434,7 @@ static const struct address_space_operations ext4_da_aops = { | |||
3431 | .direct_IO = ext4_direct_IO, | 3434 | .direct_IO = ext4_direct_IO, |
3432 | .migratepage = buffer_migrate_page, | 3435 | .migratepage = buffer_migrate_page, |
3433 | .is_partially_uptodate = block_is_partially_uptodate, | 3436 | .is_partially_uptodate = block_is_partially_uptodate, |
3437 | .error_remove_page = generic_error_remove_page, | ||
3434 | }; | 3438 | }; |
3435 | 3439 | ||
3436 | void ext4_set_aops(struct inode *inode) | 3440 | void ext4_set_aops(struct inode *inode) |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 8970d8c49bb0..04629d1302fc 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -470,19 +470,11 @@ static void fat_put_super(struct super_block *sb) | |||
470 | 470 | ||
471 | iput(sbi->fat_inode); | 471 | iput(sbi->fat_inode); |
472 | 472 | ||
473 | if (sbi->nls_disk) { | 473 | unload_nls(sbi->nls_disk); |
474 | unload_nls(sbi->nls_disk); | 474 | unload_nls(sbi->nls_io); |
475 | sbi->nls_disk = NULL; | 475 | |
476 | sbi->options.codepage = fat_default_codepage; | 476 | if (sbi->options.iocharset != fat_default_iocharset) |
477 | } | ||
478 | if (sbi->nls_io) { | ||
479 | unload_nls(sbi->nls_io); | ||
480 | sbi->nls_io = NULL; | ||
481 | } | ||
482 | if (sbi->options.iocharset != fat_default_iocharset) { | ||
483 | kfree(sbi->options.iocharset); | 477 | kfree(sbi->options.iocharset); |
484 | sbi->options.iocharset = fat_default_iocharset; | ||
485 | } | ||
486 | 478 | ||
487 | sb->s_fs_info = NULL; | 479 | sb->s_fs_info = NULL; |
488 | kfree(sbi); | 480 | kfree(sbi); |
diff --git a/fs/fcntl.c b/fs/fcntl.c index ae413086db97..fc089f2f7f56 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -263,6 +263,79 @@ pid_t f_getown(struct file *filp) | |||
263 | return pid; | 263 | return pid; |
264 | } | 264 | } |
265 | 265 | ||
266 | static int f_setown_ex(struct file *filp, unsigned long arg) | ||
267 | { | ||
268 | struct f_owner_ex * __user owner_p = (void * __user)arg; | ||
269 | struct f_owner_ex owner; | ||
270 | struct pid *pid; | ||
271 | int type; | ||
272 | int ret; | ||
273 | |||
274 | ret = copy_from_user(&owner, owner_p, sizeof(owner)); | ||
275 | if (ret) | ||
276 | return ret; | ||
277 | |||
278 | switch (owner.type) { | ||
279 | case F_OWNER_TID: | ||
280 | type = PIDTYPE_MAX; | ||
281 | break; | ||
282 | |||
283 | case F_OWNER_PID: | ||
284 | type = PIDTYPE_PID; | ||
285 | break; | ||
286 | |||
287 | case F_OWNER_GID: | ||
288 | type = PIDTYPE_PGID; | ||
289 | break; | ||
290 | |||
291 | default: | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
295 | rcu_read_lock(); | ||
296 | pid = find_vpid(owner.pid); | ||
297 | if (owner.pid && !pid) | ||
298 | ret = -ESRCH; | ||
299 | else | ||
300 | ret = __f_setown(filp, pid, type, 1); | ||
301 | rcu_read_unlock(); | ||
302 | |||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | static int f_getown_ex(struct file *filp, unsigned long arg) | ||
307 | { | ||
308 | struct f_owner_ex * __user owner_p = (void * __user)arg; | ||
309 | struct f_owner_ex owner; | ||
310 | int ret = 0; | ||
311 | |||
312 | read_lock(&filp->f_owner.lock); | ||
313 | owner.pid = pid_vnr(filp->f_owner.pid); | ||
314 | switch (filp->f_owner.pid_type) { | ||
315 | case PIDTYPE_MAX: | ||
316 | owner.type = F_OWNER_TID; | ||
317 | break; | ||
318 | |||
319 | case PIDTYPE_PID: | ||
320 | owner.type = F_OWNER_PID; | ||
321 | break; | ||
322 | |||
323 | case PIDTYPE_PGID: | ||
324 | owner.type = F_OWNER_GID; | ||
325 | break; | ||
326 | |||
327 | default: | ||
328 | WARN_ON(1); | ||
329 | ret = -EINVAL; | ||
330 | break; | ||
331 | } | ||
332 | read_unlock(&filp->f_owner.lock); | ||
333 | |||
334 | if (!ret) | ||
335 | ret = copy_to_user(owner_p, &owner, sizeof(owner)); | ||
336 | return ret; | ||
337 | } | ||
338 | |||
266 | static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | 339 | static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, |
267 | struct file *filp) | 340 | struct file *filp) |
268 | { | 341 | { |
@@ -313,6 +386,12 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | |||
313 | case F_SETOWN: | 386 | case F_SETOWN: |
314 | err = f_setown(filp, arg, 1); | 387 | err = f_setown(filp, arg, 1); |
315 | break; | 388 | break; |
389 | case F_GETOWN_EX: | ||
390 | err = f_getown_ex(filp, arg); | ||
391 | break; | ||
392 | case F_SETOWN_EX: | ||
393 | err = f_setown_ex(filp, arg); | ||
394 | break; | ||
316 | case F_GETSIG: | 395 | case F_GETSIG: |
317 | err = filp->f_owner.signum; | 396 | err = filp->f_owner.signum; |
318 | break; | 397 | break; |
@@ -428,8 +507,7 @@ static inline int sigio_perm(struct task_struct *p, | |||
428 | 507 | ||
429 | static void send_sigio_to_task(struct task_struct *p, | 508 | static void send_sigio_to_task(struct task_struct *p, |
430 | struct fown_struct *fown, | 509 | struct fown_struct *fown, |
431 | int fd, | 510 | int fd, int reason, int group) |
432 | int reason) | ||
433 | { | 511 | { |
434 | /* | 512 | /* |
435 | * F_SETSIG can change ->signum lockless in parallel, make | 513 | * F_SETSIG can change ->signum lockless in parallel, make |
@@ -461,11 +539,11 @@ static void send_sigio_to_task(struct task_struct *p, | |||
461 | else | 539 | else |
462 | si.si_band = band_table[reason - POLL_IN]; | 540 | si.si_band = band_table[reason - POLL_IN]; |
463 | si.si_fd = fd; | 541 | si.si_fd = fd; |
464 | if (!group_send_sig_info(signum, &si, p)) | 542 | if (!do_send_sig_info(signum, &si, p, group)) |
465 | break; | 543 | break; |
466 | /* fall-through: fall back on the old plain SIGIO signal */ | 544 | /* fall-through: fall back on the old plain SIGIO signal */ |
467 | case 0: | 545 | case 0: |
468 | group_send_sig_info(SIGIO, SEND_SIG_PRIV, p); | 546 | do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group); |
469 | } | 547 | } |
470 | } | 548 | } |
471 | 549 | ||
@@ -474,16 +552,23 @@ void send_sigio(struct fown_struct *fown, int fd, int band) | |||
474 | struct task_struct *p; | 552 | struct task_struct *p; |
475 | enum pid_type type; | 553 | enum pid_type type; |
476 | struct pid *pid; | 554 | struct pid *pid; |
555 | int group = 1; | ||
477 | 556 | ||
478 | read_lock(&fown->lock); | 557 | read_lock(&fown->lock); |
558 | |||
479 | type = fown->pid_type; | 559 | type = fown->pid_type; |
560 | if (type == PIDTYPE_MAX) { | ||
561 | group = 0; | ||
562 | type = PIDTYPE_PID; | ||
563 | } | ||
564 | |||
480 | pid = fown->pid; | 565 | pid = fown->pid; |
481 | if (!pid) | 566 | if (!pid) |
482 | goto out_unlock_fown; | 567 | goto out_unlock_fown; |
483 | 568 | ||
484 | read_lock(&tasklist_lock); | 569 | read_lock(&tasklist_lock); |
485 | do_each_pid_task(pid, type, p) { | 570 | do_each_pid_task(pid, type, p) { |
486 | send_sigio_to_task(p, fown, fd, band); | 571 | send_sigio_to_task(p, fown, fd, band, group); |
487 | } while_each_pid_task(pid, type, p); | 572 | } while_each_pid_task(pid, type, p); |
488 | read_unlock(&tasklist_lock); | 573 | read_unlock(&tasklist_lock); |
489 | out_unlock_fown: | 574 | out_unlock_fown: |
@@ -491,10 +576,10 @@ void send_sigio(struct fown_struct *fown, int fd, int band) | |||
491 | } | 576 | } |
492 | 577 | ||
493 | static void send_sigurg_to_task(struct task_struct *p, | 578 | static void send_sigurg_to_task(struct task_struct *p, |
494 | struct fown_struct *fown) | 579 | struct fown_struct *fown, int group) |
495 | { | 580 | { |
496 | if (sigio_perm(p, fown, SIGURG)) | 581 | if (sigio_perm(p, fown, SIGURG)) |
497 | group_send_sig_info(SIGURG, SEND_SIG_PRIV, p); | 582 | do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group); |
498 | } | 583 | } |
499 | 584 | ||
500 | int send_sigurg(struct fown_struct *fown) | 585 | int send_sigurg(struct fown_struct *fown) |
@@ -502,10 +587,17 @@ int send_sigurg(struct fown_struct *fown) | |||
502 | struct task_struct *p; | 587 | struct task_struct *p; |
503 | enum pid_type type; | 588 | enum pid_type type; |
504 | struct pid *pid; | 589 | struct pid *pid; |
590 | int group = 1; | ||
505 | int ret = 0; | 591 | int ret = 0; |
506 | 592 | ||
507 | read_lock(&fown->lock); | 593 | read_lock(&fown->lock); |
594 | |||
508 | type = fown->pid_type; | 595 | type = fown->pid_type; |
596 | if (type == PIDTYPE_MAX) { | ||
597 | group = 0; | ||
598 | type = PIDTYPE_PID; | ||
599 | } | ||
600 | |||
509 | pid = fown->pid; | 601 | pid = fown->pid; |
510 | if (!pid) | 602 | if (!pid) |
511 | goto out_unlock_fown; | 603 | goto out_unlock_fown; |
@@ -514,7 +606,7 @@ int send_sigurg(struct fown_struct *fown) | |||
514 | 606 | ||
515 | read_lock(&tasklist_lock); | 607 | read_lock(&tasklist_lock); |
516 | do_each_pid_task(pid, type, p) { | 608 | do_each_pid_task(pid, type, p) { |
517 | send_sigurg_to_task(p, fown); | 609 | send_sigurg_to_task(p, fown, group); |
518 | } while_each_pid_task(pid, type, p); | 610 | } while_each_pid_task(pid, type, p); |
519 | read_unlock(&tasklist_lock); | 611 | read_unlock(&tasklist_lock); |
520 | out_unlock_fown: | 612 | out_unlock_fown: |
diff --git a/fs/file_table.c b/fs/file_table.c index 334ce39881f8..8eb44042e009 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -74,14 +74,14 @@ EXPORT_SYMBOL_GPL(get_max_files); | |||
74 | * Handle nr_files sysctl | 74 | * Handle nr_files sysctl |
75 | */ | 75 | */ |
76 | #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) | 76 | #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) |
77 | int proc_nr_files(ctl_table *table, int write, struct file *filp, | 77 | int proc_nr_files(ctl_table *table, int write, |
78 | void __user *buffer, size_t *lenp, loff_t *ppos) | 78 | void __user *buffer, size_t *lenp, loff_t *ppos) |
79 | { | 79 | { |
80 | files_stat.nr_files = get_nr_files(); | 80 | files_stat.nr_files = get_nr_files(); |
81 | return proc_dointvec(table, write, filp, buffer, lenp, ppos); | 81 | return proc_dointvec(table, write, buffer, lenp, ppos); |
82 | } | 82 | } |
83 | #else | 83 | #else |
84 | int proc_nr_files(ctl_table *table, int write, struct file *filp, | 84 | int proc_nr_files(ctl_table *table, int write, |
85 | void __user *buffer, size_t *lenp, loff_t *ppos) | 85 | void __user *buffer, size_t *lenp, loff_t *ppos) |
86 | { | 86 | { |
87 | return -ENOSYS; | 87 | return -ENOSYS; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index e703654e7f40..992f6c9410bb 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1276,14 +1276,9 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, | |||
1276 | return 0; | 1276 | return 0; |
1277 | 1277 | ||
1278 | if (attr->ia_valid & ATTR_SIZE) { | 1278 | if (attr->ia_valid & ATTR_SIZE) { |
1279 | unsigned long limit; | 1279 | err = inode_newsize_ok(inode, attr->ia_size); |
1280 | if (IS_SWAPFILE(inode)) | 1280 | if (err) |
1281 | return -ETXTBSY; | 1281 | return err; |
1282 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
1283 | if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { | ||
1284 | send_sig(SIGXFSZ, current, 0); | ||
1285 | return -EFBIG; | ||
1286 | } | ||
1287 | is_truncate = true; | 1282 | is_truncate = true; |
1288 | } | 1283 | } |
1289 | 1284 | ||
@@ -1350,8 +1345,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, | |||
1350 | * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock. | 1345 | * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock. |
1351 | */ | 1346 | */ |
1352 | if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) { | 1347 | if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) { |
1353 | if (outarg.attr.size < oldsize) | 1348 | truncate_pagecache(inode, oldsize, outarg.attr.size); |
1354 | fuse_truncate(inode->i_mapping, outarg.attr.size); | ||
1355 | invalidate_inode_pages2(inode->i_mapping); | 1349 | invalidate_inode_pages2(inode->i_mapping); |
1356 | } | 1350 | } |
1357 | 1351 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index fc9c79feb5f7..01cc462ff45d 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -606,8 +606,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | |||
606 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | 606 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, |
607 | u64 attr_valid); | 607 | u64 attr_valid); |
608 | 608 | ||
609 | void fuse_truncate(struct address_space *mapping, loff_t offset); | ||
610 | |||
611 | /** | 609 | /** |
612 | * Initialize the client device | 610 | * Initialize the client device |
613 | */ | 611 | */ |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 6da947daabda..1a822ce2b24b 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -140,14 +140,6 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data) | |||
140 | return 0; | 140 | return 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | void fuse_truncate(struct address_space *mapping, loff_t offset) | ||
144 | { | ||
145 | /* See vmtruncate() */ | ||
146 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
147 | truncate_inode_pages(mapping, offset); | ||
148 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
149 | } | ||
150 | |||
151 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | 143 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, |
152 | u64 attr_valid) | 144 | u64 attr_valid) |
153 | { | 145 | { |
@@ -205,8 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | |||
205 | spin_unlock(&fc->lock); | 197 | spin_unlock(&fc->lock); |
206 | 198 | ||
207 | if (S_ISREG(inode->i_mode) && oldsize != attr->size) { | 199 | if (S_ISREG(inode->i_mode) && oldsize != attr->size) { |
208 | if (attr->size < oldsize) | 200 | truncate_pagecache(inode, oldsize, attr->size); |
209 | fuse_truncate(inode->i_mapping, attr->size); | ||
210 | invalidate_inode_pages2(inode->i_mapping); | 201 | invalidate_inode_pages2(inode->i_mapping); |
211 | } | 202 | } |
212 | } | 203 | } |
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 7ebae9a4ecc0..694b5d48f036 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -1135,6 +1135,7 @@ static const struct address_space_operations gfs2_writeback_aops = { | |||
1135 | .direct_IO = gfs2_direct_IO, | 1135 | .direct_IO = gfs2_direct_IO, |
1136 | .migratepage = buffer_migrate_page, | 1136 | .migratepage = buffer_migrate_page, |
1137 | .is_partially_uptodate = block_is_partially_uptodate, | 1137 | .is_partially_uptodate = block_is_partially_uptodate, |
1138 | .error_remove_page = generic_error_remove_page, | ||
1138 | }; | 1139 | }; |
1139 | 1140 | ||
1140 | static const struct address_space_operations gfs2_ordered_aops = { | 1141 | static const struct address_space_operations gfs2_ordered_aops = { |
@@ -1151,6 +1152,7 @@ static const struct address_space_operations gfs2_ordered_aops = { | |||
1151 | .direct_IO = gfs2_direct_IO, | 1152 | .direct_IO = gfs2_direct_IO, |
1152 | .migratepage = buffer_migrate_page, | 1153 | .migratepage = buffer_migrate_page, |
1153 | .is_partially_uptodate = block_is_partially_uptodate, | 1154 | .is_partially_uptodate = block_is_partially_uptodate, |
1155 | .error_remove_page = generic_error_remove_page, | ||
1154 | }; | 1156 | }; |
1155 | 1157 | ||
1156 | static const struct address_space_operations gfs2_jdata_aops = { | 1158 | static const struct address_space_operations gfs2_jdata_aops = { |
@@ -1166,6 +1168,7 @@ static const struct address_space_operations gfs2_jdata_aops = { | |||
1166 | .invalidatepage = gfs2_invalidatepage, | 1168 | .invalidatepage = gfs2_invalidatepage, |
1167 | .releasepage = gfs2_releasepage, | 1169 | .releasepage = gfs2_releasepage, |
1168 | .is_partially_uptodate = block_is_partially_uptodate, | 1170 | .is_partially_uptodate = block_is_partially_uptodate, |
1171 | .error_remove_page = generic_error_remove_page, | ||
1169 | }; | 1172 | }; |
1170 | 1173 | ||
1171 | void gfs2_set_aops(struct inode *inode) | 1174 | void gfs2_set_aops(struct inode *inode) |
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 7b6165f25fbe..8bbe03c3f6d5 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c | |||
@@ -344,10 +344,8 @@ void hfs_mdb_put(struct super_block *sb) | |||
344 | brelse(HFS_SB(sb)->mdb_bh); | 344 | brelse(HFS_SB(sb)->mdb_bh); |
345 | brelse(HFS_SB(sb)->alt_mdb_bh); | 345 | brelse(HFS_SB(sb)->alt_mdb_bh); |
346 | 346 | ||
347 | if (HFS_SB(sb)->nls_io) | 347 | unload_nls(HFS_SB(sb)->nls_io); |
348 | unload_nls(HFS_SB(sb)->nls_io); | 348 | unload_nls(HFS_SB(sb)->nls_disk); |
349 | if (HFS_SB(sb)->nls_disk) | ||
350 | unload_nls(HFS_SB(sb)->nls_disk); | ||
351 | 349 | ||
352 | free_pages((unsigned long)HFS_SB(sb)->bitmap, PAGE_SIZE < 8192 ? 1 : 0); | 350 | free_pages((unsigned long)HFS_SB(sb)->bitmap, PAGE_SIZE < 8192 ? 1 : 0); |
353 | kfree(HFS_SB(sb)); | 351 | kfree(HFS_SB(sb)); |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index c0759fe0855b..43022f3d5148 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -229,8 +229,7 @@ static void hfsplus_put_super(struct super_block *sb) | |||
229 | iput(HFSPLUS_SB(sb).alloc_file); | 229 | iput(HFSPLUS_SB(sb).alloc_file); |
230 | iput(HFSPLUS_SB(sb).hidden_dir); | 230 | iput(HFSPLUS_SB(sb).hidden_dir); |
231 | brelse(HFSPLUS_SB(sb).s_vhbh); | 231 | brelse(HFSPLUS_SB(sb).s_vhbh); |
232 | if (HFSPLUS_SB(sb).nls) | 232 | unload_nls(HFSPLUS_SB(sb).nls); |
233 | unload_nls(HFSPLUS_SB(sb).nls); | ||
234 | kfree(sb->s_fs_info); | 233 | kfree(sb->s_fs_info); |
235 | sb->s_fs_info = NULL; | 234 | sb->s_fs_info = NULL; |
236 | 235 | ||
@@ -464,8 +463,7 @@ out: | |||
464 | 463 | ||
465 | cleanup: | 464 | cleanup: |
466 | hfsplus_put_super(sb); | 465 | hfsplus_put_super(sb); |
467 | if (nls) | 466 | unload_nls(nls); |
468 | unload_nls(nls); | ||
469 | return err; | 467 | return err; |
470 | } | 468 | } |
471 | 469 | ||
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index eba6d552d9c9..87a1258953b8 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -380,36 +380,11 @@ static void hugetlbfs_delete_inode(struct inode *inode) | |||
380 | 380 | ||
381 | static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock) | 381 | static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock) |
382 | { | 382 | { |
383 | struct super_block *sb = inode->i_sb; | 383 | if (generic_detach_inode(inode)) { |
384 | 384 | truncate_hugepages(inode, 0); | |
385 | if (!hlist_unhashed(&inode->i_hash)) { | 385 | clear_inode(inode); |
386 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | 386 | destroy_inode(inode); |
387 | list_move(&inode->i_list, &inode_unused); | ||
388 | inodes_stat.nr_unused++; | ||
389 | if (!sb || (sb->s_flags & MS_ACTIVE)) { | ||
390 | spin_unlock(&inode_lock); | ||
391 | return; | ||
392 | } | ||
393 | inode->i_state |= I_WILL_FREE; | ||
394 | spin_unlock(&inode_lock); | ||
395 | /* | ||
396 | * write_inode_now is a noop as we set BDI_CAP_NO_WRITEBACK | ||
397 | * in our backing_dev_info. | ||
398 | */ | ||
399 | write_inode_now(inode, 1); | ||
400 | spin_lock(&inode_lock); | ||
401 | inode->i_state &= ~I_WILL_FREE; | ||
402 | inodes_stat.nr_unused--; | ||
403 | hlist_del_init(&inode->i_hash); | ||
404 | } | 387 | } |
405 | list_del_init(&inode->i_list); | ||
406 | list_del_init(&inode->i_sb_list); | ||
407 | inode->i_state |= I_FREEING; | ||
408 | inodes_stat.nr_inodes--; | ||
409 | spin_unlock(&inode_lock); | ||
410 | truncate_hugepages(inode, 0); | ||
411 | clear_inode(inode); | ||
412 | destroy_inode(inode); | ||
413 | } | 388 | } |
414 | 389 | ||
415 | static void hugetlbfs_drop_inode(struct inode *inode) | 390 | static void hugetlbfs_drop_inode(struct inode *inode) |
@@ -936,15 +911,9 @@ static struct file_system_type hugetlbfs_fs_type = { | |||
936 | 911 | ||
937 | static struct vfsmount *hugetlbfs_vfsmount; | 912 | static struct vfsmount *hugetlbfs_vfsmount; |
938 | 913 | ||
939 | static int can_do_hugetlb_shm(int creat_flags) | 914 | static int can_do_hugetlb_shm(void) |
940 | { | 915 | { |
941 | if (creat_flags != HUGETLB_SHMFS_INODE) | 916 | return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); |
942 | return 0; | ||
943 | if (capable(CAP_IPC_LOCK)) | ||
944 | return 1; | ||
945 | if (in_group_p(sysctl_hugetlb_shm_group)) | ||
946 | return 1; | ||
947 | return 0; | ||
948 | } | 917 | } |
949 | 918 | ||
950 | struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, | 919 | struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, |
@@ -960,7 +929,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, | |||
960 | if (!hugetlbfs_vfsmount) | 929 | if (!hugetlbfs_vfsmount) |
961 | return ERR_PTR(-ENOENT); | 930 | return ERR_PTR(-ENOENT); |
962 | 931 | ||
963 | if (!can_do_hugetlb_shm(creat_flags)) { | 932 | if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { |
964 | *user = current_user(); | 933 | *user = current_user(); |
965 | if (user_shm_lock(size, *user)) { | 934 | if (user_shm_lock(size, *user)) { |
966 | WARN_ONCE(1, | 935 | WARN_ONCE(1, |
diff --git a/fs/inode.c b/fs/inode.c index 76582b06ab97..4d8e3be55976 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1241,7 +1241,16 @@ void generic_delete_inode(struct inode *inode) | |||
1241 | } | 1241 | } |
1242 | EXPORT_SYMBOL(generic_delete_inode); | 1242 | EXPORT_SYMBOL(generic_delete_inode); |
1243 | 1243 | ||
1244 | static void generic_forget_inode(struct inode *inode) | 1244 | /** |
1245 | * generic_detach_inode - remove inode from inode lists | ||
1246 | * @inode: inode to remove | ||
1247 | * | ||
1248 | * Remove inode from inode lists, write it if it's dirty. This is just an | ||
1249 | * internal VFS helper exported for hugetlbfs. Do not use! | ||
1250 | * | ||
1251 | * Returns 1 if inode should be completely destroyed. | ||
1252 | */ | ||
1253 | int generic_detach_inode(struct inode *inode) | ||
1245 | { | 1254 | { |
1246 | struct super_block *sb = inode->i_sb; | 1255 | struct super_block *sb = inode->i_sb; |
1247 | 1256 | ||
@@ -1251,7 +1260,7 @@ static void generic_forget_inode(struct inode *inode) | |||
1251 | inodes_stat.nr_unused++; | 1260 | inodes_stat.nr_unused++; |
1252 | if (sb->s_flags & MS_ACTIVE) { | 1261 | if (sb->s_flags & MS_ACTIVE) { |
1253 | spin_unlock(&inode_lock); | 1262 | spin_unlock(&inode_lock); |
1254 | return; | 1263 | return 0; |
1255 | } | 1264 | } |
1256 | WARN_ON(inode->i_state & I_NEW); | 1265 | WARN_ON(inode->i_state & I_NEW); |
1257 | inode->i_state |= I_WILL_FREE; | 1266 | inode->i_state |= I_WILL_FREE; |
@@ -1269,6 +1278,14 @@ static void generic_forget_inode(struct inode *inode) | |||
1269 | inode->i_state |= I_FREEING; | 1278 | inode->i_state |= I_FREEING; |
1270 | inodes_stat.nr_inodes--; | 1279 | inodes_stat.nr_inodes--; |
1271 | spin_unlock(&inode_lock); | 1280 | spin_unlock(&inode_lock); |
1281 | return 1; | ||
1282 | } | ||
1283 | EXPORT_SYMBOL_GPL(generic_detach_inode); | ||
1284 | |||
1285 | static void generic_forget_inode(struct inode *inode) | ||
1286 | { | ||
1287 | if (!generic_detach_inode(inode)) | ||
1288 | return; | ||
1272 | if (inode->i_data.nrpages) | 1289 | if (inode->i_data.nrpages) |
1273 | truncate_inode_pages(&inode->i_data, 0); | 1290 | truncate_inode_pages(&inode->i_data, 0); |
1274 | clear_inode(inode); | 1291 | clear_inode(inode); |
@@ -1399,31 +1416,31 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry) | |||
1399 | struct inode *inode = dentry->d_inode; | 1416 | struct inode *inode = dentry->d_inode; |
1400 | struct timespec now; | 1417 | struct timespec now; |
1401 | 1418 | ||
1402 | if (mnt_want_write(mnt)) | ||
1403 | return; | ||
1404 | if (inode->i_flags & S_NOATIME) | 1419 | if (inode->i_flags & S_NOATIME) |
1405 | goto out; | 1420 | return; |
1406 | if (IS_NOATIME(inode)) | 1421 | if (IS_NOATIME(inode)) |
1407 | goto out; | 1422 | return; |
1408 | if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) | 1423 | if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) |
1409 | goto out; | 1424 | return; |
1410 | 1425 | ||
1411 | if (mnt->mnt_flags & MNT_NOATIME) | 1426 | if (mnt->mnt_flags & MNT_NOATIME) |
1412 | goto out; | 1427 | return; |
1413 | if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) | 1428 | if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) |
1414 | goto out; | 1429 | return; |
1415 | 1430 | ||
1416 | now = current_fs_time(inode->i_sb); | 1431 | now = current_fs_time(inode->i_sb); |
1417 | 1432 | ||
1418 | if (!relatime_need_update(mnt, inode, now)) | 1433 | if (!relatime_need_update(mnt, inode, now)) |
1419 | goto out; | 1434 | return; |
1420 | 1435 | ||
1421 | if (timespec_equal(&inode->i_atime, &now)) | 1436 | if (timespec_equal(&inode->i_atime, &now)) |
1422 | goto out; | 1437 | return; |
1438 | |||
1439 | if (mnt_want_write(mnt)) | ||
1440 | return; | ||
1423 | 1441 | ||
1424 | inode->i_atime = now; | 1442 | inode->i_atime = now; |
1425 | mark_inode_dirty_sync(inode); | 1443 | mark_inode_dirty_sync(inode); |
1426 | out: | ||
1427 | mnt_drop_write(mnt); | 1444 | mnt_drop_write(mnt); |
1428 | } | 1445 | } |
1429 | EXPORT_SYMBOL(touch_atime); | 1446 | EXPORT_SYMBOL(touch_atime); |
@@ -1444,34 +1461,37 @@ void file_update_time(struct file *file) | |||
1444 | { | 1461 | { |
1445 | struct inode *inode = file->f_path.dentry->d_inode; | 1462 | struct inode *inode = file->f_path.dentry->d_inode; |
1446 | struct timespec now; | 1463 | struct timespec now; |
1447 | int sync_it = 0; | 1464 | enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0; |
1448 | int err; | ||
1449 | 1465 | ||
1466 | /* First try to exhaust all avenues to not sync */ | ||
1450 | if (IS_NOCMTIME(inode)) | 1467 | if (IS_NOCMTIME(inode)) |
1451 | return; | 1468 | return; |
1452 | 1469 | ||
1453 | err = mnt_want_write_file(file); | ||
1454 | if (err) | ||
1455 | return; | ||
1456 | |||
1457 | now = current_fs_time(inode->i_sb); | 1470 | now = current_fs_time(inode->i_sb); |
1458 | if (!timespec_equal(&inode->i_mtime, &now)) { | 1471 | if (!timespec_equal(&inode->i_mtime, &now)) |
1459 | inode->i_mtime = now; | 1472 | sync_it = S_MTIME; |
1460 | sync_it = 1; | ||
1461 | } | ||
1462 | 1473 | ||
1463 | if (!timespec_equal(&inode->i_ctime, &now)) { | 1474 | if (!timespec_equal(&inode->i_ctime, &now)) |
1464 | inode->i_ctime = now; | 1475 | sync_it |= S_CTIME; |
1465 | sync_it = 1; | ||
1466 | } | ||
1467 | 1476 | ||
1468 | if (IS_I_VERSION(inode)) { | 1477 | if (IS_I_VERSION(inode)) |
1469 | inode_inc_iversion(inode); | 1478 | sync_it |= S_VERSION; |
1470 | sync_it = 1; | 1479 | |
1471 | } | 1480 | if (!sync_it) |
1481 | return; | ||
1472 | 1482 | ||
1473 | if (sync_it) | 1483 | /* Finally allowed to write? Takes lock. */ |
1474 | mark_inode_dirty_sync(inode); | 1484 | if (mnt_want_write_file(file)) |
1485 | return; | ||
1486 | |||
1487 | /* Only change inode inside the lock region */ | ||
1488 | if (sync_it & S_VERSION) | ||
1489 | inode_inc_iversion(inode); | ||
1490 | if (sync_it & S_CTIME) | ||
1491 | inode->i_ctime = now; | ||
1492 | if (sync_it & S_MTIME) | ||
1493 | inode->i_mtime = now; | ||
1494 | mark_inode_dirty_sync(inode); | ||
1475 | mnt_drop_write(file->f_path.mnt); | 1495 | mnt_drop_write(file->f_path.mnt); |
1476 | } | 1496 | } |
1477 | EXPORT_SYMBOL(file_update_time); | 1497 | EXPORT_SYMBOL(file_update_time); |
@@ -1599,7 +1619,8 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) | |||
1599 | else if (S_ISSOCK(mode)) | 1619 | else if (S_ISSOCK(mode)) |
1600 | inode->i_fop = &bad_sock_fops; | 1620 | inode->i_fop = &bad_sock_fops; |
1601 | else | 1621 | else |
1602 | printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n", | 1622 | printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for" |
1603 | mode); | 1623 | " inode %s:%lu\n", mode, inode->i_sb->s_id, |
1624 | inode->i_ino); | ||
1604 | } | 1625 | } |
1605 | EXPORT_SYMBOL(init_special_inode); | 1626 | EXPORT_SYMBOL(init_special_inode); |
diff --git a/fs/internal.h b/fs/internal.h index d55ef562f0bb..515175b8b72e 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -57,6 +57,7 @@ extern int check_unsafe_exec(struct linux_binprm *); | |||
57 | * namespace.c | 57 | * namespace.c |
58 | */ | 58 | */ |
59 | extern int copy_mount_options(const void __user *, unsigned long *); | 59 | extern int copy_mount_options(const void __user *, unsigned long *); |
60 | extern int copy_mount_string(const void __user *, char **); | ||
60 | 61 | ||
61 | extern void free_vfsmnt(struct vfsmount *); | 62 | extern void free_vfsmnt(struct vfsmount *); |
62 | extern struct vfsmount *alloc_vfsmnt(const char *); | 63 | extern struct vfsmount *alloc_vfsmnt(const char *); |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 5612880fcbe7..7b17a14396ff 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -162,20 +162,21 @@ EXPORT_SYMBOL(fiemap_check_flags); | |||
162 | static int fiemap_check_ranges(struct super_block *sb, | 162 | static int fiemap_check_ranges(struct super_block *sb, |
163 | u64 start, u64 len, u64 *new_len) | 163 | u64 start, u64 len, u64 *new_len) |
164 | { | 164 | { |
165 | u64 maxbytes = (u64) sb->s_maxbytes; | ||
166 | |||
165 | *new_len = len; | 167 | *new_len = len; |
166 | 168 | ||
167 | if (len == 0) | 169 | if (len == 0) |
168 | return -EINVAL; | 170 | return -EINVAL; |
169 | 171 | ||
170 | if (start > sb->s_maxbytes) | 172 | if (start > maxbytes) |
171 | return -EFBIG; | 173 | return -EFBIG; |
172 | 174 | ||
173 | /* | 175 | /* |
174 | * Shrink request scope to what the fs can actually handle. | 176 | * Shrink request scope to what the fs can actually handle. |
175 | */ | 177 | */ |
176 | if ((len > sb->s_maxbytes) || | 178 | if (len > maxbytes || (maxbytes - len) < start) |
177 | (sb->s_maxbytes - len) < start) | 179 | *new_len = maxbytes - start; |
178 | *new_len = sb->s_maxbytes - start; | ||
179 | 180 | ||
180 | return 0; | 181 | return 0; |
181 | } | 182 | } |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 85f96bc651c7..6b4dcd4f2943 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -46,10 +46,7 @@ static void isofs_put_super(struct super_block *sb) | |||
46 | #ifdef CONFIG_JOLIET | 46 | #ifdef CONFIG_JOLIET |
47 | lock_kernel(); | 47 | lock_kernel(); |
48 | 48 | ||
49 | if (sbi->s_nls_iocharset) { | 49 | unload_nls(sbi->s_nls_iocharset); |
50 | unload_nls(sbi->s_nls_iocharset); | ||
51 | sbi->s_nls_iocharset = NULL; | ||
52 | } | ||
53 | 50 | ||
54 | unlock_kernel(); | 51 | unlock_kernel(); |
55 | #endif | 52 | #endif |
@@ -912,8 +909,7 @@ out_no_root: | |||
912 | printk(KERN_WARNING "%s: get root inode failed\n", __func__); | 909 | printk(KERN_WARNING "%s: get root inode failed\n", __func__); |
913 | out_no_inode: | 910 | out_no_inode: |
914 | #ifdef CONFIG_JOLIET | 911 | #ifdef CONFIG_JOLIET |
915 | if (sbi->s_nls_iocharset) | 912 | unload_nls(sbi->s_nls_iocharset); |
916 | unload_nls(sbi->s_nls_iocharset); | ||
917 | #endif | 913 | #endif |
918 | goto out_freesbi; | 914 | goto out_freesbi; |
919 | out_no_read: | 915 | out_no_read: |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 37e6dcda8fc8..2234c73fc577 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -178,13 +178,11 @@ static void jfs_put_super(struct super_block *sb) | |||
178 | rc = jfs_umount(sb); | 178 | rc = jfs_umount(sb); |
179 | if (rc) | 179 | if (rc) |
180 | jfs_err("jfs_umount failed with return code %d", rc); | 180 | jfs_err("jfs_umount failed with return code %d", rc); |
181 | if (sbi->nls_tab) | 181 | |
182 | unload_nls(sbi->nls_tab); | 182 | unload_nls(sbi->nls_tab); |
183 | sbi->nls_tab = NULL; | ||
184 | 183 | ||
185 | truncate_inode_pages(sbi->direct_inode->i_mapping, 0); | 184 | truncate_inode_pages(sbi->direct_inode->i_mapping, 0); |
186 | iput(sbi->direct_inode); | 185 | iput(sbi->direct_inode); |
187 | sbi->direct_inode = NULL; | ||
188 | 186 | ||
189 | kfree(sbi); | 187 | kfree(sbi); |
190 | 188 | ||
@@ -347,8 +345,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, | |||
347 | 345 | ||
348 | if (nls_map != (void *) -1) { | 346 | if (nls_map != (void *) -1) { |
349 | /* Discard old (if remount) */ | 347 | /* Discard old (if remount) */ |
350 | if (sbi->nls_tab) | 348 | unload_nls(sbi->nls_tab); |
351 | unload_nls(sbi->nls_tab); | ||
352 | sbi->nls_tab = nls_map; | 349 | sbi->nls_tab = nls_map; |
353 | } | 350 | } |
354 | return 1; | 351 | return 1; |
diff --git a/fs/libfs.c b/fs/libfs.c index dcec3d3ea64f..219576c52d80 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -527,14 +527,18 @@ ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos, | |||
527 | const void *from, size_t available) | 527 | const void *from, size_t available) |
528 | { | 528 | { |
529 | loff_t pos = *ppos; | 529 | loff_t pos = *ppos; |
530 | size_t ret; | ||
531 | |||
530 | if (pos < 0) | 532 | if (pos < 0) |
531 | return -EINVAL; | 533 | return -EINVAL; |
532 | if (pos >= available) | 534 | if (pos >= available || !count) |
533 | return 0; | 535 | return 0; |
534 | if (count > available - pos) | 536 | if (count > available - pos) |
535 | count = available - pos; | 537 | count = available - pos; |
536 | if (copy_to_user(to, from + pos, count)) | 538 | ret = copy_to_user(to, from + pos, count); |
539 | if (ret == count) | ||
537 | return -EFAULT; | 540 | return -EFAULT; |
541 | count -= ret; | ||
538 | *ppos = pos + count; | 542 | *ppos = pos + count; |
539 | return count; | 543 | return count; |
540 | } | 544 | } |
@@ -735,10 +739,11 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, | |||
735 | if (copy_from_user(attr->set_buf, buf, size)) | 739 | if (copy_from_user(attr->set_buf, buf, size)) |
736 | goto out; | 740 | goto out; |
737 | 741 | ||
738 | ret = len; /* claim we got the whole input */ | ||
739 | attr->set_buf[size] = '\0'; | 742 | attr->set_buf[size] = '\0'; |
740 | val = simple_strtol(attr->set_buf, NULL, 0); | 743 | val = simple_strtol(attr->set_buf, NULL, 0); |
741 | attr->set(attr->data, val); | 744 | ret = attr->set(attr->data, val); |
745 | if (ret == 0) | ||
746 | ret = len; /* on success, claim we got the whole input */ | ||
742 | out: | 747 | out: |
743 | mutex_unlock(&attr->mutex); | 748 | mutex_unlock(&attr->mutex); |
744 | return ret; | 749 | return ret; |
diff --git a/fs/namespace.c b/fs/namespace.c index 7230787d18b0..bdc3cb4fd222 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1640,7 +1640,7 @@ static int do_new_mount(struct path *path, char *type, int flags, | |||
1640 | { | 1640 | { |
1641 | struct vfsmount *mnt; | 1641 | struct vfsmount *mnt; |
1642 | 1642 | ||
1643 | if (!type || !memchr(type, 0, PAGE_SIZE)) | 1643 | if (!type) |
1644 | return -EINVAL; | 1644 | return -EINVAL; |
1645 | 1645 | ||
1646 | /* we need capabilities... */ | 1646 | /* we need capabilities... */ |
@@ -1871,6 +1871,23 @@ int copy_mount_options(const void __user * data, unsigned long *where) | |||
1871 | return 0; | 1871 | return 0; |
1872 | } | 1872 | } |
1873 | 1873 | ||
1874 | int copy_mount_string(const void __user *data, char **where) | ||
1875 | { | ||
1876 | char *tmp; | ||
1877 | |||
1878 | if (!data) { | ||
1879 | *where = NULL; | ||
1880 | return 0; | ||
1881 | } | ||
1882 | |||
1883 | tmp = strndup_user(data, PAGE_SIZE); | ||
1884 | if (IS_ERR(tmp)) | ||
1885 | return PTR_ERR(tmp); | ||
1886 | |||
1887 | *where = tmp; | ||
1888 | return 0; | ||
1889 | } | ||
1890 | |||
1874 | /* | 1891 | /* |
1875 | * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to | 1892 | * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to |
1876 | * be given to the mount() call (ie: read-only, no-dev, no-suid etc). | 1893 | * be given to the mount() call (ie: read-only, no-dev, no-suid etc). |
@@ -1900,8 +1917,6 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1900 | 1917 | ||
1901 | if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) | 1918 | if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) |
1902 | return -EINVAL; | 1919 | return -EINVAL; |
1903 | if (dev_name && !memchr(dev_name, 0, PAGE_SIZE)) | ||
1904 | return -EINVAL; | ||
1905 | 1920 | ||
1906 | if (data_page) | 1921 | if (data_page) |
1907 | ((char *)data_page)[PAGE_SIZE - 1] = 0; | 1922 | ((char *)data_page)[PAGE_SIZE - 1] = 0; |
@@ -2070,40 +2085,42 @@ EXPORT_SYMBOL(create_mnt_ns); | |||
2070 | SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | 2085 | SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, |
2071 | char __user *, type, unsigned long, flags, void __user *, data) | 2086 | char __user *, type, unsigned long, flags, void __user *, data) |
2072 | { | 2087 | { |
2073 | int retval; | 2088 | int ret; |
2089 | char *kernel_type; | ||
2090 | char *kernel_dir; | ||
2091 | char *kernel_dev; | ||
2074 | unsigned long data_page; | 2092 | unsigned long data_page; |
2075 | unsigned long type_page; | ||
2076 | unsigned long dev_page; | ||
2077 | char *dir_page; | ||
2078 | 2093 | ||
2079 | retval = copy_mount_options(type, &type_page); | 2094 | ret = copy_mount_string(type, &kernel_type); |
2080 | if (retval < 0) | 2095 | if (ret < 0) |
2081 | return retval; | 2096 | goto out_type; |
2082 | 2097 | ||
2083 | dir_page = getname(dir_name); | 2098 | kernel_dir = getname(dir_name); |
2084 | retval = PTR_ERR(dir_page); | 2099 | if (IS_ERR(kernel_dir)) { |
2085 | if (IS_ERR(dir_page)) | 2100 | ret = PTR_ERR(kernel_dir); |
2086 | goto out1; | 2101 | goto out_dir; |
2102 | } | ||
2087 | 2103 | ||
2088 | retval = copy_mount_options(dev_name, &dev_page); | 2104 | ret = copy_mount_string(dev_name, &kernel_dev); |
2089 | if (retval < 0) | 2105 | if (ret < 0) |
2090 | goto out2; | 2106 | goto out_dev; |
2091 | 2107 | ||
2092 | retval = copy_mount_options(data, &data_page); | 2108 | ret = copy_mount_options(data, &data_page); |
2093 | if (retval < 0) | 2109 | if (ret < 0) |
2094 | goto out3; | 2110 | goto out_data; |
2095 | 2111 | ||
2096 | retval = do_mount((char *)dev_page, dir_page, (char *)type_page, | 2112 | ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags, |
2097 | flags, (void *)data_page); | 2113 | (void *) data_page); |
2098 | free_page(data_page); | ||
2099 | 2114 | ||
2100 | out3: | 2115 | free_page(data_page); |
2101 | free_page(dev_page); | 2116 | out_data: |
2102 | out2: | 2117 | kfree(kernel_dev); |
2103 | putname(dir_page); | 2118 | out_dev: |
2104 | out1: | 2119 | putname(kernel_dir); |
2105 | free_page(type_page); | 2120 | out_dir: |
2106 | return retval; | 2121 | kfree(kernel_type); |
2122 | out_type: | ||
2123 | return ret; | ||
2107 | } | 2124 | } |
2108 | 2125 | ||
2109 | /* | 2126 | /* |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index b99ce205b1bd..cf98da1be23e 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -746,16 +746,8 @@ static void ncp_put_super(struct super_block *sb) | |||
746 | 746 | ||
747 | #ifdef CONFIG_NCPFS_NLS | 747 | #ifdef CONFIG_NCPFS_NLS |
748 | /* unload the NLS charsets */ | 748 | /* unload the NLS charsets */ |
749 | if (server->nls_vol) | 749 | unload_nls(server->nls_vol); |
750 | { | 750 | unload_nls(server->nls_io); |
751 | unload_nls(server->nls_vol); | ||
752 | server->nls_vol = NULL; | ||
753 | } | ||
754 | if (server->nls_io) | ||
755 | { | ||
756 | unload_nls(server->nls_io); | ||
757 | server->nls_io = NULL; | ||
758 | } | ||
759 | #endif /* CONFIG_NCPFS_NLS */ | 751 | #endif /* CONFIG_NCPFS_NLS */ |
760 | 752 | ||
761 | if (server->info_filp) | 753 | if (server->info_filp) |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 53a7ed7eb9c6..0d58caf4a6e1 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -223,10 +223,8 @@ ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg) | |||
223 | oldset_io = server->nls_io; | 223 | oldset_io = server->nls_io; |
224 | server->nls_io = iocharset; | 224 | server->nls_io = iocharset; |
225 | 225 | ||
226 | if (oldset_cp) | 226 | unload_nls(oldset_cp); |
227 | unload_nls(oldset_cp); | 227 | unload_nls(oldset_io); |
228 | if (oldset_io) | ||
229 | unload_nls(oldset_io); | ||
230 | 228 | ||
231 | return 0; | 229 | return 0; |
232 | } | 230 | } |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 5021b75d2d1e..86d6b4db1096 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -525,6 +525,7 @@ const struct address_space_operations nfs_file_aops = { | |||
525 | .direct_IO = nfs_direct_IO, | 525 | .direct_IO = nfs_direct_IO, |
526 | .migratepage = nfs_migrate_page, | 526 | .migratepage = nfs_migrate_page, |
527 | .launder_page = nfs_launder_page, | 527 | .launder_page = nfs_launder_page, |
528 | .error_remove_page = generic_error_remove_page, | ||
528 | }; | 529 | }; |
529 | 530 | ||
530 | /* | 531 | /* |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 060022b4651c..faa091865ad0 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -458,49 +458,21 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
458 | */ | 458 | */ |
459 | static int nfs_vmtruncate(struct inode * inode, loff_t offset) | 459 | static int nfs_vmtruncate(struct inode * inode, loff_t offset) |
460 | { | 460 | { |
461 | if (i_size_read(inode) < offset) { | 461 | loff_t oldsize; |
462 | unsigned long limit; | 462 | int err; |
463 | |||
464 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
465 | if (limit != RLIM_INFINITY && offset > limit) | ||
466 | goto out_sig; | ||
467 | if (offset > inode->i_sb->s_maxbytes) | ||
468 | goto out_big; | ||
469 | spin_lock(&inode->i_lock); | ||
470 | i_size_write(inode, offset); | ||
471 | spin_unlock(&inode->i_lock); | ||
472 | } else { | ||
473 | struct address_space *mapping = inode->i_mapping; | ||
474 | 463 | ||
475 | /* | 464 | err = inode_newsize_ok(inode, offset); |
476 | * truncation of in-use swapfiles is disallowed - it would | 465 | if (err) |
477 | * cause subsequent swapout to scribble on the now-freed | 466 | goto out; |
478 | * blocks. | ||
479 | */ | ||
480 | if (IS_SWAPFILE(inode)) | ||
481 | return -ETXTBSY; | ||
482 | spin_lock(&inode->i_lock); | ||
483 | i_size_write(inode, offset); | ||
484 | spin_unlock(&inode->i_lock); | ||
485 | 467 | ||
486 | /* | 468 | spin_lock(&inode->i_lock); |
487 | * unmap_mapping_range is called twice, first simply for | 469 | oldsize = inode->i_size; |
488 | * efficiency so that truncate_inode_pages does fewer | 470 | i_size_write(inode, offset); |
489 | * single-page unmaps. However after this first call, and | 471 | spin_unlock(&inode->i_lock); |
490 | * before truncate_inode_pages finishes, it is possible for | 472 | |
491 | * private pages to be COWed, which remain after | 473 | truncate_pagecache(inode, oldsize, offset); |
492 | * truncate_inode_pages finishes, hence the second | 474 | out: |
493 | * unmap_mapping_range call must be made for correctness. | 475 | return err; |
494 | */ | ||
495 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
496 | truncate_inode_pages(mapping, offset); | ||
497 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
498 | } | ||
499 | return 0; | ||
500 | out_sig: | ||
501 | send_sig(SIGXFSZ, current, 0); | ||
502 | out_big: | ||
503 | return -EFBIG; | ||
504 | } | 476 | } |
505 | 477 | ||
506 | /** | 478 | /** |
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 477d37d83b31..2224b4d07bf0 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c | |||
@@ -270,7 +270,8 @@ struct nls_table *load_nls(char *charset) | |||
270 | 270 | ||
271 | void unload_nls(struct nls_table *nls) | 271 | void unload_nls(struct nls_table *nls) |
272 | { | 272 | { |
273 | module_put(nls->owner); | 273 | if (nls) |
274 | module_put(nls->owner); | ||
274 | } | 275 | } |
275 | 276 | ||
276 | static const wchar_t charset2uni[256] = { | 277 | static const wchar_t charset2uni[256] = { |
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index b38f944f0667..cfce53cb65d7 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c | |||
@@ -1550,6 +1550,7 @@ const struct address_space_operations ntfs_aops = { | |||
1550 | .migratepage = buffer_migrate_page, /* Move a page cache page from | 1550 | .migratepage = buffer_migrate_page, /* Move a page cache page from |
1551 | one physical page to an | 1551 | one physical page to an |
1552 | other. */ | 1552 | other. */ |
1553 | .error_remove_page = generic_error_remove_page, | ||
1553 | }; | 1554 | }; |
1554 | 1555 | ||
1555 | /** | 1556 | /** |
@@ -1569,6 +1570,7 @@ const struct address_space_operations ntfs_mst_aops = { | |||
1569 | .migratepage = buffer_migrate_page, /* Move a page cache page from | 1570 | .migratepage = buffer_migrate_page, /* Move a page cache page from |
1570 | one physical page to an | 1571 | one physical page to an |
1571 | other. */ | 1572 | other. */ |
1573 | .error_remove_page = generic_error_remove_page, | ||
1572 | }; | 1574 | }; |
1573 | 1575 | ||
1574 | #ifdef NTFS_RW | 1576 | #ifdef NTFS_RW |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index abaaa1cbf8de..80b04770e8e9 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -201,8 +201,7 @@ use_utf8: | |||
201 | v, old_nls->charset); | 201 | v, old_nls->charset); |
202 | nls_map = old_nls; | 202 | nls_map = old_nls; |
203 | } else /* nls_map */ { | 203 | } else /* nls_map */ { |
204 | if (old_nls) | 204 | unload_nls(old_nls); |
205 | unload_nls(old_nls); | ||
206 | } | 205 | } |
207 | } else if (!strcmp(p, "utf8")) { | 206 | } else if (!strcmp(p, "utf8")) { |
208 | bool val = false; | 207 | bool val = false; |
@@ -2427,10 +2426,9 @@ static void ntfs_put_super(struct super_block *sb) | |||
2427 | ntfs_free(vol->upcase); | 2426 | ntfs_free(vol->upcase); |
2428 | vol->upcase = NULL; | 2427 | vol->upcase = NULL; |
2429 | } | 2428 | } |
2430 | if (vol->nls_map) { | 2429 | |
2431 | unload_nls(vol->nls_map); | 2430 | unload_nls(vol->nls_map); |
2432 | vol->nls_map = NULL; | 2431 | |
2433 | } | ||
2434 | sb->s_fs_info = NULL; | 2432 | sb->s_fs_info = NULL; |
2435 | kfree(vol); | 2433 | kfree(vol); |
2436 | 2434 | ||
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 72e76062a900..deb2b132ae5e 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -2022,4 +2022,5 @@ const struct address_space_operations ocfs2_aops = { | |||
2022 | .releasepage = ocfs2_releasepage, | 2022 | .releasepage = ocfs2_releasepage, |
2023 | .migratepage = buffer_migrate_page, | 2023 | .migratepage = buffer_migrate_page, |
2024 | .is_partially_uptodate = block_is_partially_uptodate, | 2024 | .is_partially_uptodate = block_is_partially_uptodate, |
2025 | .error_remove_page = generic_error_remove_page, | ||
2025 | }; | 2026 | }; |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 171e052c07b3..c7bff4f603ff 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -97,7 +97,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
97 | "Committed_AS: %8lu kB\n" | 97 | "Committed_AS: %8lu kB\n" |
98 | "VmallocTotal: %8lu kB\n" | 98 | "VmallocTotal: %8lu kB\n" |
99 | "VmallocUsed: %8lu kB\n" | 99 | "VmallocUsed: %8lu kB\n" |
100 | "VmallocChunk: %8lu kB\n", | 100 | "VmallocChunk: %8lu kB\n" |
101 | #ifdef CONFIG_MEMORY_FAILURE | ||
102 | "HardwareCorrupted: %8lu kB\n" | ||
103 | #endif | ||
104 | , | ||
101 | K(i.totalram), | 105 | K(i.totalram), |
102 | K(i.freeram), | 106 | K(i.freeram), |
103 | K(i.bufferram), | 107 | K(i.bufferram), |
@@ -144,6 +148,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
144 | (unsigned long)VMALLOC_TOTAL >> 10, | 148 | (unsigned long)VMALLOC_TOTAL >> 10, |
145 | vmi.used >> 10, | 149 | vmi.used >> 10, |
146 | vmi.largest_chunk >> 10 | 150 | vmi.largest_chunk >> 10 |
151 | #ifdef CONFIG_MEMORY_FAILURE | ||
152 | ,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10) | ||
153 | #endif | ||
147 | ); | 154 | ); |
148 | 155 | ||
149 | hugetlb_report_meminfo(m); | 156 | hugetlb_report_meminfo(m); |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 9b1e4e9a16bf..f667e8aeabdf 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -153,7 +153,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, | |||
153 | 153 | ||
154 | /* careful: calling conventions are nasty here */ | 154 | /* careful: calling conventions are nasty here */ |
155 | res = count; | 155 | res = count; |
156 | error = table->proc_handler(table, write, filp, buf, &res, ppos); | 156 | error = table->proc_handler(table, write, buf, &res, ppos); |
157 | if (!error) | 157 | if (!error) |
158 | error = res; | 158 | error = res; |
159 | out: | 159 | out: |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 11f0c06316de..32fae4040ebf 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -69,14 +69,11 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
69 | /* make various checks */ | 69 | /* make various checks */ |
70 | order = get_order(newsize); | 70 | order = get_order(newsize); |
71 | if (unlikely(order >= MAX_ORDER)) | 71 | if (unlikely(order >= MAX_ORDER)) |
72 | goto too_big; | 72 | return -EFBIG; |
73 | 73 | ||
74 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | 74 | ret = inode_newsize_ok(inode, newsize); |
75 | if (limit != RLIM_INFINITY && newsize > limit) | 75 | if (ret) |
76 | goto fsize_exceeded; | 76 | return ret; |
77 | |||
78 | if (newsize > inode->i_sb->s_maxbytes) | ||
79 | goto too_big; | ||
80 | 77 | ||
81 | i_size_write(inode, newsize); | 78 | i_size_write(inode, newsize); |
82 | 79 | ||
@@ -118,12 +115,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
118 | 115 | ||
119 | return 0; | 116 | return 0; |
120 | 117 | ||
121 | fsize_exceeded: | 118 | add_error: |
122 | send_sig(SIGXFSZ, current, 0); | ||
123 | too_big: | ||
124 | return -EFBIG; | ||
125 | |||
126 | add_error: | ||
127 | while (loop < npages) | 119 | while (loop < npages) |
128 | __free_page(pages + loop++); | 120 | __free_page(pages + loop++); |
129 | return ret; | 121 | return ret; |
diff --git a/fs/read_write.c b/fs/read_write.c index 6c8c55dec2bc..3ac28987f22a 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -839,9 +839,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
839 | max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); | 839 | max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); |
840 | 840 | ||
841 | pos = *ppos; | 841 | pos = *ppos; |
842 | retval = -EINVAL; | ||
843 | if (unlikely(pos < 0)) | ||
844 | goto fput_out; | ||
845 | if (unlikely(pos + count > max)) { | 842 | if (unlikely(pos + count > max)) { |
846 | retval = -EOVERFLOW; | 843 | retval = -EOVERFLOW; |
847 | if (pos >= max) | 844 | if (pos >= max) |
diff --git a/fs/romfs/super.c b/fs/romfs/super.c index 47f132df0c3f..c117fa80d1e9 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c | |||
@@ -528,7 +528,7 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent) | |||
528 | pos = (ROMFH_SIZE + len + 1 + ROMFH_PAD) & ROMFH_MASK; | 528 | pos = (ROMFH_SIZE + len + 1 + ROMFH_PAD) & ROMFH_MASK; |
529 | 529 | ||
530 | root = romfs_iget(sb, pos); | 530 | root = romfs_iget(sb, pos); |
531 | if (!root) | 531 | if (IS_ERR(root)) |
532 | goto error; | 532 | goto error; |
533 | 533 | ||
534 | sb->s_root = d_alloc_root(root); | 534 | sb->s_root = d_alloc_root(root); |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 6c959275f2d0..eae7d9dbf3ff 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -429,20 +429,21 @@ EXPORT_SYMBOL(mangle_path); | |||
429 | */ | 429 | */ |
430 | int seq_path(struct seq_file *m, struct path *path, char *esc) | 430 | int seq_path(struct seq_file *m, struct path *path, char *esc) |
431 | { | 431 | { |
432 | if (m->count < m->size) { | 432 | char *buf; |
433 | char *s = m->buf + m->count; | 433 | size_t size = seq_get_buf(m, &buf); |
434 | char *p = d_path(path, s, m->size - m->count); | 434 | int res = -1; |
435 | |||
436 | if (size) { | ||
437 | char *p = d_path(path, buf, size); | ||
435 | if (!IS_ERR(p)) { | 438 | if (!IS_ERR(p)) { |
436 | s = mangle_path(s, p, esc); | 439 | char *end = mangle_path(buf, p, esc); |
437 | if (s) { | 440 | if (end) |
438 | p = m->buf + m->count; | 441 | res = end - buf; |
439 | m->count = s - m->buf; | ||
440 | return s - p; | ||
441 | } | ||
442 | } | 442 | } |
443 | } | 443 | } |
444 | m->count = m->size; | 444 | seq_commit(m, res); |
445 | return -1; | 445 | |
446 | return res; | ||
446 | } | 447 | } |
447 | EXPORT_SYMBOL(seq_path); | 448 | EXPORT_SYMBOL(seq_path); |
448 | 449 | ||
@@ -454,26 +455,28 @@ EXPORT_SYMBOL(seq_path); | |||
454 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | 455 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, |
455 | char *esc) | 456 | char *esc) |
456 | { | 457 | { |
457 | int err = -ENAMETOOLONG; | 458 | char *buf; |
458 | if (m->count < m->size) { | 459 | size_t size = seq_get_buf(m, &buf); |
459 | char *s = m->buf + m->count; | 460 | int res = -ENAMETOOLONG; |
461 | |||
462 | if (size) { | ||
460 | char *p; | 463 | char *p; |
461 | 464 | ||
462 | spin_lock(&dcache_lock); | 465 | spin_lock(&dcache_lock); |
463 | p = __d_path(path, root, s, m->size - m->count); | 466 | p = __d_path(path, root, buf, size); |
464 | spin_unlock(&dcache_lock); | 467 | spin_unlock(&dcache_lock); |
465 | err = PTR_ERR(p); | 468 | res = PTR_ERR(p); |
466 | if (!IS_ERR(p)) { | 469 | if (!IS_ERR(p)) { |
467 | s = mangle_path(s, p, esc); | 470 | char *end = mangle_path(buf, p, esc); |
468 | if (s) { | 471 | if (end) |
469 | p = m->buf + m->count; | 472 | res = end - buf; |
470 | m->count = s - m->buf; | 473 | else |
471 | return 0; | 474 | res = -ENAMETOOLONG; |
472 | } | ||
473 | } | 475 | } |
474 | } | 476 | } |
475 | m->count = m->size; | 477 | seq_commit(m, res); |
476 | return err; | 478 | |
479 | return res < 0 ? res : 0; | ||
477 | } | 480 | } |
478 | 481 | ||
479 | /* | 482 | /* |
@@ -481,20 +484,21 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | |||
481 | */ | 484 | */ |
482 | int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc) | 485 | int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc) |
483 | { | 486 | { |
484 | if (m->count < m->size) { | 487 | char *buf; |
485 | char *s = m->buf + m->count; | 488 | size_t size = seq_get_buf(m, &buf); |
486 | char *p = dentry_path(dentry, s, m->size - m->count); | 489 | int res = -1; |
490 | |||
491 | if (size) { | ||
492 | char *p = dentry_path(dentry, buf, size); | ||
487 | if (!IS_ERR(p)) { | 493 | if (!IS_ERR(p)) { |
488 | s = mangle_path(s, p, esc); | 494 | char *end = mangle_path(buf, p, esc); |
489 | if (s) { | 495 | if (end) |
490 | p = m->buf + m->count; | 496 | res = end - buf; |
491 | m->count = s - m->buf; | ||
492 | return s - p; | ||
493 | } | ||
494 | } | 497 | } |
495 | } | 498 | } |
496 | m->count = m->size; | 499 | seq_commit(m, res); |
497 | return -1; | 500 | |
501 | return res; | ||
498 | } | 502 | } |
499 | 503 | ||
500 | int seq_bitmap(struct seq_file *m, const unsigned long *bits, | 504 | int seq_bitmap(struct seq_file *m, const unsigned long *bits, |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 1402d2d54f52..1c4c8f089970 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -459,14 +459,8 @@ smb_show_options(struct seq_file *s, struct vfsmount *m) | |||
459 | static void | 459 | static void |
460 | smb_unload_nls(struct smb_sb_info *server) | 460 | smb_unload_nls(struct smb_sb_info *server) |
461 | { | 461 | { |
462 | if (server->remote_nls) { | 462 | unload_nls(server->remote_nls); |
463 | unload_nls(server->remote_nls); | 463 | unload_nls(server->local_nls); |
464 | server->remote_nls = NULL; | ||
465 | } | ||
466 | if (server->local_nls) { | ||
467 | unload_nls(server->local_nls); | ||
468 | server->local_nls = NULL; | ||
469 | } | ||
470 | } | 464 | } |
471 | 465 | ||
472 | static void | 466 | static void |
diff --git a/fs/super.c b/fs/super.c index 0e7207b9815c..19eb70b374bc 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -465,6 +465,48 @@ rescan: | |||
465 | } | 465 | } |
466 | 466 | ||
467 | EXPORT_SYMBOL(get_super); | 467 | EXPORT_SYMBOL(get_super); |
468 | |||
469 | /** | ||
470 | * get_active_super - get an active reference to the superblock of a device | ||
471 | * @bdev: device to get the superblock for | ||
472 | * | ||
473 | * Scans the superblock list and finds the superblock of the file system | ||
474 | * mounted on the device given. Returns the superblock with an active | ||
475 | * reference and s_umount held exclusively or %NULL if none was found. | ||
476 | */ | ||
477 | struct super_block *get_active_super(struct block_device *bdev) | ||
478 | { | ||
479 | struct super_block *sb; | ||
480 | |||
481 | if (!bdev) | ||
482 | return NULL; | ||
483 | |||
484 | spin_lock(&sb_lock); | ||
485 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
486 | if (sb->s_bdev != bdev) | ||
487 | continue; | ||
488 | |||
489 | sb->s_count++; | ||
490 | spin_unlock(&sb_lock); | ||
491 | down_write(&sb->s_umount); | ||
492 | if (sb->s_root) { | ||
493 | spin_lock(&sb_lock); | ||
494 | if (sb->s_count > S_BIAS) { | ||
495 | atomic_inc(&sb->s_active); | ||
496 | sb->s_count--; | ||
497 | spin_unlock(&sb_lock); | ||
498 | return sb; | ||
499 | } | ||
500 | spin_unlock(&sb_lock); | ||
501 | } | ||
502 | up_write(&sb->s_umount); | ||
503 | put_super(sb); | ||
504 | yield(); | ||
505 | spin_lock(&sb_lock); | ||
506 | } | ||
507 | spin_unlock(&sb_lock); | ||
508 | return NULL; | ||
509 | } | ||
468 | 510 | ||
469 | struct super_block * user_get_super(dev_t dev) | 511 | struct super_block * user_get_super(dev_t dev) |
470 | { | 512 | { |
@@ -527,11 +569,15 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
527 | { | 569 | { |
528 | int retval; | 570 | int retval; |
529 | int remount_rw; | 571 | int remount_rw; |
530 | 572 | ||
573 | if (sb->s_frozen != SB_UNFROZEN) | ||
574 | return -EBUSY; | ||
575 | |||
531 | #ifdef CONFIG_BLOCK | 576 | #ifdef CONFIG_BLOCK |
532 | if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) | 577 | if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) |
533 | return -EACCES; | 578 | return -EACCES; |
534 | #endif | 579 | #endif |
580 | |||
535 | if (flags & MS_RDONLY) | 581 | if (flags & MS_RDONLY) |
536 | acct_auto_close(sb); | 582 | acct_auto_close(sb); |
537 | shrink_dcache_sb(sb); | 583 | shrink_dcache_sb(sb); |
@@ -743,9 +789,14 @@ int get_sb_bdev(struct file_system_type *fs_type, | |||
743 | * will protect the lockfs code from trying to start a snapshot | 789 | * will protect the lockfs code from trying to start a snapshot |
744 | * while we are mounting | 790 | * while we are mounting |
745 | */ | 791 | */ |
746 | down(&bdev->bd_mount_sem); | 792 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
793 | if (bdev->bd_fsfreeze_count > 0) { | ||
794 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
795 | error = -EBUSY; | ||
796 | goto error_bdev; | ||
797 | } | ||
747 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); | 798 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); |
748 | up(&bdev->bd_mount_sem); | 799 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
749 | if (IS_ERR(s)) | 800 | if (IS_ERR(s)) |
750 | goto error_s; | 801 | goto error_s; |
751 | 802 | ||
@@ -892,6 +943,16 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
892 | if (error) | 943 | if (error) |
893 | goto out_sb; | 944 | goto out_sb; |
894 | 945 | ||
946 | /* | ||
947 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE | ||
948 | * but s_maxbytes was an unsigned long long for many releases. Throw | ||
949 | * this warning for a little while to try and catch filesystems that | ||
950 | * violate this rule. This warning should be either removed or | ||
951 | * converted to a BUG() in 2.6.34. | ||
952 | */ | ||
953 | WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " | ||
954 | "negative value (%lld)\n", type->name, mnt->mnt_sb->s_maxbytes); | ||
955 | |||
895 | mnt->mnt_mountpoint = mnt->mnt_root; | 956 | mnt->mnt_mountpoint = mnt->mnt_root; |
896 | mnt->mnt_parent = mnt; | 957 | mnt->mnt_parent = mnt; |
897 | up_write(&mnt->mnt_sb->s_umount); | 958 | up_write(&mnt->mnt_sb->s_umount); |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index d5e5559e31db..381854461b28 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -1635,4 +1635,5 @@ const struct address_space_operations xfs_address_space_operations = { | |||
1635 | .direct_IO = xfs_vm_direct_IO, | 1635 | .direct_IO = xfs_vm_direct_IO, |
1636 | .migratepage = buffer_migrate_page, | 1636 | .migratepage = buffer_migrate_page, |
1637 | .is_partially_uptodate = block_is_partially_uptodate, | 1637 | .is_partially_uptodate = block_is_partially_uptodate, |
1638 | .error_remove_page = generic_error_remove_page, | ||
1638 | }; | 1639 | }; |
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c index 916c0ffb6083..c5bc67c4e3bb 100644 --- a/fs/xfs/linux-2.6/xfs_sysctl.c +++ b/fs/xfs/linux-2.6/xfs_sysctl.c | |||
@@ -26,7 +26,6 @@ STATIC int | |||
26 | xfs_stats_clear_proc_handler( | 26 | xfs_stats_clear_proc_handler( |
27 | ctl_table *ctl, | 27 | ctl_table *ctl, |
28 | int write, | 28 | int write, |
29 | struct file *filp, | ||
30 | void __user *buffer, | 29 | void __user *buffer, |
31 | size_t *lenp, | 30 | size_t *lenp, |
32 | loff_t *ppos) | 31 | loff_t *ppos) |
@@ -34,7 +33,7 @@ xfs_stats_clear_proc_handler( | |||
34 | int c, ret, *valp = ctl->data; | 33 | int c, ret, *valp = ctl->data; |
35 | __uint32_t vn_active; | 34 | __uint32_t vn_active; |
36 | 35 | ||
37 | ret = proc_dointvec_minmax(ctl, write, filp, buffer, lenp, ppos); | 36 | ret = proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); |
38 | 37 | ||
39 | if (!ret && write && *valp) { | 38 | if (!ret && write && *valp) { |
40 | printk("XFS Clearing xfsstats\n"); | 39 | printk("XFS Clearing xfsstats\n"); |