The previous section describes the synchronization functions in RAID5 sync_request potato chips are made by handle_stripe. From the initial creation of the array, to the application of various resources, to build the personality of each array, everything is prepared to meet the data flow. It's like we're cramming for college. The process of data flow is as rich and challenging as a college campus, but as long as it crosses the line, the kernel code will no longer be mysterious, and the rest of the problem is only time.
First look at where handle_stripe is taking our potato chips:
3379 static void Handle_stripe (struct stripe_head *sh) 3380 {3381 struct S;
3382 struct r5conf *conf = sh->raid_conf;
3383 int i;
3384 int prexor;
3385 int disks = sh->disks;
3386 struct R5dev *pdev, *qdev;
3387 3388 clear_bit (Stripe_handle, &sh->state); 3389 if (Test_and_set_bit_lock (stripe_active, &sh->state)) {3390/* already being handle D, ensure it gets handled 3391 * again when the current action finishes/3392 Set_bit (stri
Pe_handle, &sh->state);
3393 return; 3394} 3395 3396 if (Test_and_clear_bit (stripe_sync_requested, &sh->state)) {3397
Set_bit (stripe_syncing, &sh->state);
3398 clear_bit (Stripe_insync, &sh->state);
3399} 3400 Clear_bit (stripe_delayed, &sh->state); 3401 3402 pr_debug ("Handling stripe%llu, state=% #lx cnt=%d," 3403 "pd_idx=%d, qd_idx=%d\n, check: %d, reconstruct:%d\n ", 3404 (unsigned long Long) sh->sector, Sh->state, 3405 Atomic _read (&sh->count), Sh->pd_idx, Sh->qd_idx, 3406 sh->check_state, sh->reconstruct_state
); 3407 3408 analyse_stripe (SH, &s);
This function code is longer than the first section, analysis strip. The role of analysis is based on the state of the strip to do some preprocessing, according to these states again to determine what the next step should be specific operations. For example, synchronization, then first read the data disk, and so on read back, then verify, and then write the checksum value. But these steps are not done in a one-time handle_stripe, because with disk IO is asynchronous, so it is necessary to wait for the last disk request callback after the call Handle_stripe, usually each data flow will be entered handle_stripe multiple times, And every time you go through the code flow is not the same.
struct Stripe_head has a lot of States, these states determine how the stripe should be handled, so must be very careful to deal with these signs, these signs are many, now first simple.
enum {
stripe_active,// processing
stripe_handle,//need to process
stripe_sync_requested, //sync request
Stripe_syncing,// processing sync
stripe_insync,// stripe synchronized
stripe_preread_active, //Pre-read
stripe _delayed,// deferred processing
stripe_degraded,// degraded
stripe_bit_delay,// waiting for bitmap processing
stripe_ Expanding, //
Stripe_expand_source, //
Stripe_expand_ready, //
stripe_io_started , /* does not count towards ' bypass_count ' //IO has been issued
stripe_full_write,/ * All blocks are set to be ov Erwritten//// Full write
stripe_biofill_run, //bio fill, is to copy page page to Bio
Stripe_compute_run, // Run calculation
stripe_ops_req_pending,// handle_stripe queue with
stripe_on_unplug_list, //Bulk Release_ Stripe when the identity is added to the Unplug linked list
};
3388 lines, clear the need to process the flag.
3389 lines, the setting is processing the flag.
3392 lines, if you are already working, set the next processing flag and return.
3396 lines, if synchronization is requested.
3397 lines, settings are processing sync flags.
3398 lines, clear the synchronized flag.
3400 lines, clear the delay processing flag.
3408 lines, analysis stripe, this function is very long divided into several paragraphs to illustrate: