diff options
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 22098e1cd085..07eb6649e4fa 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "ext4.h" | 37 | #include "ext4.h" |
38 | #include "ext4_jbd2.h" | 38 | #include "ext4_jbd2.h" |
39 | 39 | ||
40 | #include "namei.h" | ||
41 | #include "xattr.h" | 40 | #include "xattr.h" |
42 | #include "acl.h" | 41 | #include "acl.h" |
43 | 42 | ||
@@ -750,7 +749,7 @@ static int dx_make_map(struct ext4_dir_entry_2 *de, unsigned blocksize, | |||
750 | ext4fs_dirhash(de->name, de->name_len, &h); | 749 | ext4fs_dirhash(de->name, de->name_len, &h); |
751 | map_tail--; | 750 | map_tail--; |
752 | map_tail->hash = h.hash; | 751 | map_tail->hash = h.hash; |
753 | map_tail->offs = (u16) ((char *) de - base); | 752 | map_tail->offs = ((char *) de - base)>>2; |
754 | map_tail->size = le16_to_cpu(de->rec_len); | 753 | map_tail->size = le16_to_cpu(de->rec_len); |
755 | count++; | 754 | count++; |
756 | cond_resched(); | 755 | cond_resched(); |
@@ -1148,7 +1147,8 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count, | |||
1148 | unsigned rec_len = 0; | 1147 | unsigned rec_len = 0; |
1149 | 1148 | ||
1150 | while (count--) { | 1149 | while (count--) { |
1151 | struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + map->offs); | 1150 | struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) |
1151 | (from + (map->offs<<2)); | ||
1152 | rec_len = EXT4_DIR_REC_LEN(de->name_len); | 1152 | rec_len = EXT4_DIR_REC_LEN(de->name_len); |
1153 | memcpy (to, de, rec_len); | 1153 | memcpy (to, de, rec_len); |
1154 | ((struct ext4_dir_entry_2 *) to)->rec_len = | 1154 | ((struct ext4_dir_entry_2 *) to)->rec_len = |
@@ -1997,7 +1997,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
1997 | if (!ext4_handle_valid(handle)) | 1997 | if (!ext4_handle_valid(handle)) |
1998 | return 0; | 1998 | return 0; |
1999 | 1999 | ||
2000 | lock_super(sb); | 2000 | mutex_lock(&EXT4_SB(sb)->s_orphan_lock); |
2001 | if (!list_empty(&EXT4_I(inode)->i_orphan)) | 2001 | if (!list_empty(&EXT4_I(inode)->i_orphan)) |
2002 | goto out_unlock; | 2002 | goto out_unlock; |
2003 | 2003 | ||
@@ -2006,9 +2006,13 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
2006 | 2006 | ||
2007 | /* @@@ FIXME: Observation from aviro: | 2007 | /* @@@ FIXME: Observation from aviro: |
2008 | * I think I can trigger J_ASSERT in ext4_orphan_add(). We block | 2008 | * I think I can trigger J_ASSERT in ext4_orphan_add(). We block |
2009 | * here (on lock_super()), so race with ext4_link() which might bump | 2009 | * here (on s_orphan_lock), so race with ext4_link() which might bump |
2010 | * ->i_nlink. For, say it, character device. Not a regular file, | 2010 | * ->i_nlink. For, say it, character device. Not a regular file, |
2011 | * not a directory, not a symlink and ->i_nlink > 0. | 2011 | * not a directory, not a symlink and ->i_nlink > 0. |
2012 | * | ||
2013 | * tytso, 4/25/2009: I'm not sure how that could happen; | ||
2014 | * shouldn't the fs core protect us from these sort of | ||
2015 | * unlink()/link() races? | ||
2012 | */ | 2016 | */ |
2013 | J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 2017 | J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
2014 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); | 2018 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); |
@@ -2045,7 +2049,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
2045 | jbd_debug(4, "orphan inode %lu will point to %d\n", | 2049 | jbd_debug(4, "orphan inode %lu will point to %d\n", |
2046 | inode->i_ino, NEXT_ORPHAN(inode)); | 2050 | inode->i_ino, NEXT_ORPHAN(inode)); |
2047 | out_unlock: | 2051 | out_unlock: |
2048 | unlock_super(sb); | 2052 | mutex_unlock(&EXT4_SB(sb)->s_orphan_lock); |
2049 | ext4_std_error(inode->i_sb, err); | 2053 | ext4_std_error(inode->i_sb, err); |
2050 | return err; | 2054 | return err; |
2051 | } | 2055 | } |
@@ -2066,11 +2070,9 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) | |||
2066 | if (!ext4_handle_valid(handle)) | 2070 | if (!ext4_handle_valid(handle)) |
2067 | return 0; | 2071 | return 0; |
2068 | 2072 | ||
2069 | lock_super(inode->i_sb); | 2073 | mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); |
2070 | if (list_empty(&ei->i_orphan)) { | 2074 | if (list_empty(&ei->i_orphan)) |
2071 | unlock_super(inode->i_sb); | 2075 | goto out; |
2072 | return 0; | ||
2073 | } | ||
2074 | 2076 | ||
2075 | ino_next = NEXT_ORPHAN(inode); | 2077 | ino_next = NEXT_ORPHAN(inode); |
2076 | prev = ei->i_orphan.prev; | 2078 | prev = ei->i_orphan.prev; |
@@ -2120,7 +2122,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) | |||
2120 | out_err: | 2122 | out_err: |
2121 | ext4_std_error(inode->i_sb, err); | 2123 | ext4_std_error(inode->i_sb, err); |
2122 | out: | 2124 | out: |
2123 | unlock_super(inode->i_sb); | 2125 | mutex_unlock(&EXT4_SB(inode->i_sb)->s_orphan_lock); |
2124 | return err; | 2126 | return err; |
2125 | 2127 | ||
2126 | out_brelse: | 2128 | out_brelse: |
@@ -2533,6 +2535,7 @@ const struct inode_operations ext4_dir_inode_operations = { | |||
2533 | .removexattr = generic_removexattr, | 2535 | .removexattr = generic_removexattr, |
2534 | #endif | 2536 | #endif |
2535 | .permission = ext4_permission, | 2537 | .permission = ext4_permission, |
2538 | .fiemap = ext4_fiemap, | ||
2536 | }; | 2539 | }; |
2537 | 2540 | ||
2538 | const struct inode_operations ext4_special_inode_operations = { | 2541 | const struct inode_operations ext4_special_inode_operations = { |