/* *Ifmeta_bdevisnon-NULL,itmeansthataseparatedeviceis *beingusedtostorethemetadata(superblock/bitmap)which *wouldotherwisebecontainedonthesamedeviceasthedata(bdev).
*/ struct block_device *meta_bdev; struct block_device *bdev; /* block device handle */ struct file *bdev_file; /* Handle from open for bdev */
struct page *sb_page, *bb_page; int sb_loaded;
__u64 sb_events;
sector_t data_offset; /* start of data in array */
sector_t new_data_offset;/* only relevant while reshaping */
sector_t sb_start; /* offset of the super block (in 512byte sectors) */ int sb_size; /* bytes in the superblock */ int preferred_minor; /* autorun support */
struct kobject kobj;
/* A device can be in one of three states based on two flags: *Notworking:faulty==1in_sync==0 *Fullyworking:faulty==0in_sync==1 *Working,butnot *insyncwitharray *faulty==0in_sync==0 * *Itcanneverhavefaulty==1,in_sync==1 *Thisreducestheburdenoftestingmultipleflagsinmanycases
*/
unsignedlong flags; /* bit set of 'enum flag_bits' bits. */
wait_queue_head_t blocked_wait;
int desc_nr; /* descriptor index in the superblock */ int raid_disk; /* role of device in array */ int new_raid_disk; /* role that the device will have in *thearrayafteralevel-changecompletes.
*/ int saved_raid_disk; /* role that device used to have in the *arrayandcouldagainifwedidapartial *resyncfromthebitmap
*/ union {
sector_t recovery_offset;/* If this device has been partially *recovered,thisiswherewewere *upto.
*/
sector_t journal_tail; /* If this device is a journal device, *thisisthejournaltail(journal *recoverystartpoint)
*/
};
atomic_t nr_pending; /* number of pending requests. *onlymaintainedforarraysthat *supporthotremoval
*/
atomic_t read_errors; /* number of consecutive read errors that *wehavetriedtoignore.
*/
time64_t last_read_error; /* monotonic time since our *lastreaderror
*/
atomic_t corrected_errors; /* number of corrected read errors, *forreportingtouserspaceandstoring *insuperblock.
*/
struct serial_in_rdev *serial; /* used for raid1 io serialization */
struct { short offset; /* Offset from superblock to start of PPL.
* Not used by external metadata. */ unsignedint size; /* Size in sectors of the PPL space */
sector_t sector; /* First sector of the PPL space */
} ppl;
}; enum flag_bits {
Faulty, /* device is known to have a fault */
In_sync, /* device is in_sync with rest of array */
Bitmap_sync, /* ..actually, not quite In_sync. Need a *bitmap-basedrecoverytogetfullyinsync. *Thebitisonlymeaningfulbeforedevice *hasbeenpassedtopers->hot_add_disk.
*/
WriteMostly, /* Avoid reading if at all possible */
AutoDetected, /* added by auto-detect */
Blocked, /* An error occurred but has not yet *beenacknowledgedbythemetadata *handler,sodon'tallowwrites
* until it is cleared */
WriteErrorSeen, /* A write error has been seen on this *device
*/
FaultRecorded, /* Intermediate state for clearing *Blocked.TheFaultis/will-be *recordedinthemetadata,butthat *metadatahasn'tbeenstoredsafely *ondiskyet.
*/
BlockedBadBlocks, /* A writer is blocked because they *foundanunacknowledgedbad-block. *Thiscansafelybeclearedatany *time,andthewriterwillre-check. *Itmaybesetatanytime,andat *worstthewriterwilltimeoutand *re-check.Sosettingitas *accuratelyaspossibleisgood,but *notabsolutelycritical.
*/
WantReplacement, /* This device is a candidate to be *hot-replaced,eitherbecauseithas *reportedsomefaults,orbecause *ofexplicitrequest.
*/
Replacement, /* This device is a replacement for *awant_replacementdevicewithsame *raid_disknumber.
*/
Candidate, /* For clustered environments only: *Thisdeviceisseenlocallybutnot *bythewholecluster
*/
Journal, /* This device is used as journal for *raid-5/6. *Usually,thisdeviceshouldbefaster *thanotherdevicesinthearray
*/
ClusterRemove,
ExternalBbl, /* External metadata provides bad *blockmanagementforadisk
*/
FailFast, /* Minimal retries should be attempted on *thisdevice,souseREQ_FAILFAST_DEV. *Alsodon'ttrytorepairfailedreads. *Itisexpectsthatnobadblocklog *ispresent.
*/
LastDev, /* Seems to be the last working dev as *itdidn'tfail,sodon'tuseFailFast *anymoreformetadata
*/
CollisionCheck, /* *checkifthereiscollisionbetweenraid1 *serialbios.
*/
Nonrot, /* non-rotational device (SSD) */
};
enum mddev_sb_flags {
MD_SB_CHANGE_DEVS, /* Some device status has changed */
MD_SB_CHANGE_CLEAN, /* transition to or from 'clean' */
MD_SB_CHANGE_PENDING, /* switch from 'clean' to 'active' in progress */
MD_SB_NEED_REWRITE, /* metadata write needs to be repeated */
};
#define NR_SERIAL_INFOS 8 /* record current range of serialize IOs */ struct serial_info { struct rb_node node;
sector_t start; /* start sector of rb node */
sector_t last; /* end sector of rb node */
sector_t _subtree_last; /* highest sector in subtree of rb node */
};
/* *mddev->curr_resyncstoresthecurrentsectoroftheresyncbut *alsohassomeoverloadedvalues.
*/ enum { /* No resync in progress */
MD_RESYNC_NONE = 0, /* Yielded to allow another conflicting resync to commence */
MD_RESYNC_YIELDED = 1, /* Delayed to check that there is no conflict with another sync */
MD_RESYNC_DELAYED = 2, /* Any value greater than or equal to this is in an active resync */
MD_RESYNC_ACTIVE = 3,
};
/* Superblock information */ int major_version,
minor_version,
patch_version; int persistent; int external; /* metadata is
* managed externally */ char metadata_type[17]; /* externally set*/ int chunk_sectors;
time64_t ctime, utime; int level, layout; char clevel[16]; int raid_disks; int max_disks;
sector_t dev_sectors; /* used size of
* component devices */
sector_t array_sectors; /* exported array size */ int external_size; /* size managed
* externally */
__u64 events; /* If the last 'event' was simply a clean->dirty transition, and *wedidn'twriteittothespares,thenitissafeandsimple *tojustdecrementtheeventcountonadirty->cleantransition. *Sowerecordthatpossibilityhere.
*/ int can_decrease_events;
char uuid[16];
/* If the array is being reshaped, we need to record the *newshapeandanindicationofwhereweareupto. *Thisiswrittentothesuperblock. *Ifreshape_positionisMaxSector,thennoreshapeishappening(yet).
*/
sector_t reshape_position; int delta_disks, new_level, new_layout; int new_chunk_sectors; int reshape_backwards;
/* *Setwhenasyncoperationisstarted.Itholdsthisvalueeven *whenthesyncthreadis"frozen"(interrupted)or"idle"(stopped *orfinished).Itisoverwrittenwhenanewsyncoperationisbegun.
*/ enum sync_action last_sync_action;
sector_t curr_resync; /* last block scheduled */ /* As resync requests can complete out of order, we cannot easily track *howmuchresynchasbeencompleted.Soweoccasionallypauseuntil *everythingcompletes,thensetcurr_resync_completedtocurr_resync. *Assuchitmaybewellbehindtherealresyncmark,butitisavalue *wearecertainof.
*/
sector_t curr_resync_completed; unsignedlong resync_mark; /* a recent timestamp */
sector_t resync_mark_cnt;/* blocks written at resync_mark */
sector_t curr_mark_cnt; /* blocks scheduled now */
sector_t resync_max_sectors; /* may be set by personality */
atomic64_t resync_mismatches; /* count of sectors where *parity/replicamismatchfound
*/
/* allow user-space to request suspension of IO to regions of the array */
sector_t suspend_lo;
sector_t suspend_hi; /* if zero, use the system-wide default */ int sync_speed_min; int sync_speed_max; int sync_io_depth;
/* resync even though the same disks are shared among md-devices */ int parallel_resync;
int ok_start_degraded;
unsignedlong recovery; /* If a RAID personality determines that recovery (of a particular *device)willfailduetoareaderroronthesourcedevice,it *takesacopyofthisnumberanddoesnotattemptrecoveryagain *untilthisnumberchanges.
*/ int recovery_disabled;
int in_sync; /* know to not need resync */ /* 'open_mutex' avoids races between 'md_open' and 'do_md_stop', so *thatweareneverstoppinganarraywhileitisopen. *'reconfig_mutex'protectsallotherreconfiguration. *Theselocksareseparateduetoconflictinginteractions *withdisk->open_mutex. *Lockorderingis: *reconfig_mutex->disk->open_mutex *disk->open_mutex->open_mutex:e.g.__blkdev_get->md_open
*/ struct mutex open_mutex; struct mutex reconfig_mutex;
atomic_t active; /* general refcount */
atomic_t openers; /* number of active opens */
int changed; /* True if we might need to
* reread partition info */ int degraded; /* whether md should consider *addingaspare
*/
unsignedlong normal_io_events; /* IO event timestamp */
atomic_t recovery_active; /* blocks scheduled, but not written */
wait_queue_head_t recovery_wait;
sector_t resync_offset;
sector_t resync_min; /* user requested sync
* starts here */
sector_t resync_max; /* resync should pause
* when it gets here */
struct kernfs_node *sysfs_state; /* handle for 'array_state' *fileinsysfs.
*/ struct kernfs_node *sysfs_action; /* handle for 'sync_action' */ struct kernfs_node *sysfs_completed; /*handle for 'sync_completed' */ struct kernfs_node *sysfs_degraded; /*handle for 'degraded' */ struct kernfs_node *sysfs_level; /*handle for 'level' */
/* used for delayed sysfs removal */ struct work_struct del_work; /* used for register new sync thread */ struct work_struct sync_work;
/* "lock" protects: *flush_biotransitionfromNULLto!NULL *rdevsuperblocks,events *clearingMD_CHANGE_* *in_sync-andrelatedsafemodeandMD_CHANGEchanges *pers(alsoprotectedbyreconfig_mutexandpendingIO). *clearing->bitmap *clearing->bitmap_info.file *changing->resync_{min,max} *settingMD_RECOVERY_RUNNING(whichinteractswithresync_{min,max})
*/
spinlock_t lock;
wait_queue_head_t sb_wait; /* for waiting on superblock updates */
atomic_t pending_writes; /* number of active superblock writes */
unsignedint safemode; /* if set, update "clean" superblock *whennowritespending.
*/ unsignedint safemode_delay; struct timer_list safemode_timer; struct percpu_ref writes_pending; int sync_checkers; /* # of threads checking writes_pending */
void *bitmap; /* the bitmap for the device */ struct bitmap_operations *bitmap_ops; struct { struct file *file; /* the bitmap file */
loff_t offset; /* offset from superblock of *startofbitmap.Maybe *negative,butnot'0' *Forexternalmetadata,offset *fromstartofdevice.
*/ unsignedlong space; /* space available at this offset */
loff_t default_offset; /* this is the offset to use when *hot-addingabitmap.Itshould *eventuallybesettablebysysfs.
*/ unsignedlong default_space; /* space available at
* default offset */ struct mutex mutex; unsignedlong chunksize; unsignedlong daemon_sleep; /* how many jiffies between updates? */ unsignedlong max_write_behind; /* write-behind mode */ int external; int nodes; /* Maximum number of nodes in the cluster */ char cluster_name[64]; /* Name of the cluster */
} bitmap_info;
atomic_t max_corr_read_errors; /* max read retries */ struct list_head all_mddevs;
conststruct attribute_group *to_remove;
struct bio_set bio_set; struct bio_set sync_set; /* for sync operations like *metadataandbitmapwrites
*/ struct bio_set io_clone_set;
struct work_struct event_work; /* used by dm to report failure event */
mempool_t *serial_info_pool; void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); struct md_cluster_info *cluster_info; struct md_cluster_operations *cluster_ops; unsignedint good_device_nr; /* good device num within cluster raid */ unsignedint noio_flag; /* for memalloc scope API */
enum recovery_flags { /* flags for sync thread running status */
/* *setwhenoneofsyncactionissetandnewsyncthreadneedtobe *registered,orjustadd/removesparesfromconf.
*/
MD_RECOVERY_NEEDED, /* sync thread is running, or about to be started */
MD_RECOVERY_RUNNING, /* sync thread needs to be aborted for some reason */
MD_RECOVERY_INTR, /* sync thread is done and is waiting to be unregistered */
MD_RECOVERY_DONE, /* running sync thread must abort immediately, and not restart */
MD_RECOVERY_FROZEN, /* waiting for pers->start() to finish */
MD_RECOVERY_WAIT, /* interrupted because io-error */
MD_RECOVERY_ERROR,
/* flags determines sync action, see details in enum sync_action */
/* if just this flag is set, action is resync. */
MD_RECOVERY_SYNC, /* *pairedwithMD_RECOVERY_SYNC,ifMD_RECOVERY_CHECKisnotset, *actionisrepair,meansuserrequestedresync.
*/
MD_RECOVERY_REQUESTED, /* *pairedwithMD_RECOVERY_SYNCandMD_RECOVERY_REQUESTED,actionis *check.
*/
MD_RECOVERY_CHECK, /* recovery, or need to try it */
MD_RECOVERY_RECOVER, /* reshape */
MD_RECOVERY_RESHAPE, /* remote node is running resync thread */
MD_RESYNCING_REMOTE,
};
staticinlinebool reshape_interrupted(struct mddev *mddev)
{ /* reshape never start */ if (mddev->reshape_position == MaxSector) returnfalse;
/* interrupted */ if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) returntrue;
/* running reshape will be interrupted soon. */ if (test_bit(MD_RECOVERY_WAIT, &mddev->recovery) ||
test_bit(MD_RECOVERY_INTR, &mddev->recovery) ||
test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) returntrue;
returnfalse;
}
staticinlineint __must_check mddev_lock(struct mddev *mddev)
{ int ret;
ret = mutex_lock_interruptible(&mddev->reconfig_mutex);
/* MD_DELETED is set in do_md_stop with reconfig_mutex. *Socheckithere.
*/ if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
ret = -ENODEV;
mutex_unlock(&mddev->reconfig_mutex);
}
return ret;
}
/* Sometimes we need to take the lock in a situation where *failureduetointerruptsisnotacceptable. *Itdoesn'tneedtocheckMD_DELETEDhere,theownerwhich *holdsthelockherecan'tbestopped.Andallpathscan't *callthisfunctionafterdo_md_stop.
*/ staticinlinevoid mddev_lock_nointr(struct mddev *mddev)
{
mutex_lock(&mddev->reconfig_mutex);
}
staticinlineint mddev_trylock(struct mddev *mddev)
{ int ret;
ret = mutex_trylock(&mddev->reconfig_mutex); if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
ret = -ENODEV;
mutex_unlock(&mddev->reconfig_mutex);
} return ret;
} externvoid mddev_unlock(struct mddev *mddev);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.