diff options
| author | NeilBrown <neilb@suse.de> | 2012-08-01 06:40:02 -0400 |
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2012-08-01 06:40:02 -0400 |
| commit | bb181e2e48f8c85db08c9cb015cbba9618dbf05c (patch) | |
| tree | 191bc24dd97bcb174535cc217af082f16da3b43d /fs/ext4 | |
| parent | d57368afe63b3b7b45ce6c2b8c5276417935be2f (diff) | |
| parent | c039c332f23e794deb6d6f37b9f07ff3b27fb2cf (diff) | |
Merge commit 'c039c332f23e794deb6d6f37b9f07ff3b27fb2cf' into md
Pull in pre-requisites for adding raid10 support to dm-raid.
Diffstat (limited to 'fs/ext4')
| -rw-r--r-- | fs/ext4/dir.c | 75 | ||||
| -rw-r--r-- | fs/ext4/file.c | 9 | ||||
| -rw-r--r-- | fs/ext4/fsync.c | 11 | ||||
| -rw-r--r-- | fs/ext4/ioctl.c | 5 | ||||
| -rw-r--r-- | fs/ext4/namei.c | 8 | ||||
| -rw-r--r-- | fs/ext4/super.c | 5 |
6 files changed, 32 insertions, 81 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index aa39e600d159..8e07d2a5a139 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
| @@ -324,74 +324,27 @@ static inline loff_t ext4_get_htree_eof(struct file *filp) | |||
| 324 | 324 | ||
| 325 | 325 | ||
| 326 | /* | 326 | /* |
| 327 | * ext4_dir_llseek() based on generic_file_llseek() to handle both | 327 | * ext4_dir_llseek() calls generic_file_llseek_size to handle htree |
| 328 | * non-htree and htree directories, where the "offset" is in terms | 328 | * directories, where the "offset" is in terms of the filename hash |
| 329 | * of the filename hash value instead of the byte offset. | 329 | * value instead of the byte offset. |
| 330 | * | 330 | * |
| 331 | * NOTE: offsets obtained *before* ext4_set_inode_flag(dir, EXT4_INODE_INDEX) | 331 | * Because we may return a 64-bit hash that is well beyond offset limits, |
| 332 | * will be invalid once the directory was converted into a dx directory | 332 | * we need to pass the max hash as the maximum allowable offset in |
| 333 | * the htree directory case. | ||
| 334 | * | ||
| 335 | * For non-htree, ext4_llseek already chooses the proper max offset. | ||
| 333 | */ | 336 | */ |
| 334 | loff_t ext4_dir_llseek(struct file *file, loff_t offset, int origin) | 337 | loff_t ext4_dir_llseek(struct file *file, loff_t offset, int origin) |
| 335 | { | 338 | { |
| 336 | struct inode *inode = file->f_mapping->host; | 339 | struct inode *inode = file->f_mapping->host; |
| 337 | loff_t ret = -EINVAL; | ||
| 338 | int dx_dir = is_dx_dir(inode); | 340 | int dx_dir = is_dx_dir(inode); |
| 341 | loff_t htree_max = ext4_get_htree_eof(file); | ||
| 339 | 342 | ||
| 340 | mutex_lock(&inode->i_mutex); | 343 | if (likely(dx_dir)) |
| 341 | 344 | return generic_file_llseek_size(file, offset, origin, | |
| 342 | /* NOTE: relative offsets with dx directories might not work | 345 | htree_max, htree_max); |
| 343 | * as expected, as it is difficult to figure out the | 346 | else |
| 344 | * correct offset between dx hashes */ | 347 | return ext4_llseek(file, offset, origin); |
| 345 | |||
| 346 | switch (origin) { | ||
| 347 | case SEEK_END: | ||
| 348 | if (unlikely(offset > 0)) | ||
| 349 | goto out_err; /* not supported for directories */ | ||
| 350 | |||
| 351 | /* so only negative offsets are left, does that have a | ||
| 352 | * meaning for directories at all? */ | ||
| 353 | if (dx_dir) | ||
| 354 | offset += ext4_get_htree_eof(file); | ||
| 355 | else | ||
| 356 | offset += inode->i_size; | ||
| 357 | break; | ||
| 358 | case SEEK_CUR: | ||
| 359 | /* | ||
| 360 | * Here we special-case the lseek(fd, 0, SEEK_CUR) | ||
| 361 | * position-querying operation. Avoid rewriting the "same" | ||
| 362 | * f_pos value back to the file because a concurrent read(), | ||
| 363 | * write() or lseek() might have altered it | ||
| 364 | */ | ||
| 365 | if (offset == 0) { | ||
| 366 | offset = file->f_pos; | ||
| 367 | goto out_ok; | ||
| 368 | } | ||
| 369 | |||
| 370 | offset += file->f_pos; | ||
| 371 | break; | ||
| 372 | } | ||
| 373 | |||
| 374 | if (unlikely(offset < 0)) | ||
| 375 | goto out_err; | ||
| 376 | |||
| 377 | if (!dx_dir) { | ||
| 378 | if (offset > inode->i_sb->s_maxbytes) | ||
| 379 | goto out_err; | ||
| 380 | } else if (offset > ext4_get_htree_eof(file)) | ||
| 381 | goto out_err; | ||
| 382 | |||
| 383 | /* Special lock needed here? */ | ||
| 384 | if (offset != file->f_pos) { | ||
| 385 | file->f_pos = offset; | ||
| 386 | file->f_version = 0; | ||
| 387 | } | ||
| 388 | |||
| 389 | out_ok: | ||
| 390 | ret = offset; | ||
| 391 | out_err: | ||
| 392 | mutex_unlock(&inode->i_mutex); | ||
| 393 | |||
| 394 | return ret; | ||
| 395 | } | 348 | } |
| 396 | 349 | ||
| 397 | /* | 350 | /* |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 8c7642a00054..782eecb57e43 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
| @@ -211,9 +211,9 @@ static int ext4_file_open(struct inode * inode, struct file * filp) | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /* | 213 | /* |
| 214 | * ext4_llseek() copied from generic_file_llseek() to handle both | 214 | * ext4_llseek() handles both block-mapped and extent-mapped maxbytes values |
| 215 | * block-mapped and extent-mapped maxbytes values. This should | 215 | * by calling generic_file_llseek_size() with the appropriate maxbytes |
| 216 | * otherwise be identical with generic_file_llseek(). | 216 | * value for each. |
| 217 | */ | 217 | */ |
| 218 | loff_t ext4_llseek(struct file *file, loff_t offset, int origin) | 218 | loff_t ext4_llseek(struct file *file, loff_t offset, int origin) |
| 219 | { | 219 | { |
| @@ -225,7 +225,8 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int origin) | |||
| 225 | else | 225 | else |
| 226 | maxbytes = inode->i_sb->s_maxbytes; | 226 | maxbytes = inode->i_sb->s_maxbytes; |
| 227 | 227 | ||
| 228 | return generic_file_llseek_size(file, offset, origin, maxbytes); | 228 | return generic_file_llseek_size(file, offset, origin, |
| 229 | maxbytes, i_size_read(inode)); | ||
| 229 | } | 230 | } |
| 230 | 231 | ||
| 231 | const struct file_operations ext4_file_operations = { | 232 | const struct file_operations ext4_file_operations = { |
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index bb6c7d811313..2a1dcea4f12e 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
| @@ -135,14 +135,7 @@ static int ext4_sync_parent(struct inode *inode) | |||
| 135 | inode = igrab(inode); | 135 | inode = igrab(inode); |
| 136 | while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { | 136 | while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { |
| 137 | ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); | 137 | ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); |
| 138 | dentry = NULL; | 138 | dentry = d_find_any_alias(inode); |
| 139 | spin_lock(&inode->i_lock); | ||
| 140 | if (!list_empty(&inode->i_dentry)) { | ||
| 141 | dentry = list_first_entry(&inode->i_dentry, | ||
| 142 | struct dentry, d_alias); | ||
| 143 | dget(dentry); | ||
| 144 | } | ||
| 145 | spin_unlock(&inode->i_lock); | ||
| 146 | if (!dentry) | 139 | if (!dentry) |
| 147 | break; | 140 | break; |
| 148 | next = igrab(dentry->d_parent->d_inode); | 141 | next = igrab(dentry->d_parent->d_inode); |
| @@ -232,7 +225,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 232 | 225 | ||
| 233 | if (!journal) { | 226 | if (!journal) { |
| 234 | ret = __sync_inode(inode, datasync); | 227 | ret = __sync_inode(inode, datasync); |
| 235 | if (!ret && !list_empty(&inode->i_dentry)) | 228 | if (!ret && !hlist_empty(&inode->i_dentry)) |
| 236 | ret = ext4_sync_parent(inode); | 229 | ret = ext4_sync_parent(inode); |
| 237 | goto out; | 230 | goto out; |
| 238 | } | 231 | } |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index e34deac3f366..7f7dad787603 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
| @@ -268,7 +268,6 @@ group_extend_out: | |||
| 268 | err = ext4_move_extents(filp, donor_filp, me.orig_start, | 268 | err = ext4_move_extents(filp, donor_filp, me.orig_start, |
| 269 | me.donor_start, me.len, &me.moved_len); | 269 | me.donor_start, me.len, &me.moved_len); |
| 270 | mnt_drop_write_file(filp); | 270 | mnt_drop_write_file(filp); |
| 271 | mnt_drop_write(filp->f_path.mnt); | ||
| 272 | 271 | ||
| 273 | if (copy_to_user((struct move_extent __user *)arg, | 272 | if (copy_to_user((struct move_extent __user *)arg, |
| 274 | &me, sizeof(me))) | 273 | &me, sizeof(me))) |
| @@ -390,7 +389,7 @@ group_add_out: | |||
| 390 | if (err) | 389 | if (err) |
| 391 | return err; | 390 | return err; |
| 392 | 391 | ||
| 393 | err = mnt_want_write(filp->f_path.mnt); | 392 | err = mnt_want_write_file(filp); |
| 394 | if (err) | 393 | if (err) |
| 395 | goto resizefs_out; | 394 | goto resizefs_out; |
| 396 | 395 | ||
| @@ -402,7 +401,7 @@ group_add_out: | |||
| 402 | } | 401 | } |
| 403 | if (err == 0) | 402 | if (err == 0) |
| 404 | err = err2; | 403 | err = err2; |
| 405 | mnt_drop_write(filp->f_path.mnt); | 404 | mnt_drop_write_file(filp); |
| 406 | resizefs_out: | 405 | resizefs_out: |
| 407 | ext4_resize_end(sb); | 406 | ext4_resize_end(sb); |
| 408 | return err; | 407 | return err; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5845cd97bf8b..d0d3f0e87f99 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -1312,7 +1312,7 @@ errout: | |||
| 1312 | return NULL; | 1312 | return NULL; |
| 1313 | } | 1313 | } |
| 1314 | 1314 | ||
| 1315 | static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 1315 | static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
| 1316 | { | 1316 | { |
| 1317 | struct inode *inode; | 1317 | struct inode *inode; |
| 1318 | struct ext4_dir_entry_2 *de; | 1318 | struct ext4_dir_entry_2 *de; |
| @@ -2072,8 +2072,8 @@ static int ext4_add_nondir(handle_t *handle, | |||
| 2072 | int err = ext4_add_entry(handle, dentry, inode); | 2072 | int err = ext4_add_entry(handle, dentry, inode); |
| 2073 | if (!err) { | 2073 | if (!err) { |
| 2074 | ext4_mark_inode_dirty(handle, inode); | 2074 | ext4_mark_inode_dirty(handle, inode); |
| 2075 | d_instantiate(dentry, inode); | ||
| 2076 | unlock_new_inode(inode); | 2075 | unlock_new_inode(inode); |
| 2076 | d_instantiate(dentry, inode); | ||
| 2077 | return 0; | 2077 | return 0; |
| 2078 | } | 2078 | } |
| 2079 | drop_nlink(inode); | 2079 | drop_nlink(inode); |
| @@ -2091,7 +2091,7 @@ static int ext4_add_nondir(handle_t *handle, | |||
| 2091 | * with d_instantiate(). | 2091 | * with d_instantiate(). |
| 2092 | */ | 2092 | */ |
| 2093 | static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 2093 | static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
| 2094 | struct nameidata *nd) | 2094 | bool excl) |
| 2095 | { | 2095 | { |
| 2096 | handle_t *handle; | 2096 | handle_t *handle; |
| 2097 | struct inode *inode; | 2097 | struct inode *inode; |
| @@ -2249,8 +2249,8 @@ out_clear_inode: | |||
| 2249 | err = ext4_mark_inode_dirty(handle, dir); | 2249 | err = ext4_mark_inode_dirty(handle, dir); |
| 2250 | if (err) | 2250 | if (err) |
| 2251 | goto out_clear_inode; | 2251 | goto out_clear_inode; |
| 2252 | d_instantiate(dentry, inode); | ||
| 2253 | unlock_new_inode(inode); | 2252 | unlock_new_inode(inode); |
| 2253 | d_instantiate(dentry, inode); | ||
| 2254 | out_stop: | 2254 | out_stop: |
| 2255 | brelse(dir_block); | 2255 | brelse(dir_block); |
| 2256 | ext4_journal_stop(handle); | 2256 | ext4_journal_stop(handle); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index eb7aa3e4ef05..d8759401ecae 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -4325,6 +4325,11 @@ static int ext4_sync_fs(struct super_block *sb, int wait) | |||
| 4325 | 4325 | ||
| 4326 | trace_ext4_sync_fs(sb, wait); | 4326 | trace_ext4_sync_fs(sb, wait); |
| 4327 | flush_workqueue(sbi->dio_unwritten_wq); | 4327 | flush_workqueue(sbi->dio_unwritten_wq); |
| 4328 | /* | ||
| 4329 | * Writeback quota in non-journalled quota case - journalled quota has | ||
| 4330 | * no dirty dquots | ||
| 4331 | */ | ||
| 4332 | dquot_writeback_dquots(sb, -1); | ||
| 4328 | if (jbd2_journal_start_commit(sbi->s_journal, &target)) { | 4333 | if (jbd2_journal_start_commit(sbi->s_journal, &target)) { |
| 4329 | if (wait) | 4334 | if (wait) |
| 4330 | jbd2_log_wait_commit(sbi->s_journal, target); | 4335 | jbd2_log_wait_commit(sbi->s_journal, target); |
