diff options
Diffstat (limited to 'fs/ext4/namei.c')
| -rw-r--r-- | fs/ext4/namei.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 28aa2ed4297e..ab16beaa830d 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -28,14 +28,14 @@ | |||
| 28 | #include <linux/pagemap.h> | 28 | #include <linux/pagemap.h> |
| 29 | #include <linux/jbd2.h> | 29 | #include <linux/jbd2.h> |
| 30 | #include <linux/time.h> | 30 | #include <linux/time.h> |
| 31 | #include <linux/ext4_fs.h> | ||
| 32 | #include <linux/ext4_jbd2.h> | ||
| 33 | #include <linux/fcntl.h> | 31 | #include <linux/fcntl.h> |
| 34 | #include <linux/stat.h> | 32 | #include <linux/stat.h> |
| 35 | #include <linux/string.h> | 33 | #include <linux/string.h> |
| 36 | #include <linux/quotaops.h> | 34 | #include <linux/quotaops.h> |
| 37 | #include <linux/buffer_head.h> | 35 | #include <linux/buffer_head.h> |
| 38 | #include <linux/bio.h> | 36 | #include <linux/bio.h> |
| 37 | #include "ext4.h" | ||
| 38 | #include "ext4_jbd2.h" | ||
| 39 | 39 | ||
| 40 | #include "namei.h" | 40 | #include "namei.h" |
| 41 | #include "xattr.h" | 41 | #include "xattr.h" |
| @@ -57,10 +57,15 @@ static struct buffer_head *ext4_append(handle_t *handle, | |||
| 57 | 57 | ||
| 58 | *block = inode->i_size >> inode->i_sb->s_blocksize_bits; | 58 | *block = inode->i_size >> inode->i_sb->s_blocksize_bits; |
| 59 | 59 | ||
| 60 | if ((bh = ext4_bread(handle, inode, *block, 1, err))) { | 60 | bh = ext4_bread(handle, inode, *block, 1, err); |
| 61 | if (bh) { | ||
| 61 | inode->i_size += inode->i_sb->s_blocksize; | 62 | inode->i_size += inode->i_sb->s_blocksize; |
| 62 | EXT4_I(inode)->i_disksize = inode->i_size; | 63 | EXT4_I(inode)->i_disksize = inode->i_size; |
| 63 | ext4_journal_get_write_access(handle,bh); | 64 | *err = ext4_journal_get_write_access(handle, bh); |
| 65 | if (*err) { | ||
| 66 | brelse(bh); | ||
| 67 | bh = NULL; | ||
| 68 | } | ||
| 64 | } | 69 | } |
| 65 | return bh; | 70 | return bh; |
| 66 | } | 71 | } |
| @@ -348,7 +353,7 @@ dx_probe(struct dentry *dentry, struct inode *dir, | |||
| 348 | if (root->info.hash_version != DX_HASH_TEA && | 353 | if (root->info.hash_version != DX_HASH_TEA && |
| 349 | root->info.hash_version != DX_HASH_HALF_MD4 && | 354 | root->info.hash_version != DX_HASH_HALF_MD4 && |
| 350 | root->info.hash_version != DX_HASH_LEGACY) { | 355 | root->info.hash_version != DX_HASH_LEGACY) { |
| 351 | ext4_warning(dir->i_sb, __FUNCTION__, | 356 | ext4_warning(dir->i_sb, __func__, |
| 352 | "Unrecognised inode hash code %d", | 357 | "Unrecognised inode hash code %d", |
| 353 | root->info.hash_version); | 358 | root->info.hash_version); |
| 354 | brelse(bh); | 359 | brelse(bh); |
| @@ -362,7 +367,7 @@ dx_probe(struct dentry *dentry, struct inode *dir, | |||
| 362 | hash = hinfo->hash; | 367 | hash = hinfo->hash; |
| 363 | 368 | ||
| 364 | if (root->info.unused_flags & 1) { | 369 | if (root->info.unused_flags & 1) { |
| 365 | ext4_warning(dir->i_sb, __FUNCTION__, | 370 | ext4_warning(dir->i_sb, __func__, |
| 366 | "Unimplemented inode hash flags: %#06x", | 371 | "Unimplemented inode hash flags: %#06x", |
| 367 | root->info.unused_flags); | 372 | root->info.unused_flags); |
| 368 | brelse(bh); | 373 | brelse(bh); |
| @@ -371,7 +376,7 @@ dx_probe(struct dentry *dentry, struct inode *dir, | |||
| 371 | } | 376 | } |
| 372 | 377 | ||
| 373 | if ((indirect = root->info.indirect_levels) > 1) { | 378 | if ((indirect = root->info.indirect_levels) > 1) { |
| 374 | ext4_warning(dir->i_sb, __FUNCTION__, | 379 | ext4_warning(dir->i_sb, __func__, |
| 375 | "Unimplemented inode hash depth: %#06x", | 380 | "Unimplemented inode hash depth: %#06x", |
| 376 | root->info.indirect_levels); | 381 | root->info.indirect_levels); |
| 377 | brelse(bh); | 382 | brelse(bh); |
| @@ -384,7 +389,7 @@ dx_probe(struct dentry *dentry, struct inode *dir, | |||
| 384 | 389 | ||
| 385 | if (dx_get_limit(entries) != dx_root_limit(dir, | 390 | if (dx_get_limit(entries) != dx_root_limit(dir, |
| 386 | root->info.info_length)) { | 391 | root->info.info_length)) { |
| 387 | ext4_warning(dir->i_sb, __FUNCTION__, | 392 | ext4_warning(dir->i_sb, __func__, |
| 388 | "dx entry: limit != root limit"); | 393 | "dx entry: limit != root limit"); |
| 389 | brelse(bh); | 394 | brelse(bh); |
| 390 | *err = ERR_BAD_DX_DIR; | 395 | *err = ERR_BAD_DX_DIR; |
| @@ -396,7 +401,7 @@ dx_probe(struct dentry *dentry, struct inode *dir, | |||
| 396 | { | 401 | { |
| 397 | count = dx_get_count(entries); | 402 | count = dx_get_count(entries); |
| 398 | if (!count || count > dx_get_limit(entries)) { | 403 | if (!count || count > dx_get_limit(entries)) { |
| 399 | ext4_warning(dir->i_sb, __FUNCTION__, | 404 | ext4_warning(dir->i_sb, __func__, |
| 400 | "dx entry: no count or count > limit"); | 405 | "dx entry: no count or count > limit"); |
| 401 | brelse(bh); | 406 | brelse(bh); |
| 402 | *err = ERR_BAD_DX_DIR; | 407 | *err = ERR_BAD_DX_DIR; |
| @@ -441,7 +446,7 @@ dx_probe(struct dentry *dentry, struct inode *dir, | |||
| 441 | goto fail2; | 446 | goto fail2; |
| 442 | at = entries = ((struct dx_node *) bh->b_data)->entries; | 447 | at = entries = ((struct dx_node *) bh->b_data)->entries; |
| 443 | if (dx_get_limit(entries) != dx_node_limit (dir)) { | 448 | if (dx_get_limit(entries) != dx_node_limit (dir)) { |
| 444 | ext4_warning(dir->i_sb, __FUNCTION__, | 449 | ext4_warning(dir->i_sb, __func__, |
| 445 | "dx entry: limit != node limit"); | 450 | "dx entry: limit != node limit"); |
| 446 | brelse(bh); | 451 | brelse(bh); |
| 447 | *err = ERR_BAD_DX_DIR; | 452 | *err = ERR_BAD_DX_DIR; |
| @@ -457,7 +462,7 @@ fail2: | |||
| 457 | } | 462 | } |
| 458 | fail: | 463 | fail: |
| 459 | if (*err == ERR_BAD_DX_DIR) | 464 | if (*err == ERR_BAD_DX_DIR) |
| 460 | ext4_warning(dir->i_sb, __FUNCTION__, | 465 | ext4_warning(dir->i_sb, __func__, |
| 461 | "Corrupt dir inode %ld, running e2fsck is " | 466 | "Corrupt dir inode %ld, running e2fsck is " |
| 462 | "recommended.", dir->i_ino); | 467 | "recommended.", dir->i_ino); |
| 463 | return NULL; | 468 | return NULL; |
| @@ -914,7 +919,7 @@ restart: | |||
| 914 | wait_on_buffer(bh); | 919 | wait_on_buffer(bh); |
| 915 | if (!buffer_uptodate(bh)) { | 920 | if (!buffer_uptodate(bh)) { |
| 916 | /* read error, skip block & hope for the best */ | 921 | /* read error, skip block & hope for the best */ |
| 917 | ext4_error(sb, __FUNCTION__, "reading directory #%lu " | 922 | ext4_error(sb, __func__, "reading directory #%lu " |
| 918 | "offset %lu", dir->i_ino, | 923 | "offset %lu", dir->i_ino, |
| 919 | (unsigned long)block); | 924 | (unsigned long)block); |
| 920 | brelse(bh); | 925 | brelse(bh); |
| @@ -1007,7 +1012,7 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, | |||
| 1007 | retval = ext4_htree_next_block(dir, hash, frame, | 1012 | retval = ext4_htree_next_block(dir, hash, frame, |
| 1008 | frames, NULL); | 1013 | frames, NULL); |
| 1009 | if (retval < 0) { | 1014 | if (retval < 0) { |
| 1010 | ext4_warning(sb, __FUNCTION__, | 1015 | ext4_warning(sb, __func__, |
| 1011 | "error reading index page in directory #%lu", | 1016 | "error reading index page in directory #%lu", |
| 1012 | dir->i_ino); | 1017 | dir->i_ino); |
| 1013 | *err = retval; | 1018 | *err = retval; |
| @@ -1532,7 +1537,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, | |||
| 1532 | 1537 | ||
| 1533 | if (levels && (dx_get_count(frames->entries) == | 1538 | if (levels && (dx_get_count(frames->entries) == |
| 1534 | dx_get_limit(frames->entries))) { | 1539 | dx_get_limit(frames->entries))) { |
| 1535 | ext4_warning(sb, __FUNCTION__, | 1540 | ext4_warning(sb, __func__, |
| 1536 | "Directory index full!"); | 1541 | "Directory index full!"); |
| 1537 | err = -ENOSPC; | 1542 | err = -ENOSPC; |
| 1538 | goto cleanup; | 1543 | goto cleanup; |
| @@ -1860,11 +1865,11 @@ static int empty_dir (struct inode * inode) | |||
| 1860 | if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) || | 1865 | if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) || |
| 1861 | !(bh = ext4_bread (NULL, inode, 0, 0, &err))) { | 1866 | !(bh = ext4_bread (NULL, inode, 0, 0, &err))) { |
| 1862 | if (err) | 1867 | if (err) |
| 1863 | ext4_error(inode->i_sb, __FUNCTION__, | 1868 | ext4_error(inode->i_sb, __func__, |
| 1864 | "error %d reading directory #%lu offset 0", | 1869 | "error %d reading directory #%lu offset 0", |
| 1865 | err, inode->i_ino); | 1870 | err, inode->i_ino); |
| 1866 | else | 1871 | else |
| 1867 | ext4_warning(inode->i_sb, __FUNCTION__, | 1872 | ext4_warning(inode->i_sb, __func__, |
| 1868 | "bad directory (dir #%lu) - no data block", | 1873 | "bad directory (dir #%lu) - no data block", |
| 1869 | inode->i_ino); | 1874 | inode->i_ino); |
| 1870 | return 1; | 1875 | return 1; |
| @@ -1893,7 +1898,7 @@ static int empty_dir (struct inode * inode) | |||
| 1893 | offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err); | 1898 | offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err); |
| 1894 | if (!bh) { | 1899 | if (!bh) { |
| 1895 | if (err) | 1900 | if (err) |
| 1896 | ext4_error(sb, __FUNCTION__, | 1901 | ext4_error(sb, __func__, |
| 1897 | "error %d reading directory" | 1902 | "error %d reading directory" |
| 1898 | " #%lu offset %lu", | 1903 | " #%lu offset %lu", |
| 1899 | err, inode->i_ino, offset); | 1904 | err, inode->i_ino, offset); |
| @@ -2217,6 +2222,8 @@ retry: | |||
| 2217 | goto out_stop; | 2222 | goto out_stop; |
| 2218 | } | 2223 | } |
| 2219 | } else { | 2224 | } else { |
| 2225 | /* clear the extent format for fast symlink */ | ||
| 2226 | EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL; | ||
| 2220 | inode->i_op = &ext4_fast_symlink_inode_operations; | 2227 | inode->i_op = &ext4_fast_symlink_inode_operations; |
| 2221 | memcpy((char*)&EXT4_I(inode)->i_data,symname,l); | 2228 | memcpy((char*)&EXT4_I(inode)->i_data,symname,l); |
| 2222 | inode->i_size = l-1; | 2229 | inode->i_size = l-1; |
| @@ -2347,6 +2354,9 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
| 2347 | EXT4_FEATURE_INCOMPAT_FILETYPE)) | 2354 | EXT4_FEATURE_INCOMPAT_FILETYPE)) |
| 2348 | new_de->file_type = old_de->file_type; | 2355 | new_de->file_type = old_de->file_type; |
| 2349 | new_dir->i_version++; | 2356 | new_dir->i_version++; |
| 2357 | new_dir->i_ctime = new_dir->i_mtime = | ||
| 2358 | ext4_current_time(new_dir); | ||
| 2359 | ext4_mark_inode_dirty(handle, new_dir); | ||
| 2350 | BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata"); | 2360 | BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata"); |
| 2351 | ext4_journal_dirty_metadata(handle, new_bh); | 2361 | ext4_journal_dirty_metadata(handle, new_bh); |
| 2352 | brelse(new_bh); | 2362 | brelse(new_bh); |
