+ struct dx_entry *entries,
+ struct dx_entry *at, u32 hash)
+{
-+ if (!(ext4_htree_lock_data(lck)->ld_flags & EXT4_LB_EXACT)) {
++ if (!(lck && ext4_htree_lock_data(lck)->ld_flags & EXT4_LB_EXACT)) {
+ return DX_HASH_COL_IGNORE; /* don't care about collision */
+
+ } else if (at == entries + dx_get_count(entries) - 1) {
unsigned count, indirect;
- struct dx_entry *at, *entries, *p, *q, *m;
+ struct dx_entry *at, *entries, *p, *q, *m, *dx = NULL;
- struct dx_root_info * info;
+ struct dx_root_info *info;
struct buffer_head *bh;
struct dx_frame *frame = frame_in;
@@ -750,8 +980,15 @@ dx_probe(const struct qstr *d_name, stru
dx_get_limit((frame - 1)->entries)) {
@@ -2277,16 +2622,43 @@ again:
restart = 1;
- goto cleanup;
+ goto journal_error;
}
+ } else if (!ext4_htree_dx_locked(lck)) {
+ struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck);
goto cleanup;
journal_error:
- ext4_std_error(dir->i_sb, err);
+ ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */
cleanup:
+ ext4_htree_dx_unlock(lck);
+ ext4_htree_de_unlock(lck);