- do_corr(schedule());
- BUFFER_TRACE(frame->bh, "get_write_access");
- err = ldiskfs_journal_get_write_access(handle, frame->bh);
- if (err)
- goto journal_error;
- }
- /* Add "safe" node to transaction too */
- if (safe + 1 != path->ip_frames) {
- do_corr(schedule());
- err = ldiskfs_journal_get_write_access(handle, safe->bh);
- if (err)
- goto journal_error;
- }
-
- /* Go through nodes once more, inserting pointers */
- for (frame = safe + 1, i = 0; i < nr_splet; ++i, ++frame) {
- unsigned count;
- int idx;
- struct buffer_head *bh2;
- struct buffer_head *bh;
-
- entries = frame->entries;
- count = dx_get_count(entries);
- idx = iam_entry_diff(path, frame->at, entries);
-
- bh2 = bh_new[i];
- entries2 = dx_get_entries(path, bh2->b_data, 0);
-
- bh = frame->bh;
- if (frame == path->ip_frames) {
- /* splitting root node. Tricky point:
- *
- * In the "normal" B-tree we'd split root *and* add
- * new root to the tree with pointers to the old root
- * and its sibling (thus introducing two new nodes).
- *
- * In htree it's enough to add one node, because
- * capacity of the root node is smaller than that of
- * non-root one.
- */
- struct iam_frame *frames;
- struct iam_entry *next;
-
- assert_corr(i == 0);
-
- do_corr(schedule());
-
- frames = path->ip_frames;
- memcpy((char *) entries2, (char *) entries,
- count * iam_entry_size(path));
- dx_set_limit(entries2, dx_node_limit(path));
-
- /* Set up root */
- iam_lock_bh(frame->bh);
- next = descr->id_ops->id_root_inc(path->ip_container,
- path, frame);
- dx_set_block(path, next, newblock[0]);
- iam_unlock_bh(frame->bh);
-
- do_corr(schedule());
- /* Shift frames in the path */
- memmove(frames + 2, frames + 1,
- (sizeof path->ip_frames) - 2 * sizeof frames[0]);
- /* Add new access path frame */
- frames[1].at = iam_entry_shift(path, entries2, idx);
- frames[1].entries = entries = entries2;
- frames[1].bh = bh2;
- assert_inv(dx_node_check(path, frame));
- ++ path->ip_frame;
- ++ frame;
- assert_inv(dx_node_check(path, frame));
- bh_new[0] = NULL; /* buffer head is "consumed" */
- err = ldiskfs_journal_dirty_metadata(handle, bh2);
- if (err)
- goto journal_error;
- do_corr(schedule());
- } else {
- /* splitting non-root index node. */
- struct iam_frame *parent = frame - 1;
-
- do_corr(schedule());
- count = iam_shift_entries(path, frame, count,
- entries, entries2, newblock[i]);
- /* Which index block gets the new entry? */
- if (idx >= count) {
- int d = dx_index_is_compat(path) ? 0 : +1;
-
- frame->at = iam_entry_shift(path, entries2,
- idx - count + d);
- frame->entries = entries = entries2;
- frame->curidx = newblock[i];
- swap(frame->bh, bh2);
- assert_corr(lock[i + 1] != NULL);
- assert_corr(new_lock[i] != NULL);
- swap(lock[i + 1], new_lock[i]);
- bh_new[i] = bh2;
- parent->at = iam_entry_shift(path,
- parent->at, +1);
- }
- assert_inv(dx_node_check(path, frame));
- assert_inv(dx_node_check(path, parent));
- dxtrace(dx_show_index ("node", frame->entries));
- dxtrace(dx_show_index ("node",
- ((struct dx_node *) bh2->b_data)->entries));
- err = ldiskfs_journal_dirty_metadata(handle, bh2);
- if (err)
- goto journal_error;
- do_corr(schedule());
- err = ldiskfs_journal_dirty_metadata(handle, parent->bh);
- if (err)
- goto journal_error;
- }
- do_corr(schedule());
- err = ldiskfs_journal_dirty_metadata(handle, bh);
- if (err)
- goto journal_error;
- }
- /*
- * This function was called to make insertion of new leaf
- * possible. Check that it fulfilled its obligations.
- */
- assert_corr(dx_get_count(path->ip_frame->entries) <
- dx_get_limit(path->ip_frame->entries));
- assert_corr(lock[nr_splet] != NULL);
- *lh = lock[nr_splet];
- lock[nr_splet] = NULL;
- if (nr_splet > 0) {
- /*
- * Log ->i_size modification.
- */
- err = ldiskfs_mark_inode_dirty(handle, dir);
- if (err)
- goto journal_error;
- }
- goto cleanup;
+ do_corr(schedule());
+ BUFFER_TRACE(frame->bh, "get_write_access");
+ err = ldiskfs_journal_get_write_access(handle, frame->bh);
+ if (err)
+ goto journal_error;
+ }
+ /* Add "safe" node to transaction too */
+ if (safe + 1 != path->ip_frames) {
+ do_corr(schedule());
+ err = ldiskfs_journal_get_write_access(handle, safe->bh);
+ if (err)
+ goto journal_error;
+ }
+
+ /* Go through nodes once more, inserting pointers */
+ for (frame = safe + 1, i = 0; i < nr_splet; ++i, ++frame) {
+ unsigned count;
+ int idx;
+ struct buffer_head *bh2;
+ struct buffer_head *bh;
+
+ entries = frame->entries;
+ count = dx_get_count(entries);
+ idx = iam_entry_diff(path, frame->at, entries);
+
+ bh2 = bh_new[i];
+ entries2 = dx_get_entries(path, bh2->b_data, 0);
+
+ bh = frame->bh;
+ if (frame == path->ip_frames) {
+ /* splitting root node. Tricky point:
+ *
+ * In the "normal" B-tree we'd split root *and* add
+ * new root to the tree with pointers to the old root
+ * and its sibling (thus introducing two new nodes).
+ *
+ * In htree it's enough to add one node, because
+ * capacity of the root node is smaller than that of
+ * non-root one.
+ */
+ struct iam_frame *frames;
+ struct iam_entry *next;
+
+ assert_corr(i == 0);
+
+ do_corr(schedule());
+
+ frames = path->ip_frames;
+ memcpy((char *) entries2, (char *) entries,
+ count * iam_entry_size(path));
+ dx_set_limit(entries2, dx_node_limit(path));
+
+ /* Set up root */
+ iam_lock_bh(frame->bh);
+ next = descr->id_ops->id_root_inc(path->ip_container,
+ path, frame);
+ dx_set_block(path, next, newblock[0]);
+ iam_unlock_bh(frame->bh);
+
+ do_corr(schedule());
+ /* Shift frames in the path */
+ memmove(frames + 2, frames + 1,
+ (sizeof path->ip_frames) - 2 * sizeof frames[0]);
+ /* Add new access path frame */
+ frames[1].at = iam_entry_shift(path, entries2, idx);
+ frames[1].entries = entries = entries2;
+ frames[1].bh = bh2;
+ assert_inv(dx_node_check(path, frame));
+ ++ path->ip_frame;
+ ++ frame;
+ assert_inv(dx_node_check(path, frame));
+ bh_new[0] = NULL; /* buffer head is "consumed" */
+ err = ldiskfs_handle_dirty_metadata(handle, NULL, bh2);
+ if (err)
+ goto journal_error;
+ do_corr(schedule());
+ } else {
+ /* splitting non-root index node. */
+ struct iam_frame *parent = frame - 1;
+
+ do_corr(schedule());
+ count = iam_shift_entries(path, frame, count,
+ entries, entries2, newblock[i]);
+ /* Which index block gets the new entry? */
+ if (idx >= count) {
+ int d = dx_index_is_compat(path) ? 0 : +1;
+
+ frame->at = iam_entry_shift(path, entries2,
+ idx - count + d);
+ frame->entries = entries = entries2;
+ frame->curidx = newblock[i];
+ swap(frame->bh, bh2);
+ assert_corr(lock[i + 1] != NULL);
+ assert_corr(new_lock[i] != NULL);
+ swap(lock[i + 1], new_lock[i]);
+ bh_new[i] = bh2;
+ parent->at = iam_entry_shift(path,
+ parent->at, +1);
+ }
+ assert_inv(dx_node_check(path, frame));
+ assert_inv(dx_node_check(path, parent));
+ dxtrace(dx_show_index("node", frame->entries));
+ dxtrace(dx_show_index("node",
+ ((struct dx_node *) bh2->b_data)->entries));
+ err = ldiskfs_handle_dirty_metadata(handle, NULL, bh2);
+ if (err)
+ goto journal_error;
+ do_corr(schedule());
+ err = ldiskfs_handle_dirty_metadata(handle, NULL,
+ parent->bh);
+ if (err)
+ goto journal_error;
+ }
+ do_corr(schedule());
+ err = ldiskfs_handle_dirty_metadata(handle, NULL, bh);
+ if (err)
+ goto journal_error;
+ }
+ /*
+ * This function was called to make insertion of new leaf
+ * possible. Check that it fulfilled its obligations.
+ */
+ assert_corr(dx_get_count(path->ip_frame->entries) <
+ dx_get_limit(path->ip_frame->entries));
+ assert_corr(lock[nr_splet] != NULL);
+ *lh = lock[nr_splet];
+ lock[nr_splet] = NULL;
+ if (nr_splet > 0) {
+ /*
+ * Log ->i_size modification.
+ */
+ err = ldiskfs_mark_inode_dirty(handle, dir);
+ if (err)
+ goto journal_error;
+ }
+ goto cleanup;