Index: linux-2.6.38/fs/reiser4/plugin/space/bitmap.c =================================================================== --- linux-2.6.38.orig/fs/reiser4/plugin/space/bitmap.c +++ linux-2.6.38/fs/reiser4/plugin/space/bitmap.c @@ -830,45 +830,43 @@ static int load_and_lock_bnode(struct bi } ret = prepare_bnode(bnode, &cjnode, &wjnode); - if (ret == 0) { - mutex_lock(&bnode->mutex); + if (ret) + return ret; - if (!atomic_read(&bnode->loaded)) { - assert("nikita-2822", cjnode != NULL); - assert("nikita-2823", wjnode != NULL); - assert("nikita-2824", jnode_is_loaded(cjnode)); - assert("nikita-2825", jnode_is_loaded(wjnode)); - - bnode->wjnode = wjnode; - bnode->cjnode = cjnode; - - ret = check_struct_bnode(bnode, current_blocksize); - if (!ret) { - cjnode = wjnode = NULL; - atomic_set(&bnode->loaded, 1); - /* working bitmap is initialized by on-disk - * commit bitmap. This should be performed - * under mutex. */ - memcpy(bnode_working_data(bnode), - bnode_commit_data(bnode), - bmap_size(current_blocksize)); - } else - mutex_unlock(&bnode->mutex); - } else - /* race: someone already loaded bitmap while we were - * busy initializing data. */ - check_bnode_loaded(bnode); - } - - if (wjnode != NULL) { - release(wjnode); - bnode->wjnode = NULL; - } - if (cjnode != NULL) { - release(cjnode); - bnode->cjnode = NULL; - } + mutex_lock(&bnode->mutex); + if (!atomic_read(&bnode->loaded)) { + assert("nikita-2822", cjnode != NULL); + assert("nikita-2823", wjnode != NULL); + assert("nikita-2824", jnode_is_loaded(cjnode)); + assert("nikita-2825", jnode_is_loaded(wjnode)); + + bnode->wjnode = wjnode; + bnode->cjnode = cjnode; + + ret = check_struct_bnode(bnode, current_blocksize); + if (unlikely(ret != 0)) + goto error; + + atomic_set(&bnode->loaded, 1); + /* working bitmap is initialized by on-disk + * commit bitmap. This should be performed + * under mutex. */ + memcpy(bnode_working_data(bnode), + bnode_commit_data(bnode), + bmap_size(current_blocksize)); + } else + /* race: someone already loaded bitmap + * while we were busy initializing data. */ + check_bnode_loaded(bnode); + return 0; + + error: + release(wjnode); + release(cjnode); + bnode->wjnode = NULL; + bnode->cjnode = NULL; + mutex_unlock(&bnode->mutex); return ret; }