e schityvaniya kazhdogo bloka yadro umen'shaet razmer kanala v sootvetstvii s koli- chestvom schitannyh dannyh i ustanavlivaet znachenie smeshcheniya v prostranstve processa tak, chtoby pri dostizhenii konca kanala ono ukazyvalo na ego nachalo. Kogda vypolnenie sistemnoj funkcii read zavershaetsya, yadro vozobnovlyaet vy- polnenie vseh priostanovlennyh processov zapisi i zapominaet tekushchee znache- nie ukazatelya chteniya v indekse (a ne v zapisi tablicy fajlov). Esli process pytaetsya schitat' bol'she informacii, chem fakticheski est' v kanale, funkciya read zavershitsya uspeshno, vozvrativ vse dannye, nahodyashchiesya v dannyj moment v kanale, pust' dazhe ne polnost'yu vypolniv zapros pol'zovate- lya. Esli kanal pust, process obychno priostanavlivaetsya do teh por, poka ka- koj-nibud' drugoj process ne zapishet dannye v kanal, posle chego vse priosta- novlennye processy, ozhidayushchie vvoda dannyh, vozobnovyat svoe vypolnenie i nachnut konkurirovat' za chtenie iz kanala. Esli, odnako, process otkryvaet poimenovannyj kanal s parametrom "no delay" (bez zaderzhki), funkciya read vozvratit upravlenie nemedlenno, esli v kanale otsutstvuyut dannye. Operacii chteniya i zapisi v kanal imeyut tu zhe semantiku, chto i analogichnye operacii dlya terminal'nyh ustrojstv (glava 10), ona pozvolyaet processam ignorirovat' tip teh fajlov, s kotorymi eti programmy imeyut delo. Esli process vedet zapis' v kanal i v kanale net mesta dlya vseh dannyh, yadro pomechaet indeks i priostanavlivaet vypolnenie processa do teh por, poka kanal ne nachnet ochishchat'sya ot dannyh. Kogda vposledstvii drugoj process budet schityvat' dannye iz kanala, yadro zametit sushchestvovanie processov, priosta- novlennyh v ozhidanii ochistki kanala, i vozobnovit ih vypolnenie podobno to- mu, kak eto bylo ob®yasneno vyshe. Isklyucheniem iz etogo utverzhdeniya yavlyaetsya 107 situaciya, kogda process zapisyvaet v kanal dannye, ob®em kotoryh prevyshaet emkost' kanala (to est', ob®em dannyh, kotorye mogut hranit'sya v blokah prya- moj adresacii); v etom sluchae yadro zapisyvaet v kanal stol'ko dannyh, skol'- ko on mozhet vmestit' v sebya, i priostanavlivaet process do teh por, poka ne osvoboditsya dopolnitel'noe mesto. Takim obrazom, vozmozhno polozhenie, pri ko- torom zapisyvaemye dannye ne budut zanimat' nepreryvnoe mesto v kanale, esli drugie processy vedut zapis' v kanal v to vremya, na kotoroe pervyj process prerval svoyu rabotu. Analiziruya realizaciyu kanalov, mozhno zametit', chto interfejs processov soglasuetsya s interfejsom obychnyh fajlov, no ego voploshchenie otlichaetsya, tak kak yadro zapominaet smeshcheniya dlya chteniya i zapisi v indekse vmesto togo, chto- by delat' eto v tablice fajlov. YAdro vynuzhdeno hranit' znacheniya smeshchenij dlya poimenovannyh kanalov v indekse dlya togo, chtoby processy mogli sovmestno is- pol'zovat' eti znacheniya: oni ne mogli by sovmestno ispol'zovat' znacheniya, hranyashchiesya v tablice fajlov, tak kak process poluchaet novuyu zapis' v tablice fajlov po kazhdomu vyzovu funkcii open. Tem ne menee, sovmestnoe ispol'zova- nie smeshchenij chteniya i zapisi v indekse nablyudalos' i do realizacii poimeno- vannyh kanalov. Processy, obrashchayushchiesya k nepoimenovannym kanalam, razdelyayut dostup k kanalu cherez obshchie tochki vhoda v tablicu fajlov, poetomu oni mogli by po umolchaniyu hranit' smeshcheniya zapisi i chteniya v tablice fajlov, kak eto prinyato dlya obychnyh fajlov. |to ne bylo sdelano, tak kak procedury nizkogo urovnya, rabotayushchie v yadre, bol'she ne imeyut dostupa k zapisyam v tablice faj- lov: programma uprostilas' za schet togo, chto processy sovmestno ispol'zuyut znacheniya smeshchenij, hranyashchiesya v indekse. .te1 5.12.4 Zakrytie kanalov Pri zakrytii kanala process vypolnyaet tu zhe samuyu proceduru, chto i pri zakrytii obychnogo fajla, za isklyucheniem togo, chto yadro, prezhde chem osvobo- dit' indeks kanala, vypolnyaet special'nuyu obrabotku. Ono umen'shaet kolichest- vo processov chteniya iz kanala ili zapisi v kanal v zavisimosti ot tipa faj- lovogo deskriptora. Esli znachenie schetchika chisla zapisyvayushchih v kanal pro- cessov stanovitsya ravnym 0 i imeyutsya processy, priostanovlennye v ozhidanii chteniya dannyh iz kanala, yadro vozobnovlyaet vypolnenie poslednih i oni zaver- shayut svoi operacii chteniya bez vozvrata kakih-libo dannyh. Esli stanovitsya ravnym 0 znachenie schetchika chisla schityvayushchih iz kanala processov i imeyutsya processy, priostanovlennye v ozhidanii vozmozhnosti zapisi dannyh v kanal, yad- ro vozobnovlyaet vypolnenie poslednih i posylaet im signal (glava 7) ob oshib- ke. V oboih sluchayah ne imeet smysla prodolzhat' derzhat' processy priostanov- lennymi, esli net nadezhdy na to, chto sostoyanie kanala kogda-nibud' izmenit- sya. Naprimer, esli process ozhidaet vozmozhnosti proizvodit' chtenie iz nepoi- menovannogo kanala i v sisteme bol'she net processov, zapisyvayushchih v etot ka- nal, znachit, zapisyvayushchij process nikogda ne poyavitsya. Nesmotrya na to, chto esli kanal poimenovannyj, v principe vozmozhno poyavlenie novogo schityvayushchego ili zapisyvayushchego processa, yadro traktuet etu situaciyu tochno tak zhe, kak i dlya nepoimenovannyh kanalov. Esli k kanalu ne obrashchaetsya ni odin zapisyvayu- shchij ili schityvayushchij process, yadro osvobozhdaet vse informacionnye bloki kana- la i pereustanavlivaet indeks takim obrazom, chtoby on ukazyval na to, chto kanal pust. Kogda yadro osvobozhdaet indeks obychnogo kanala, ono osvobozhdaet dlya perenaznacheniya i diskovuyu kopiyu etogo indeksa. 5.12.5 Primery Programma na Risunke 5.18 illyustriruet iskusstvennoe ispol'zovanie kana- lov. Process sozdaet kanal i vhodit v beskonechnyj cikl, zapisyvaya v kanal 108 +---------------------------------+ | char string[] = "hello"; | | main() | | { | | char buf[1024]; | | char *cp1,*cp2; | | int fds[2]; | | | | cp1 = string; | | cp2 = buf; | | while(*cp1) | | *cp2++ = *cp1++; | | pipe(fds); | | for (;;) | | { | | write(fds[1],buf,6); | | read(fds[0],buf,6); | | } | | } | +---------------------------------+ Risunok 5.18. CHtenie iz kanala i zapis' v kanal stroku simvolov "hello" i schityvaya ee iz kanala. YAdru ne nuzhno ni znat' o tom, chto process, vedushchij zapis' v kanal, yavlyaetsya i processom, schityvayushchim iz kanala, ni proyavlyat' po etomu povodu kakoe-libo bespokojstvo. Process, vypolnyayushchij programmu, kotoraya privedena na Risunke 5.19, soz- daet poimenovannyj kanal s imenem "fifo". Esli etot process zapushchen s ukaza- niem vtorogo (formal'nogo) argumenta, on pos- +------------------------------------------------------------+ | #include | | char string[] = "hello"; | | main(argc,argv) | | int argc; | | char *argv[]; | | { | | int fd; | | char buf[256]; | | | | /* sozdanie poimenovannogo kanala s razresheniem chteniya i | | zapisi dlya vseh pol'zovatelej */ | | mknod("fifo",010777,0); | | if(argc == 2) | | fd = open("fifo",O_WRONLY); | | else | | fd = open("fifo",O_RDONLY); | | for (;;) | | if(argc == 2) | | write(fd,string,6); | | else | | read(fd,buf,6); | | } | +------------------------------------------------------------+ Risunok 5.19. CHtenie i zapis' v poimenovannyj kanal 109 toyanno zapisyvaet v kanal stroku simvolov "hello"; buduchi zapushchen bez vtoro- go argumenta, on vedet chtenie iz poimenovannogo kanala. Dva processa zapus- kayutsya po odnoj i toj zhe programme, tajno dogovorivshis' vzaimodejstvovat' mezhdu soboj cherez poimenovannyj kanal "fifo", no im net neobhodimosti byt' rodstvennymi processami. Drugie pol'zovateli mogut vypolnyat' programmu i uchastvovat' v dialoge (ili meshat' emu). 5.13 DUR Sistemnaya funkciya dup kopiruet deskriptor fajla v pervoe svobodnoe mesto v tablice pol'zovatel'skih deskriptorov fajla, vozvrashchaya novyj deskriptor pol'zovatelyu. Ona dejstvuet dlya vseh tipov fajla. Sintaksis vyzova funkcii: newfd = dup(fd); gde fd - deskriptor fajla, kopiruemyj funkciej, a newfd - novyj deskriptor, ssylayushchijsya na fajl. Poskol'ku funkciya dup dubliruet deskriptor fajla, ona uvelichivaet znachenie schetchika v sootvetstvuyushchej zapisi tablicy fajlov - za- tablica pol'zova- tel'skih deskrip- torov fajla tablica fajlov tablica indeksov +---------+ +------------+ +--------------+ 0| ----+----+ | | | - | +---------+ | | | | - | 1| ----+---++-->| | | - | +---------+ | +------------+ | - | 2| ----+--++--->| - | | - | +---------+ +---->| - | | - | 3| ----+----+ | - | | - | +---------+ | | - | +--------------+ 4| ----+---+| | - | +---->| schet- | +---------+ || | - | | | chik (/etc/ | 5| ----+--+|| +------------+ | +-->| 2 passwd)| +---------+ ||| | schet- | | | +--------------+ 6| ----++ ||+-->| chik +--+ | | - | +---------++-||--->| 2 | | | - | 7| | || +------------+ | | - | +---------+ || | - | | | - | | - | || +------------+ | | - | +---------+ || | schetchik | | | - | |+--->| 1 +----|+ | - | | +------------+ || | - | | | - | || +--------------+ | | - | || | schet- | | | - | |+->| chik (local)| | | - | | | 1 | | | - | | +--------------+ | +------------+ | | - | | | schetchik | | | - | +---->| 1 +----+ | - | +------------+ | - | | - | +--------------+ | - | +------------+ Risunok 5.20. Struktury dannyh posle vypolneniya funkcii dup 110 pisi, na kotoruyu ukazyvayut svyazannye s nej tochki vhoda v tablice fajlovyh deskriptorov, kotoryh teper' stalo na odnu bol'she. Naprimer, obzor struktur dannyh, izobrazhennyh na Risunke 5.20, pokazyvaet, chto process vyzyvaet sle- duyushchuyu posledovatel'nost' funkcij: on otkryvaet (open) fajl s imenem "/etc/passwd" (fajlovyj deskriptor 3), zatem otkryvaet fajl s imenem "local" (fajlovyj deskriptor 4), snova fajl s imenem "/etc/passwd" (fajlovyj desk- riptor 5) i, nakonec, dubliruet (dup) fajlovyj deskriptor 3, vozvrashchaya desk- riptor 6. Vozmozhno, dup - funkciya, ne otlichayushchayasya izyashchestvom, poskol'ku ona pred- polagaet, chto pol'zovatel' znaet o tom, chto sistema vozvratit svobodnuyu toch- ku vhoda v tablice pol'zovatel'skih deskriptorov, imeyushchuyu naimen'shij nomer. Odnako, ona sluzhit vazhnoj zadache konstruirovaniya slozhnyh programm iz bolee prostyh konstrukcionnyh blokov, chto, v chastnosti, imeet mesto pri sozdanii konvejerov, sostavlennyh iz komandnyh processorov. Rassmotrim programmu, privedennuyu na Risunke 5.21. V peremennoj i hra- nitsya deskriptor fajla, vozvrashchaemyj v rezul'tate otkrytiya fajla "/etc/passwd", a v peremennoj j - deskriptor fajla, vozvrashchaemyj sistemoj v rezul'tate dublirovaniya deskriptora i s pomoshch'yu funkcii dup. V adresnom prostranstve processa oba pol'zovatel'skih deskriptora, predstavlennye pere- mennymi i i j, ssylayutsya na odnu i tu zhe zapis' v tablice fajlov i poetomu ispol'zuyut odno i to zhe znachenie smeshcheniya vnutri fajla. Takim obrazom, per- vye dva vyzova processom funkcii read realizuyut posledovatel'noe schityvanie dannyh, i v buferah buf1 i buf2 budut raspolagat'sya raznye dannye. Sovsem drugoj rezul'tat poluchaetsya, kogda process +--------------------------------------------------------+ | #include | | main() | | { | | int i,j; | | char buf1[512],buf2[512]; | | | | i = open("/etc/passwd",O_RDONLY); | | j = dup(i); | | read(i,buf1,sizeof(buf1)); | | read(j,buf2,sizeof(buf2)); | | close(i); | | read(j,buf2,sizeof(buf2)); | | } | +--------------------------------------------------------+ Risunok 5.21. Programma na yazyke Si, illyustriruyushchaya ispol'zo- vanie funkcii dup otkryvaet odin i tot zhe fajl dvazhdy i chitaet dvazhdy odni i te zhe dannye (razdel 5.2). Process mozhet osvobodit' s pomoshch'yu funkcii close lyuboj iz faj- lovyh deskriptorov po svoemu zhelaniyu, i vvod-vyvod poluchit normal'noe pro- dolzhenie po drugomu deskriptoru, kak pokazano na primere. V chastnosti, pro- cess mozhet "zakryt'" deskriptor fajla standartnogo vyvoda (fajlovyj deskrip- tor 1), snyat' s nego kopiyu, imeyushchuyu to zhe znachenie, i zatem rassmatrivat' novyj fajl v kachestve fajla standartnogo vyvoda. V glave 7 budet predstavlen bolee realisticheskij primer ispol'zovaniya funkcij pipe i dup pri opisanii osobennostej realizacii komandnogo processora. 111 5.14 MONTIROVANIE I DEMONTIROVANIE FAJLOVYH SISTEM Fizicheskij disk sostoit iz neskol'kih logicheskih razdelov, na kotorye on razbit diskovym drajverom, prichem kazhdomu razdelu sootvetstvuet fajl ustroj- stva, imeyushchij opredelennoe imya. Processy obrashchayutsya k dannym razdela, otkry- vaya sootvetstvuyushchij fajl ustrojstva i zatem vedya zapis' i chtenie iz etogo "fajla", predstavlyaya ego sebe v vide posledovatel'nosti diskovyh blokov. |to vzaimodejstvie vo vseh detalyah rassmatrivaetsya v glave 10. Razdel diska mo- zhet soderzhat' logicheskuyu fajlovuyu sistemu, sostoyashchuyu iz bloka nachal'noj zag- ruzki, superbloka, spiska indeksov i informacionnyh blokov (sm. glavu 2). Sistemnaya funkciya mount (montirovat') svyazyvaet fajlovuyu sistemu iz ukazan- nogo razdela na diske s sushchestvuyushchej ierarhiej fajlovyh sistem, a funkciya umount (demontirovat') vyklyuchaet fajlovuyu sistemu iz ierarhii. Funkciya mount, takim obrazom, daet pol'zovatelyam vozmozhnost' obrashchat'sya k dannym v diskovom razdele kak k fajlovoj sisteme, a ne kak k posledovatel'nosti dis- kovyh blokov. Sintaksis vyzova funkcii mount: mount(special pathname,directory pathname,options); gde special pathname - imya special'nogo fajla ustrojstva, sootvetstvuyushchego diskovomu razdelu s montiruemoj fajlovoj sistemoj, directory pathname - ka- talog v sushchestvuyushchej ierarhii, gde budet montirovat'sya fajlovaya sistema (drugimi slovami, tochka ili mesto montirovaniya), a options ukazyvaet, sledu- et li montirovat' fajlovuyu sistemu "tol'ko dlya chteniya" (pri etom ne budut vypolnyat'sya + - - - - - - - - - - - - - - - - - - - - - - - - + / | | | +----------------+--+-------------+ Kornevaya | | | | | fajlovaya bin etc usr sistema | | | - | +-----+-----+ +----+----+ - | | | | | | - | cc date sh getty passwd - + - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - + / | | | Fajlovaya +----------------+--+-------------+ sistema iz | | | | | razdela s bin include src imenem | | | | | /dev/dsk1 +-----+-----+ | | | | | | | | | awk banner yacc stdio.h uts + - - - - - - - - - - - - - - - - - - - - - - - - + Risunok 5.22. Derevo fajlovyh sistem do i posle vypolneniya funkcii mount takie funkcii, kak write i creat, kotorye proizvodyat zapis' v fajlovuyu sis- temu). Naprimer, esli process vyzyvaet funkciyu mount sleduyushchim obrazom: mount("/dev/dsk1","/usr",0); yadro prisoedinyaet fajlovuyu sistemu, nahodyashchuyusya v diskovom razdele s imenem "/dev/dsk1", k katalogu "/usr" v sushchestvuyushchem dereve fajlovyh sistem (sm. 112 Risunok 5.22). Fajl "/dev/dsk1" yavlyaetsya blochnym special'nym fajlom, t.e. on nosit imya ustrojstva blochnogo tipa, obychno imya razdela na diske. YAdro pred- polagaet, chto razdel na diske s ukazannym imenem soderzhit fajlovuyu sistemu s superblokom, spiskom indeksov i kornevym indeksom. Posle vypolneniya funkcii mount k kornyu smontirovannoj fajlovoj sistemy mozhno obrashchat'sya po imeni "/usr". Processy mogut obrashchat'sya k fajlam v montirovannoj fajlovoj sisteme i ignorirovat' tot fakt, chto sistema mozhet otsoedinyat'sya. Tol'ko sistemnaya funkciya link kontroliruet fajlovuyu sistemu, tak kak v versii V ne razreshayut- sya svyazi mezhdu fajlami, prinadlezhashchimi raznym fajlovym sistemam (sm. razdel 5.15). YAdro podderzhivaet tablicu montirovaniya s zapisyami o kazhdoj montirovannoj fajlovoj sisteme. V kazhdoj zapisi tablicy montirovaniya soderzhatsya: * nomer ustrojstva, identificiruyushchij montirovannuyu fajlovuyu sistemu (upo- myanutyj vyshe logicheskij nomer fajlovoj sistemy); * ukazatel' na bufer, gde nahoditsya superblok fajlovoj sistemy; * ukazatel' na kornevoj indeks montirovannoj fajlovoj sistemy ("/" dlya fajlovoj sistemy s imenem "/dev/dsk1" na Risunke 5.22); * ukazatel' na indeks kataloga, stavshego tochkoj montirovaniya (na Risunke 5.22 eto katalog "usr", prinadlezhashchij kornevoj fajlovoj sisteme). Svyaz' indeksa tochki montirovaniya s kornevym indeksom montirovannoj faj- lovoj sistemy, voznikshaya v rezul'tate vypolneniya sistemnoj funkcii mount, daet yadru vozmozhnost' legko dvigat'sya po ierarhii fajlovyh sistem bez polu- cheniya ot pol'zovatelej dopolnitel'nyh svedenij. +------------------------------------------------------------+ | algoritm mount | | vhodnaya informaciya: imya blochnogo special'nogo fajla | | imya kataloga tochki montirovaniya | | opcii ("tol'ko dlya chteniya") | | vyhodnaya informaciya: otsutstvuet | | { | | esli (pol'zovatel' ne yavlyaetsya superpol'zovatelem) | | vozvratit' (oshibku); | | poluchit' indeks dlya blochnogo special'nogo fajla (algo- | | ritm namei); | | proverit' dopustimost' znachenij parametrov; | | poluchit' indeks dlya imeni kataloga, gde proizvoditsya | | montirovanie (algoritm namei); | | esli (indeks ne yavlyaetsya indeksom kataloga ili schetchik | | ssylok imeet znachenie > 1) | | { | | osvobodit' indeksy (algoritm iput); | | vozvratit' (oshibku); | | } | | najti svobodnoe mesto v tablice montirovaniya; | | zapustit' proceduru otkrytiya blochnogo ustrojstva dlya | | dannogo drajvera; | | poluchit' svobodnyj bufer iz bufernogo kesha; | | schitat' superblok v svobodnyj bufer; | | proinicializirovat' polya superbloka; | | poluchit' kornevoj indeks montiruemoj sistemy (algoritm | | iget), sohranit' ego v tablice montirovaniya; | | sdelat' pometku v indekse kataloga o tom, chto katalog | | yavlyaetsya tochkoj montirovaniya; | | osvobodit' indeks special'nogo fajla (algoritm iput); | | snyat' blokirovku s indeksa kataloga tochki montirovaniya;| | } | +------------------------------------------------------------+ Risunok 5.23. Algoritm montirovaniya fajlovoj sistemy 113 Na Risunke 5.23 pokazan algoritm montirovaniya fajlovoj sistemy. YAdro pozvolyaet montirovat' i demontirovat' fajlovye sistemy tol'ko tem processam, vladel'cem kotoryh yavlyaetsya superpol'zovatel'. Predostavlenie vozmozhnosti vypolnyat' funkcii mount i umount vsem pol'zovatelyam privelo by k vneseniyu s ih storony haosa v rabotu fajlovoj sistemy, kak umyshlennomu, tak i yavivshemu- sya rezul'tatom neostorozhnosti. Superpol'zovateli mogut razrushit' sistemu tol'ko sluchajno. YAdro nahodit indeks special'nogo fajla, predstavlyayushchego fajlovuyu siste- mu, podlezhashchuyu montirovaniyu, izvlekaet starshij i mladshij nomera, kotorye identificiruyut sootvetstvuyushchij diskovyj razdel, i vybiraet indeks kataloga, v kotorom fajlovaya sistema budet smontirovana. Schetchik ssylok v indekse ka- taloga dolzhen imet' znachenie, ne prevyshayushchee 1 (i men'she 1 on ne dolzhen byt' - pochemu?), v svyazi s nalichiem potencial'no opasnyh pobochnyh effektov (sm. uprazhnenie 5.27). Zatem yadro naznachaet svobodnoe mesto v tablice montirova- niya, pomechaet ego dlya ispol'zovaniya i prisvaivaet znachenie polyu nomera ust- rojstva v tablice. Vysheukazannye naznacheniya proizvodyatsya nemedlenno, pos- kol'ku vyzyvayushchij process mozhet priostanovit'sya, sleduya procedure otkrytiya ustrojstva ili schityvaya superblok fajlovoj sistemy, a drugoj process tem vremenem popytalsya by smontirovat' fajlovuyu sistemu. Pometiv dlya ispol'zova- niya zapis' v tablice montirovaniya, yadro ne dopuskaet ispol'zovaniya v dvuh vyzovah funkcii mount odnoj i toj zhe zapisi tablicy. Zapominaya nomer ustroj- stva s montiruemoj sistemoj, yadro mozhet vosprepyatstvovat' povtornomu monti- rovaniyu odnoj i toj zhe sistemy drugimi processami, kotoroe, bud' ono dopushche- no, moglo by privesti k nepredskazuemym posledstviyam (sm. uprazhnenie 5.26). YAdro vyzyvaet proceduru otkrytiya dlya blochnogo ustrojstva, soderzhashchego fajlovuyu sistemu, tochno tak zhe, kak ono delaet eto pri neposredstvennom otk- rytii blochnogo ustrojstva (glava 10). Procedura otkrytiya ustrojstva obychno proveryaet sushchestvovanie takogo ustrojstva, inogda proizvodya inicializaciyu struktur dannyh drajvera i posylaya komandy inicializacii apparature. Zatem yadro vydelyaet iz bufernogo pula svobodnyj bufer (variant algoritma getblk) dlya hraneniya superbloka montiruemoj fajlovoj sistemy i schityvaet superblok, ispol'zuya odin iz variantov algoritma read. YAdro sohranyaet ukazatel' na in- deks kataloga, v kotorom montiruetsya sistema, davaya vozmozhnost' marshrutam poiska fajlovyh imen, soderzhashchih imya "..", peresekat' tochku montirovaniya, kak my uvidim dal'she. Ono nahodit kornevoj indeks montiruemoj fajlovoj sis- temy i zapominaet ukazatel' na indeks v tablice montirovaniya. S tochki zreniya pol'zovatelya, mesto (tochka) montirovaniya i koren' fajlovoj sistemy logicheski ekvivalentny, i yadro uprochivaet etu ekvivalentnost' blagodarya ih sosushchestvo- vaniyu v odnoj zapisi tablicy montirovaniya. Processy bol'she ne mogut obra- shchat'sya k indeksu kataloga - tochki montirovaniya. YAdro inicializiruet polya v superbloke fajlovoj sistemy, ochishchaya polya dlya spiska svobodnyh blokov i spiska svobodnyh indeksov i ustanavlivaya chislo svobodnyh indeksov v superbloke ravnym 0. Cel'yu inicializacii (zadaniya na- chal'nyh znachenij polej) yavlyaetsya svedenie k minimumu opasnosti razrushit' fajlovuyu sistemu, esli montirovanie osushchestvlyaetsya posle avarijnogo zavershe- niya raboty sistemy. Esli yadro zastavit' dumat', chto v superbloke otsutstvuyut svobodnye indeksy, to eto privedet k zapusku algoritma ialloc, vedushchego po- isk na diske svobodnyh indeksov. K sozhaleniyu, esli spisok svobodnyh diskovyh blokov isporchen, yadro ne ispravlyaet etot spisok iznutri (sm. razdel 5.17 o soprovozhdenii fajlovoj sistemy). Esli pol'zovatel' montiruet fajlovuyu siste- mu tol'ko dlya chteniya, zapreshchaya provedenie vseh operacij zapisi v sisteme, yadro ustanavlivaet v superbloke sootvetstvuyushchij flag. Nakonec, yadro pomechaet indeks kataloga kak "tochku montirovaniya", chtoby drugie processy pozdnee mog- li ssylat'sya na nee. Na Risunke 5.24 predstavlen vid razlichnyh struktur dan- nyh po zavershenii vypolneniya funkcii mount. 114 5.14.1 Peresechenie tochek montirovaniya v marshrutah poiska imen fajlov Davajte povtorno rassmotrim povedenie algoritmov namei i iget v sluchayah, kogda marshrut poiska fajlov prohodit cherez tochku montirovaniya. Tochku monti- rovaniya mozhno peresech' dvumya sposobami: iz fajlovoj sistemy, gde proizvodit- sya montirovanie, v fajlovuyu sistemu, kotoraya montiruetsya (v napravlenii ot global'nogo kornya k listu), i v obratnom napravlenii. |ti sposoby illyustri- ruet sleduyushchaya posledovatel'nost' komand shell'a. Tablica indeksov Tablica montirovaniya +------------------+ +--------------------+ +------------------+ | | | Indeks kataloga, + - - + | | | gde proizvoditsya | | | | montirovanie | | | | +-------+ | Pomechen kak "toch-|<---+ | |+->| Bufer | | ka montirovaniya" | || | || +-------+ | Schetchik ssylok =1| | | || +------------------+ |+ >+--------------------+| | | | | Superblok ---++ +------------------+ +---+ Indeks tochki monti-| | Indeks ustrojstva| | rovaniya | | Ne ispol'zuetsya | +---+- Kornevoj indeks | | Schetchik ssylok =0| | +--------------------+ +------------------+ | | | +------------------+<---+ | | | Indeks kornya mon-| | | | tiruemoj fajlovoj| | | | sistemy | | | | Schetchik ssylok =1| +--------------------+ +------------------+ +------------------+ Risunok 5.24. Struktury dannyh posle montirovaniya mount /dev/dsk1 /usr cd /usr/src/uts cd ../../.. Po komande mount posle vypolneniya nekotoryh logicheskih proverok zapuska- etsya sistemnaya funkciya mount, kotoraya montiruet fajlovuyu sistemu v diskovom razdele s imenem "/dev/dsk1" pod upravleniem kataloga "/usr". Pervaya iz ko- mand cd (smenit' katalog) pobuzhdaet komandnyj processor shell vyzvat' sis- temnuyu funkciyu chdir, vypolnyaya kotoruyu, yadro analiziruet imya puti poiska, peresekayushchego tochku montirovaniya v "/usr". Vtoraya iz komand cd privodit k tomu, chto yadro analiziruet imya puti poiska i peresekaet tochku montirovaniya v tret'ej komponente ".." imeni. Dlya sluchaya peresecheniya tochki montirovaniya v napravlenii iz fajlovoj sis- temy, gde proizvoditsya montirovanie, v fajlovuyu sistemu, kotoraya montiruet- sya, rassmotrim modifikaciyu algoritma iget (Risunok 5.25), kotoraya identichna versii algoritma, privedennoj na Risunke 4.3, pochti vo vsem, za isklyucheniem togo, chto v dannoj modifikacii proizvoditsya proverka, yavlyaetsya li indeks in- deksom tochki montirovaniya. Esli indeks imeet sootvetstvuyushchuyu pometku, yadro soglashaetsya, chto eto indeks tochki montirovaniya. Ono obnaruzhivaet v tablice montirovaniya zapis' s ukazannym indeksom tochki montirovaniya i zapominaet no- mer ustrojstva montiruemoj fajlovoj sistemy. Zatem, ispol'zuya nomer ustrojs- tva i nomer indeksa kornya, obshchego dlya vseh fajlovyh sistem, yadro obrashchaetsya k indeksu kornya 115 +------------------------------------------------------------+ | algoritm iget | | vhodnaya informaciya: nomer indeksa v fajlovoj sisteme | | vyhodnaya informaciya: zablokirovannyj indeks | | { | | vypolnit' | | { | | esli (indeks v indeksnom keshe) | | { | | esli (indeks zablokirovan) | | { | | priostanovit'sya (do osvobozhdeniya indeksa); | | prodolzhit'; /* cikl s usloviem prodolzheniya */ | | } | | /* special'naya obrabotka dlya tochek montirovaniya */ | | esli (indeks yavlyaetsya indeksom tochki montirovaniya) | | { | | najti zapis' v tablice montirovaniya dlya tochki mon- | | tirovaniya; | | poluchit' novyj nomer fajlovoj sistemy iz tablicy | | montirovaniya; | | ispol'zovat' nomer indeksa kornya dlya prosmotra; | | prodolzhit'; /* prodolzhenie cikla */ | | } | | esli (indeks v spiske svobodnyh indeksov) | | ubrat' iz spiska svobodnyh indeksov; | | uvelichit' schetchik ssylok dlya indeksa; | | vozvratit' (indeks); | | } | | | | /* indeks otsutstvuet v indeksnom keshe */ | | ubrat' novyj indeks iz spiska svobodnyh indeksov; | | sbrosit' nomer indeksa i fajlovoj sistemy; | | ubrat' indeks iz staroj hesh-ocheredi, pomestit' v novuyu;| | schitat' indeks s diska (algoritm bread); | | inicializirovat' indeks (naprimer, ustanoviv schetchik | | ssylok v 1); | | vozvratit' (indeks); | | } | | } | +------------------------------------------------------------+ Risunok 5.25. Modifikaciya algoritma polucheniya dostupa k in- deksu montiruemogo ustrojstva i vozvrashchaet pri vyhode iz funkcii etot indeks. V pervom primere smeny kataloga yadro obrashchaetsya k indeksu kataloga "/usr" iz fajlovoj sistemy, v kotoroj proizvoditsya montirovanie, obnaruzhivaet, chto etot indeks imeet pometku "tochka montirovaniya", nahodit v tablice montirova- niya indeks kornya montiruemoj fajlovoj sistemy i obrashchaetsya k etomu indeksu. Dlya vtorogo sluchaya peresecheniya tochki montirovaniya v napravlenii iz faj- lovoj sistemy, kotoraya montiruetsya, v fajlovuyu sistemu, gde vypolnyaetsya mon- tirovanie, rassmotrim modifikaciyu algoritma namei (Risunok 5.26). Ona pohozha na versiyu algoritma, privedennuyu na Risunke 4.11. Odnako, posle obnaruzheniya v kataloge nomera indeksa dlya dannoj komponenty puti poiska yadro proveryaet, ne ukazyvaet li nomer indeksa na to, chto eto kornevoj indeks fajlovoj siste- my. Esli eto tak i esli tekushchij rabochij indeks tak zhe yavlyaetsya kornevym, a 116 +------------------------------------------------------------+ | algoritm namei /* prevrashchenie imeni puti poiska v indeks */| | vhodnaya informaciya: imya puti poiska | | vyhodnaya informaciya: zablokirovannyj indeks | | { | | esli (put' poiska beret nachalo s kornya) | | rabochij indeks = indeksu kornya (algoritm iget); | | v protivnom sluchae | | rabochij indeks = indeksu tekushchego kataloga | | (algoritm iget); | | | | vypolnit' (poka put' poiska ne konchilsya) | | { | | schitat' sleduyushchuyu komponentu imeni puti poiska; | | proverit' sootvetstvie rabochego indeksa katalogu | | i prava dostupa; | | esli (rabochij indeks sootvetstvuet kornyu i kompo- | | nenta imeni "..") | | prodolzhit'; /* cikl s usloviem prodolzheniya */| | poisk komponenty: | | schitat' katalog (rabochij indeks), povtoryaya algo- | | ritmy bmap, bread i brelse; | | esli (komponenta sootvetstvuet zapisi v kataloge | | (rabochem indekse)) | | { | | poluchit' nomer indeksa dlya sovpavshej komponen-| | ty; | | esli (najdennyj indeks yavlyaetsya indeksom kor- | | nya i rabochij indeks yavlyaetsya indeksom kornya | | i imya komponenty "..") | | { | | /* peresechenie tochki montirovaniya */ | | poluchit' zapis' v tablice montirovaniya dlya | | rabochego indeksa; | | osvobodit' rabochij indeks (algoritm iput); | | rabochij indeks = indeksu tochki montirovaniya;| | zablokirovat' indeks tochki montirovaniya; | | uvelichit' znachenie schetchika ssylok na rabo- | | chij indeks; | | perejti k poisku komponenty (dlya ".."); | | } | | osvobodit' rabochij indeks (algoritm iput); | | rabochij indeks = indeksu s novym nomerom | | (algoritm iget); | | } | | v protivnom sluchae /* komponenta otsutstvuet v | | kataloge */ | | vozvratit' (net indeksa); | | } | | vozvratit' (rabochij indeks); | | } | +------------------------------------------------------------+ Risunok 5.26. Modifikaciya algoritma sintaksicheskogo analiza imeni fajla komponenta puti poiska, v svoyu ochered', imeet imya "..", yadro identificiruet indeks kak tochku montirovaniya. Ono nahodit v tablice montirovaniya zapis', 117 nomer ustrojstva v kotoroj sovpadaet s nomerom ustrojstva dlya poslednego iz najdennyh indeksov, poluchaet indeks dlya kataloga, v kotorom proizvoditsya montirovanie, i prodolzhaet poisk komponenty s imenem "..", ispol'zuya tol'ko chto poluchennyj indeks v kachestve rabochego. V korne fajlovoj sistemy, tem ne menee, kornevym katalogom yavlyaetsya "..". V vysheprivedennom primere (cd "../../..") predpolagaetsya, chto v nachale process imeet tekushchij katalog s imenem "/usr/src/uts". Kogda imya puti poiska podvergaetsya analizu v algoritme namei, nachal'nym rabochim indeksom yavlyaetsya indeks tekushchego kataloga. YAdro menyaet tekushchij rabochij indeks na indeks kata- loga s imenem "/usr/src" v rezul'tate rasshifrovki pervoj komponenty ".." v imeni puti poiska. Zatem yadro analiziruet vtoruyu komponentu ".." v imeni pu- ti poiska, nahodit kornevoj indeks smontirovannoj (pered etim) fajlovoj sis- temy - indeks kataloga "usr" - i delaet ego rabochim indeksom pri analize imeni s pomoshch'yu algoritma namei. Nakonec, ono rasshifrovyvaet tret'yu kompo- nentu ".." v imeni puti poiska. YAdro obnaruzhivaet, chto nomer indeksa dlya ".." sovpadaet s nomerom kornevogo indeksa, rabochim indeksom yavlyaetsya korne- voj indeks, a ".." yavlyaetsya tekushchej komponentoj imeni puti poiska. YAdro na- hodit zapis' v tablice montirovaniya, sootvetstvuyushchuyu tochke montirovaniya "usr", osvobozhdaet tekushchij rabochij indeks (koren' fajlovoj sistemy, smonti- rovannoj v kataloge "usr") i naznachaet indeks tochki montirovaniya (kataloga "usr" v kornevoj fajlovoj sisteme) v kachestve novogo rabochego indeksa. Zatem ono prosmatrivaet zapisi v kataloge tochki montirovaniya "/usr" v poiskah ime- ni ".." i nahodit nomer indeksa dlya kornya fajlovoj sistemy ("/"). Posle eto- go sistemnaya funkciya chdir zavershaetsya kak obychno, vyzyvayushchij process ne ob- rashchaet vnimaniya na tot fakt, chto on peresek tochku montirovaniya. 5.14.2 Demontirovanie fajlovoj sistemy Sintaksis vyzova sistemnoj funkcii umount: umount(special filename); gde special filename ukazyvaet demontiruemuyu fajlovuyu sistemu. Pri demonti- rovanii fajlovoj sistemy (Risunok 5.27) yadro obrashchaetsya k indeksu demontiru- emogo ustrojstva, vosstanavlivaet nomer ustrojstva dlya special'nogo fajla, osvobozhdaet indeks (algoritm iput) i nahodit v tablice montirovaniya zapis' s nomerom ustrojstva, ravnym nomeru ustrojstva dlya special'nogo fajla. Prezhde chem yadro dejstvitel'no demontiruet fajlovuyu sistemu, ono dolzhno udostove- rit'sya v tom, chto v sisteme ne ostalos' ispol'zuemyh fajlov, dlya etogo yadro prosmatrivaet tablicu indeksov v poiskah vseh fajlov, chej nomer ustrojstva sovpadaet s nomerom demontiruemoj sistemy. Aktivnym fajlam sootvetstvuet po- lozhitel'noe znachenie schetchika ssylok i v ih chislo vhodyat tekushchij katalog processa, fajly s razdelyaemym tekstom, kotorye ispolnyayutsya v tekushchij moment (glava 7), i otkrytye kogda-to fajly, kotorye potom ne byli zakryty. Esli kakie-nibud' fajly iz fajlovoj sistemy aktivny, funkciya umount zavershaetsya neudachno: esli by ona proshla uspeshno, aktivnye fajly sdelalis' by