diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ext3/super.c | 10 | ||||
| -rw-r--r-- | fs/ext4/balloc.c | 77 | ||||
| -rw-r--r-- | fs/ext4/ext4.h | 3 | ||||
| -rw-r--r-- | fs/ext4/super.c | 11 | ||||
| -rw-r--r-- | fs/file_table.c | 4 | ||||
| -rw-r--r-- | fs/fuse/dev.c | 1 | ||||
| -rw-r--r-- | fs/inotify_user.c | 3 | ||||
| -rw-r--r-- | fs/jbd2/commit.c | 8 | ||||
| -rw-r--r-- | fs/lockd/svc4proc.c | 1 | ||||
| -rw-r--r-- | fs/lockd/svcproc.c | 1 | ||||
| -rw-r--r-- | fs/nfsd/vfs.c | 1 | ||||
| -rw-r--r-- | fs/pipe.c | 3 | ||||
| -rw-r--r-- | fs/proc/uptime.c | 38 |
13 files changed, 73 insertions, 88 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 18eaa78ecb4e..e5717a4fae67 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -281,7 +281,8 @@ void ext3_abort (struct super_block * sb, const char * function, | |||
| 281 | EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; | 281 | EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; |
| 282 | sb->s_flags |= MS_RDONLY; | 282 | sb->s_flags |= MS_RDONLY; |
| 283 | EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT; | 283 | EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT; |
| 284 | journal_abort(EXT3_SB(sb)->s_journal, -EIO); | 284 | if (EXT3_SB(sb)->s_journal) |
| 285 | journal_abort(EXT3_SB(sb)->s_journal, -EIO); | ||
| 285 | } | 286 | } |
| 286 | 287 | ||
| 287 | void ext3_warning (struct super_block * sb, const char * function, | 288 | void ext3_warning (struct super_block * sb, const char * function, |
| @@ -390,11 +391,14 @@ static void ext3_put_super (struct super_block * sb) | |||
| 390 | { | 391 | { |
| 391 | struct ext3_sb_info *sbi = EXT3_SB(sb); | 392 | struct ext3_sb_info *sbi = EXT3_SB(sb); |
| 392 | struct ext3_super_block *es = sbi->s_es; | 393 | struct ext3_super_block *es = sbi->s_es; |
| 393 | int i; | 394 | int i, err; |
| 394 | 395 | ||
| 395 | ext3_xattr_put_super(sb); | 396 | ext3_xattr_put_super(sb); |
| 396 | if (journal_destroy(sbi->s_journal) < 0) | 397 | err = journal_destroy(sbi->s_journal); |
| 398 | sbi->s_journal = NULL; | ||
| 399 | if (err < 0) | ||
| 397 | ext3_abort(sb, __func__, "Couldn't clean up the journal"); | 400 | ext3_abort(sb, __func__, "Couldn't clean up the journal"); |
| 401 | |||
| 398 | if (!(sb->s_flags & MS_RDONLY)) { | 402 | if (!(sb->s_flags & MS_RDONLY)) { |
| 399 | EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); | 403 | EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); |
| 400 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 404 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index b9821be709bd..d2003cdc36aa 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -589,21 +589,23 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
| 589 | return; | 589 | return; |
| 590 | } | 590 | } |
| 591 | 591 | ||
| 592 | int ext4_claim_free_blocks(struct ext4_sb_info *sbi, | 592 | /** |
| 593 | s64 nblocks) | 593 | * ext4_has_free_blocks() |
| 594 | * @sbi: in-core super block structure. | ||
| 595 | * @nblocks: number of needed blocks | ||
| 596 | * | ||
| 597 | * Check if filesystem has nblocks free & available for allocation. | ||
| 598 | * On success return 1, return 0 on failure. | ||
| 599 | */ | ||
| 600 | int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | ||
| 594 | { | 601 | { |
| 595 | s64 free_blocks, dirty_blocks; | 602 | s64 free_blocks, dirty_blocks, root_blocks; |
| 596 | s64 root_blocks = 0; | ||
| 597 | struct percpu_counter *fbc = &sbi->s_freeblocks_counter; | 603 | struct percpu_counter *fbc = &sbi->s_freeblocks_counter; |
| 598 | struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter; | 604 | struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter; |
| 599 | 605 | ||
| 600 | free_blocks = percpu_counter_read_positive(fbc); | 606 | free_blocks = percpu_counter_read_positive(fbc); |
| 601 | dirty_blocks = percpu_counter_read_positive(dbc); | 607 | dirty_blocks = percpu_counter_read_positive(dbc); |
| 602 | 608 | root_blocks = ext4_r_blocks_count(sbi->s_es); | |
| 603 | if (!capable(CAP_SYS_RESOURCE) && | ||
| 604 | sbi->s_resuid != current->fsuid && | ||
| 605 | (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid))) | ||
| 606 | root_blocks = ext4_r_blocks_count(sbi->s_es); | ||
| 607 | 609 | ||
| 608 | if (free_blocks - (nblocks + root_blocks + dirty_blocks) < | 610 | if (free_blocks - (nblocks + root_blocks + dirty_blocks) < |
| 609 | EXT4_FREEBLOCKS_WATERMARK) { | 611 | EXT4_FREEBLOCKS_WATERMARK) { |
| @@ -616,57 +618,32 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, | |||
| 616 | } | 618 | } |
| 617 | } | 619 | } |
| 618 | /* Check whether we have space after | 620 | /* Check whether we have space after |
| 619 | * accounting for current dirty blocks | 621 | * accounting for current dirty blocks & root reserved blocks. |
| 620 | */ | 622 | */ |
| 621 | if (free_blocks < ((root_blocks + nblocks) + dirty_blocks)) | 623 | if (free_blocks >= ((root_blocks + nblocks) + dirty_blocks)) |
| 622 | /* we don't have free space */ | 624 | return 1; |
| 623 | return -ENOSPC; | 625 | |
| 626 | /* Hm, nope. Are (enough) root reserved blocks available? */ | ||
| 627 | if (sbi->s_resuid == current->fsuid || | ||
| 628 | ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || | ||
| 629 | capable(CAP_SYS_RESOURCE)) { | ||
| 630 | if (free_blocks >= (nblocks + dirty_blocks)) | ||
| 631 | return 1; | ||
| 632 | } | ||
| 624 | 633 | ||
| 625 | /* Add the blocks to nblocks */ | ||
| 626 | percpu_counter_add(dbc, nblocks); | ||
| 627 | return 0; | 634 | return 0; |
| 628 | } | 635 | } |
| 629 | 636 | ||
| 630 | /** | 637 | int ext4_claim_free_blocks(struct ext4_sb_info *sbi, |
| 631 | * ext4_has_free_blocks() | ||
| 632 | * @sbi: in-core super block structure. | ||
| 633 | * @nblocks: number of neeed blocks | ||
| 634 | * | ||
| 635 | * Check if filesystem has free blocks available for allocation. | ||
| 636 | * Return the number of blocks avaible for allocation for this request | ||
| 637 | * On success, return nblocks | ||
| 638 | */ | ||
| 639 | ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, | ||
| 640 | s64 nblocks) | 638 | s64 nblocks) |
| 641 | { | 639 | { |
| 642 | s64 free_blocks, dirty_blocks; | 640 | if (ext4_has_free_blocks(sbi, nblocks)) { |
| 643 | s64 root_blocks = 0; | 641 | percpu_counter_add(&sbi->s_dirtyblocks_counter, nblocks); |
| 644 | struct percpu_counter *fbc = &sbi->s_freeblocks_counter; | ||
| 645 | struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter; | ||
| 646 | |||
| 647 | free_blocks = percpu_counter_read_positive(fbc); | ||
| 648 | dirty_blocks = percpu_counter_read_positive(dbc); | ||
| 649 | |||
| 650 | if (!capable(CAP_SYS_RESOURCE) && | ||
| 651 | sbi->s_resuid != current->fsuid && | ||
| 652 | (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid))) | ||
| 653 | root_blocks = ext4_r_blocks_count(sbi->s_es); | ||
| 654 | |||
| 655 | if (free_blocks - (nblocks + root_blocks + dirty_blocks) < | ||
| 656 | EXT4_FREEBLOCKS_WATERMARK) { | ||
| 657 | free_blocks = percpu_counter_sum(fbc); | ||
| 658 | dirty_blocks = percpu_counter_sum(dbc); | ||
| 659 | } | ||
| 660 | if (free_blocks <= (root_blocks + dirty_blocks)) | ||
| 661 | /* we don't have free space */ | ||
| 662 | return 0; | 642 | return 0; |
| 663 | 643 | } else | |
| 664 | if (free_blocks - (root_blocks + dirty_blocks) < nblocks) | 644 | return -ENOSPC; |
| 665 | return free_blocks - (root_blocks + dirty_blocks); | ||
| 666 | return nblocks; | ||
| 667 | } | 645 | } |
| 668 | 646 | ||
| 669 | |||
| 670 | /** | 647 | /** |
| 671 | * ext4_should_retry_alloc() | 648 | * ext4_should_retry_alloc() |
| 672 | * @sb: super block | 649 | * @sb: super block |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4880cc3e6727..b0537c827024 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -1003,8 +1003,7 @@ extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, | |||
| 1003 | ext4_lblk_t iblock, ext4_fsblk_t goal, | 1003 | ext4_lblk_t iblock, ext4_fsblk_t goal, |
| 1004 | unsigned long *count, int *errp); | 1004 | unsigned long *count, int *errp); |
| 1005 | extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); | 1005 | extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); |
| 1006 | extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, | 1006 | extern int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); |
| 1007 | s64 nblocks); | ||
| 1008 | extern void ext4_free_blocks(handle_t *handle, struct inode *inode, | 1007 | extern void ext4_free_blocks(handle_t *handle, struct inode *inode, |
| 1009 | ext4_fsblk_t block, unsigned long count, int metadata); | 1008 | ext4_fsblk_t block, unsigned long count, int metadata); |
| 1010 | extern void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, | 1009 | extern void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index bdddea14e782..994859df010e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -333,7 +333,8 @@ void ext4_abort(struct super_block *sb, const char *function, | |||
| 333 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 333 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
| 334 | sb->s_flags |= MS_RDONLY; | 334 | sb->s_flags |= MS_RDONLY; |
| 335 | EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT; | 335 | EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT; |
| 336 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); | 336 | if (EXT4_SB(sb)->s_journal) |
| 337 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); | ||
| 337 | } | 338 | } |
| 338 | 339 | ||
| 339 | void ext4_warning(struct super_block *sb, const char *function, | 340 | void ext4_warning(struct super_block *sb, const char *function, |
| @@ -442,14 +443,16 @@ static void ext4_put_super(struct super_block *sb) | |||
| 442 | { | 443 | { |
| 443 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 444 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 444 | struct ext4_super_block *es = sbi->s_es; | 445 | struct ext4_super_block *es = sbi->s_es; |
| 445 | int i; | 446 | int i, err; |
| 446 | 447 | ||
| 447 | ext4_mb_release(sb); | 448 | ext4_mb_release(sb); |
| 448 | ext4_ext_release(sb); | 449 | ext4_ext_release(sb); |
| 449 | ext4_xattr_put_super(sb); | 450 | ext4_xattr_put_super(sb); |
| 450 | if (jbd2_journal_destroy(sbi->s_journal) < 0) | 451 | err = jbd2_journal_destroy(sbi->s_journal); |
| 451 | ext4_abort(sb, __func__, "Couldn't clean up the journal"); | ||
| 452 | sbi->s_journal = NULL; | 452 | sbi->s_journal = NULL; |
| 453 | if (err < 0) | ||
| 454 | ext4_abort(sb, __func__, "Couldn't clean up the journal"); | ||
| 455 | |||
| 453 | if (!(sb->s_flags & MS_RDONLY)) { | 456 | if (!(sb->s_flags & MS_RDONLY)) { |
| 454 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 457 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
| 455 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 458 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
diff --git a/fs/file_table.c b/fs/file_table.c index efc06faede6c..5ad0eca6eea2 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
| @@ -269,6 +269,10 @@ void __fput(struct file *file) | |||
| 269 | eventpoll_release(file); | 269 | eventpoll_release(file); |
| 270 | locks_remove_flock(file); | 270 | locks_remove_flock(file); |
| 271 | 271 | ||
| 272 | if (unlikely(file->f_flags & FASYNC)) { | ||
| 273 | if (file->f_op && file->f_op->fasync) | ||
| 274 | file->f_op->fasync(-1, file, 0); | ||
| 275 | } | ||
| 272 | if (file->f_op && file->f_op->release) | 276 | if (file->f_op && file->f_op->release) |
| 273 | file->f_op->release(inode, file); | 277 | file->f_op->release(inode, file); |
| 274 | security_file_free(file); | 278 | security_file_free(file); |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 87250b6a8682..b72361479be2 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -1056,7 +1056,6 @@ static int fuse_dev_release(struct inode *inode, struct file *file) | |||
| 1056 | end_requests(fc, &fc->pending); | 1056 | end_requests(fc, &fc->pending); |
| 1057 | end_requests(fc, &fc->processing); | 1057 | end_requests(fc, &fc->processing); |
| 1058 | spin_unlock(&fc->lock); | 1058 | spin_unlock(&fc->lock); |
| 1059 | fasync_helper(-1, file, 0, &fc->fasync); | ||
| 1060 | fuse_conn_put(fc); | 1059 | fuse_conn_put(fc); |
| 1061 | } | 1060 | } |
| 1062 | 1061 | ||
diff --git a/fs/inotify_user.c b/fs/inotify_user.c index d85c7d931cdf..d367e9b92862 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c | |||
| @@ -537,9 +537,6 @@ static int inotify_release(struct inode *ignored, struct file *file) | |||
| 537 | inotify_dev_event_dequeue(dev); | 537 | inotify_dev_event_dequeue(dev); |
| 538 | mutex_unlock(&dev->ev_mutex); | 538 | mutex_unlock(&dev->ev_mutex); |
| 539 | 539 | ||
| 540 | if (file->f_flags & FASYNC) | ||
| 541 | inotify_fasync(-1, file, 0); | ||
| 542 | |||
| 543 | /* free this device: the put matching the get in inotify_init() */ | 540 | /* free this device: the put matching the get in inotify_init() */ |
| 544 | put_inotify_dev(dev); | 541 | put_inotify_dev(dev); |
| 545 | 542 | ||
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 8b119e16aa36..ebc667bc54a8 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
| @@ -974,6 +974,9 @@ restart_loop: | |||
| 974 | journal->j_committing_transaction = NULL; | 974 | journal->j_committing_transaction = NULL; |
| 975 | spin_unlock(&journal->j_state_lock); | 975 | spin_unlock(&journal->j_state_lock); |
| 976 | 976 | ||
| 977 | if (journal->j_commit_callback) | ||
| 978 | journal->j_commit_callback(journal, commit_transaction); | ||
| 979 | |||
| 977 | if (commit_transaction->t_checkpoint_list == NULL && | 980 | if (commit_transaction->t_checkpoint_list == NULL && |
| 978 | commit_transaction->t_checkpoint_io_list == NULL) { | 981 | commit_transaction->t_checkpoint_io_list == NULL) { |
| 979 | __jbd2_journal_drop_transaction(journal, commit_transaction); | 982 | __jbd2_journal_drop_transaction(journal, commit_transaction); |
| @@ -995,11 +998,8 @@ restart_loop: | |||
| 995 | } | 998 | } |
| 996 | spin_unlock(&journal->j_list_lock); | 999 | spin_unlock(&journal->j_list_lock); |
| 997 | 1000 | ||
| 998 | if (journal->j_commit_callback) | ||
| 999 | journal->j_commit_callback(journal, commit_transaction); | ||
| 1000 | |||
| 1001 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", | 1001 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", |
| 1002 | journal->j_devname, commit_transaction->t_tid, | 1002 | journal->j_devname, journal->j_commit_sequence, |
| 1003 | journal->j_tail_sequence); | 1003 | journal->j_tail_sequence); |
| 1004 | jbd_debug(1, "JBD: commit %d complete, head %d\n", | 1004 | jbd_debug(1, "JBD: commit %d complete, head %d\n", |
| 1005 | journal->j_commit_sequence, journal->j_tail_sequence); | 1005 | journal->j_commit_sequence, journal->j_tail_sequence); |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 014f6ce48172..4dfdcbc6bf68 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
| @@ -434,6 +434,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
| 434 | * reclaim all locks we hold on this server. | 434 | * reclaim all locks we hold on this server. |
| 435 | */ | 435 | */ |
| 436 | memset(&saddr, 0, sizeof(saddr)); | 436 | memset(&saddr, 0, sizeof(saddr)); |
| 437 | saddr.sin_family = AF_INET; | ||
| 437 | saddr.sin_addr.s_addr = argp->addr; | 438 | saddr.sin_addr.s_addr = argp->addr; |
| 438 | nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state); | 439 | nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state); |
| 439 | 440 | ||
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 548b0bb2b84d..3ca89e2a9381 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
| @@ -466,6 +466,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
| 466 | * reclaim all locks we hold on this server. | 466 | * reclaim all locks we hold on this server. |
| 467 | */ | 467 | */ |
| 468 | memset(&saddr, 0, sizeof(saddr)); | 468 | memset(&saddr, 0, sizeof(saddr)); |
| 469 | saddr.sin_family = AF_INET; | ||
| 469 | saddr.sin_addr.s_addr = argp->addr; | 470 | saddr.sin_addr.s_addr = argp->addr; |
| 470 | nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state); | 471 | nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state); |
| 471 | 472 | ||
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 0bc56f6d9276..848a03e83a42 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -1912,6 +1912,7 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func, | |||
| 1912 | de = (struct buffered_dirent *)((char *)de + reclen); | 1912 | de = (struct buffered_dirent *)((char *)de + reclen); |
| 1913 | } | 1913 | } |
| 1914 | offset = vfs_llseek(file, 0, SEEK_CUR); | 1914 | offset = vfs_llseek(file, 0, SEEK_CUR); |
| 1915 | cdp->err = nfserr_eof; | ||
| 1915 | if (!buf.full) | 1916 | if (!buf.full) |
| 1916 | break; | 1917 | break; |
| 1917 | } | 1918 | } |
| @@ -717,14 +717,12 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on) | |||
| 717 | static int | 717 | static int |
| 718 | pipe_read_release(struct inode *inode, struct file *filp) | 718 | pipe_read_release(struct inode *inode, struct file *filp) |
| 719 | { | 719 | { |
| 720 | pipe_read_fasync(-1, filp, 0); | ||
| 721 | return pipe_release(inode, 1, 0); | 720 | return pipe_release(inode, 1, 0); |
| 722 | } | 721 | } |
| 723 | 722 | ||
| 724 | static int | 723 | static int |
| 725 | pipe_write_release(struct inode *inode, struct file *filp) | 724 | pipe_write_release(struct inode *inode, struct file *filp) |
| 726 | { | 725 | { |
| 727 | pipe_write_fasync(-1, filp, 0); | ||
| 728 | return pipe_release(inode, 0, 1); | 726 | return pipe_release(inode, 0, 1); |
| 729 | } | 727 | } |
| 730 | 728 | ||
| @@ -733,7 +731,6 @@ pipe_rdwr_release(struct inode *inode, struct file *filp) | |||
| 733 | { | 731 | { |
| 734 | int decr, decw; | 732 | int decr, decw; |
| 735 | 733 | ||
| 736 | pipe_rdwr_fasync(-1, filp, 0); | ||
| 737 | decr = (filp->f_mode & FMODE_READ) != 0; | 734 | decr = (filp->f_mode & FMODE_READ) != 0; |
| 738 | decw = (filp->f_mode & FMODE_WRITE) != 0; | 735 | decw = (filp->f_mode & FMODE_WRITE) != 0; |
| 739 | return pipe_release(inode, decr, decw); | 736 | return pipe_release(inode, decr, decw); |
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c index 0c10a0b3f146..df26aa88fa47 100644 --- a/fs/proc/uptime.c +++ b/fs/proc/uptime.c | |||
| @@ -1,43 +1,45 @@ | |||
| 1 | #include <linux/fs.h> | ||
| 2 | #include <linux/init.h> | 1 | #include <linux/init.h> |
| 3 | #include <linux/proc_fs.h> | 2 | #include <linux/proc_fs.h> |
| 4 | #include <linux/sched.h> | 3 | #include <linux/sched.h> |
| 5 | #include <linux/seq_file.h> | ||
| 6 | #include <linux/time.h> | 4 | #include <linux/time.h> |
| 7 | #include <asm/cputime.h> | 5 | #include <asm/cputime.h> |
| 8 | 6 | ||
| 9 | static int uptime_proc_show(struct seq_file *m, void *v) | 7 | static int proc_calc_metrics(char *page, char **start, off_t off, |
| 8 | int count, int *eof, int len) | ||
| 9 | { | ||
| 10 | if (len <= off + count) | ||
| 11 | *eof = 1; | ||
| 12 | *start = page + off; | ||
| 13 | len -= off; | ||
| 14 | if (len > count) | ||
| 15 | len = count; | ||
| 16 | if (len < 0) | ||
| 17 | len = 0; | ||
| 18 | return len; | ||
| 19 | } | ||
| 20 | |||
| 21 | static int uptime_read_proc(char *page, char **start, off_t off, int count, | ||
| 22 | int *eof, void *data) | ||
| 10 | { | 23 | { |
| 11 | struct timespec uptime; | 24 | struct timespec uptime; |
| 12 | struct timespec idle; | 25 | struct timespec idle; |
| 26 | int len; | ||
| 13 | cputime_t idletime = cputime_add(init_task.utime, init_task.stime); | 27 | cputime_t idletime = cputime_add(init_task.utime, init_task.stime); |
| 14 | 28 | ||
| 15 | do_posix_clock_monotonic_gettime(&uptime); | 29 | do_posix_clock_monotonic_gettime(&uptime); |
| 16 | monotonic_to_bootbased(&uptime); | 30 | monotonic_to_bootbased(&uptime); |
| 17 | cputime_to_timespec(idletime, &idle); | 31 | cputime_to_timespec(idletime, &idle); |
| 18 | seq_printf(m, "%lu.%02lu %lu.%02lu\n", | 32 | len = sprintf(page, "%lu.%02lu %lu.%02lu\n", |
| 19 | (unsigned long) uptime.tv_sec, | 33 | (unsigned long) uptime.tv_sec, |
| 20 | (uptime.tv_nsec / (NSEC_PER_SEC / 100)), | 34 | (uptime.tv_nsec / (NSEC_PER_SEC / 100)), |
| 21 | (unsigned long) idle.tv_sec, | 35 | (unsigned long) idle.tv_sec, |
| 22 | (idle.tv_nsec / (NSEC_PER_SEC / 100))); | 36 | (idle.tv_nsec / (NSEC_PER_SEC / 100))); |
| 23 | return 0; | 37 | return proc_calc_metrics(page, start, off, count, eof, len); |
| 24 | } | 38 | } |
| 25 | 39 | ||
| 26 | static int uptime_proc_open(struct inode *inode, struct file *file) | ||
| 27 | { | ||
| 28 | return single_open(file, uptime_proc_show, NULL); | ||
| 29 | } | ||
| 30 | |||
| 31 | static const struct file_operations uptime_proc_fops = { | ||
| 32 | .open = uptime_proc_open, | ||
| 33 | .read = seq_read, | ||
| 34 | .llseek = seq_lseek, | ||
| 35 | .release = single_release, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static int __init proc_uptime_init(void) | 40 | static int __init proc_uptime_init(void) |
| 39 | { | 41 | { |
| 40 | proc_create("uptime", 0, NULL, &uptime_proc_fops); | 42 | create_proc_read_entry("uptime", 0, NULL, uptime_read_proc, NULL); |
| 41 | return 0; | 43 | return 0; |
| 42 | } | 44 | } |
| 43 | module_init(proc_uptime_init); | 45 | module_init(proc_uptime_init); |
