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 /fs | |
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
Diffstat (limited to 'fs')
-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 |
4 files changed, 47 insertions, 14 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 */ |