diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-24 15:12:40 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-24 15:12:40 -0500 |
| commit | d2346963bfcbb9a8ee783ca3c3b3bdd7448ec9d5 (patch) | |
| tree | 4ba57a6ec31f3a4683e7766fbf4f182d459a8b51 | |
| parent | 4a7cbb56fdbd92a47f57ca8b25bf5db35f0d6518 (diff) | |
| parent | 46fe44ce8777f087aa8ad4a2605fdcfb9c2d63af (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
quota: Pass information that quota is stored in system file to userspace
ext2: protect inode changes in the SETVERSION and SETFLAGS ioctls
jbd: Issue cache flush after checkpointing
| -rw-r--r-- | fs/ext2/ioctl.c | 22 | ||||
| -rw-r--r-- | fs/jbd/checkpoint.c | 27 | ||||
| -rw-r--r-- | fs/jbd/recovery.c | 4 | ||||
| -rw-r--r-- | fs/quota/dquot.c | 8 | ||||
| -rw-r--r-- | include/linux/quota.h | 6 |
5 files changed, 52 insertions, 15 deletions
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 1089f760c847..2de655f5d625 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
| @@ -77,10 +77,11 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 77 | flags = flags & EXT2_FL_USER_MODIFIABLE; | 77 | flags = flags & EXT2_FL_USER_MODIFIABLE; |
| 78 | flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; | 78 | flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; |
| 79 | ei->i_flags = flags; | 79 | ei->i_flags = flags; |
| 80 | mutex_unlock(&inode->i_mutex); | ||
| 81 | 80 | ||
| 82 | ext2_set_inode_flags(inode); | 81 | ext2_set_inode_flags(inode); |
| 83 | inode->i_ctime = CURRENT_TIME_SEC; | 82 | inode->i_ctime = CURRENT_TIME_SEC; |
| 83 | mutex_unlock(&inode->i_mutex); | ||
| 84 | |||
| 84 | mark_inode_dirty(inode); | 85 | mark_inode_dirty(inode); |
| 85 | setflags_out: | 86 | setflags_out: |
| 86 | mnt_drop_write_file(filp); | 87 | mnt_drop_write_file(filp); |
| @@ -88,20 +89,29 @@ setflags_out: | |||
| 88 | } | 89 | } |
| 89 | case EXT2_IOC_GETVERSION: | 90 | case EXT2_IOC_GETVERSION: |
| 90 | return put_user(inode->i_generation, (int __user *) arg); | 91 | return put_user(inode->i_generation, (int __user *) arg); |
| 91 | case EXT2_IOC_SETVERSION: | 92 | case EXT2_IOC_SETVERSION: { |
| 93 | __u32 generation; | ||
| 94 | |||
| 92 | if (!inode_owner_or_capable(inode)) | 95 | if (!inode_owner_or_capable(inode)) |
| 93 | return -EPERM; | 96 | return -EPERM; |
| 94 | ret = mnt_want_write_file(filp); | 97 | ret = mnt_want_write_file(filp); |
| 95 | if (ret) | 98 | if (ret) |
| 96 | return ret; | 99 | return ret; |
| 97 | if (get_user(inode->i_generation, (int __user *) arg)) { | 100 | if (get_user(generation, (int __user *) arg)) { |
| 98 | ret = -EFAULT; | 101 | ret = -EFAULT; |
| 99 | } else { | 102 | goto setversion_out; |
| 100 | inode->i_ctime = CURRENT_TIME_SEC; | ||
| 101 | mark_inode_dirty(inode); | ||
| 102 | } | 103 | } |
| 104 | |||
| 105 | mutex_lock(&inode->i_mutex); | ||
| 106 | inode->i_ctime = CURRENT_TIME_SEC; | ||
| 107 | inode->i_generation = generation; | ||
| 108 | mutex_unlock(&inode->i_mutex); | ||
| 109 | |||
| 110 | mark_inode_dirty(inode); | ||
| 111 | setversion_out: | ||
| 103 | mnt_drop_write_file(filp); | 112 | mnt_drop_write_file(filp); |
| 104 | return ret; | 113 | return ret; |
| 114 | } | ||
| 105 | case EXT2_IOC_GETRSVSZ: | 115 | case EXT2_IOC_GETRSVSZ: |
| 106 | if (test_opt(inode->i_sb, RESERVATION) | 116 | if (test_opt(inode->i_sb, RESERVATION) |
| 107 | && S_ISREG(inode->i_mode) | 117 | && S_ISREG(inode->i_mode) |
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 5d1a00a5041b..05f0754f2b46 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c | |||
| @@ -453,8 +453,6 @@ out: | |||
| 453 | * | 453 | * |
| 454 | * Return <0 on error, 0 on success, 1 if there was nothing to clean up. | 454 | * Return <0 on error, 0 on success, 1 if there was nothing to clean up. |
| 455 | * | 455 | * |
| 456 | * Called with the journal lock held. | ||
| 457 | * | ||
| 458 | * This is the only part of the journaling code which really needs to be | 456 | * This is the only part of the journaling code which really needs to be |
| 459 | * aware of transaction aborts. Checkpointing involves writing to the | 457 | * aware of transaction aborts. Checkpointing involves writing to the |
| 460 | * main filesystem area rather than to the journal, so it can proceed | 458 | * main filesystem area rather than to the journal, so it can proceed |
| @@ -472,13 +470,14 @@ int cleanup_journal_tail(journal_t *journal) | |||
| 472 | if (is_journal_aborted(journal)) | 470 | if (is_journal_aborted(journal)) |
| 473 | return 1; | 471 | return 1; |
| 474 | 472 | ||
| 475 | /* OK, work out the oldest transaction remaining in the log, and | 473 | /* |
| 474 | * OK, work out the oldest transaction remaining in the log, and | ||
| 476 | * the log block it starts at. | 475 | * the log block it starts at. |
| 477 | * | 476 | * |
| 478 | * If the log is now empty, we need to work out which is the | 477 | * If the log is now empty, we need to work out which is the |
| 479 | * next transaction ID we will write, and where it will | 478 | * next transaction ID we will write, and where it will |
| 480 | * start. */ | 479 | * start. |
| 481 | 480 | */ | |
| 482 | spin_lock(&journal->j_state_lock); | 481 | spin_lock(&journal->j_state_lock); |
| 483 | spin_lock(&journal->j_list_lock); | 482 | spin_lock(&journal->j_list_lock); |
| 484 | transaction = journal->j_checkpoint_transactions; | 483 | transaction = journal->j_checkpoint_transactions; |
| @@ -504,7 +503,25 @@ int cleanup_journal_tail(journal_t *journal) | |||
| 504 | spin_unlock(&journal->j_state_lock); | 503 | spin_unlock(&journal->j_state_lock); |
| 505 | return 1; | 504 | return 1; |
| 506 | } | 505 | } |
| 506 | spin_unlock(&journal->j_state_lock); | ||
| 507 | |||
| 508 | /* | ||
| 509 | * We need to make sure that any blocks that were recently written out | ||
| 510 | * --- perhaps by log_do_checkpoint() --- are flushed out before we | ||
| 511 | * drop the transactions from the journal. It's unlikely this will be | ||
| 512 | * necessary, especially with an appropriately sized journal, but we | ||
| 513 | * need this to guarantee correctness. Fortunately | ||
| 514 | * cleanup_journal_tail() doesn't get called all that often. | ||
| 515 | */ | ||
| 516 | if (journal->j_flags & JFS_BARRIER) | ||
| 517 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); | ||
| 507 | 518 | ||
| 519 | spin_lock(&journal->j_state_lock); | ||
| 520 | if (!tid_gt(first_tid, journal->j_tail_sequence)) { | ||
| 521 | spin_unlock(&journal->j_state_lock); | ||
| 522 | /* Someone else cleaned up journal so return 0 */ | ||
| 523 | return 0; | ||
| 524 | } | ||
| 508 | /* OK, update the superblock to recover the freed space. | 525 | /* OK, update the superblock to recover the freed space. |
| 509 | * Physical blocks come first: have we wrapped beyond the end of | 526 | * Physical blocks come first: have we wrapped beyond the end of |
| 510 | * the log? */ | 527 | * the log? */ |
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c index 5b43e96788e6..008bf062fd26 100644 --- a/fs/jbd/recovery.c +++ b/fs/jbd/recovery.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
| 21 | #include <linux/jbd.h> | 21 | #include <linux/jbd.h> |
| 22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
| 23 | #include <linux/blkdev.h> | ||
| 23 | #endif | 24 | #endif |
| 24 | 25 | ||
| 25 | /* | 26 | /* |
| @@ -263,6 +264,9 @@ int journal_recover(journal_t *journal) | |||
| 263 | err2 = sync_blockdev(journal->j_fs_dev); | 264 | err2 = sync_blockdev(journal->j_fs_dev); |
| 264 | if (!err) | 265 | if (!err) |
| 265 | err = err2; | 266 | err = err2; |
| 267 | /* Flush disk caches to get replayed data on the permanent storage */ | ||
| 268 | if (journal->j_flags & JFS_BARRIER) | ||
| 269 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); | ||
| 266 | 270 | ||
| 267 | return err; | 271 | return err; |
| 268 | } | 272 | } |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 5ec59b20cf76..46741970371b 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -2125,6 +2125,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, | |||
| 2125 | mutex_unlock(&dqopt->dqio_mutex); | 2125 | mutex_unlock(&dqopt->dqio_mutex); |
| 2126 | goto out_file_init; | 2126 | goto out_file_init; |
| 2127 | } | 2127 | } |
| 2128 | if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) | ||
| 2129 | dqopt->info[type].dqi_flags |= DQF_SYS_FILE; | ||
| 2128 | mutex_unlock(&dqopt->dqio_mutex); | 2130 | mutex_unlock(&dqopt->dqio_mutex); |
| 2129 | spin_lock(&dq_state_lock); | 2131 | spin_lock(&dq_state_lock); |
| 2130 | dqopt->flags |= dquot_state_flag(flags, type); | 2132 | dqopt->flags |= dquot_state_flag(flags, type); |
| @@ -2464,7 +2466,7 @@ int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
| 2464 | spin_lock(&dq_data_lock); | 2466 | spin_lock(&dq_data_lock); |
| 2465 | ii->dqi_bgrace = mi->dqi_bgrace; | 2467 | ii->dqi_bgrace = mi->dqi_bgrace; |
| 2466 | ii->dqi_igrace = mi->dqi_igrace; | 2468 | ii->dqi_igrace = mi->dqi_igrace; |
| 2467 | ii->dqi_flags = mi->dqi_flags & DQF_MASK; | 2469 | ii->dqi_flags = mi->dqi_flags & DQF_GETINFO_MASK; |
| 2468 | ii->dqi_valid = IIF_ALL; | 2470 | ii->dqi_valid = IIF_ALL; |
| 2469 | spin_unlock(&dq_data_lock); | 2471 | spin_unlock(&dq_data_lock); |
| 2470 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2472 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
| @@ -2490,8 +2492,8 @@ int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
| 2490 | if (ii->dqi_valid & IIF_IGRACE) | 2492 | if (ii->dqi_valid & IIF_IGRACE) |
| 2491 | mi->dqi_igrace = ii->dqi_igrace; | 2493 | mi->dqi_igrace = ii->dqi_igrace; |
| 2492 | if (ii->dqi_valid & IIF_FLAGS) | 2494 | if (ii->dqi_valid & IIF_FLAGS) |
| 2493 | mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | | 2495 | mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) | |
| 2494 | (ii->dqi_flags & DQF_MASK); | 2496 | (ii->dqi_flags & DQF_SETINFO_MASK); |
| 2495 | spin_unlock(&dq_data_lock); | 2497 | spin_unlock(&dq_data_lock); |
| 2496 | mark_info_dirty(sb, type); | 2498 | mark_info_dirty(sb, type); |
| 2497 | /* Force write to disk */ | 2499 | /* Force write to disk */ |
diff --git a/include/linux/quota.h b/include/linux/quota.h index cb7855699037..c09fa042b5ea 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
| @@ -230,7 +230,11 @@ struct mem_dqinfo { | |||
