سيستم مديريت فايل در Unix

 1- مقدمه‌اي بر فايل‌سيستم

 مهمترين قسمت سيستم‌عامل Unix مديريت فايل آن است. در Unix ‌عملكرد همه اجزاي سيستم‌عامل توسط فايلها كنترل مي‌شود. يكي از تعاريفي كه در مورد سيستمهاي مبتني بر Unix بيان شده اين است كه Unix يك فايل بزرگ است. همين باعث مي‌شود كه سيستم مديريت فايل در اين سيستمها اهميت زيادي پيدا كند. حال ببينيم Unix با فايلها چگونه برخورد مي‌كند. تمام فايلهايي كه از طريق سيستم قابل دستيرسي هستند در يك ساختار درختي معكوس قرار مي‌گيرند و اين امر باعث مي‌شود كل فايل‌سيستم به عنوان يك موجوديت واحد در نظر گرفته شود. هر گونه دسترسي به فايلهاي موجود از طريق ريشه اين درخت كه دايركتوري / مي‌باشد انجام مي‌شود. تمام منابعي كه ما قصد استفاده از آنها را داريم بايد داخل اين ساختار درختي قرار بگيرند و هنگامي كه نيازي به آنها نداريم مي‌توانيم آنها را از اين ساختار خارج كنيم. به اين دو عمل به ترتيب mount و unmount كردن مي‌گويند. پارتيشن‌هاي داراي فايل‌سيستمهاي مختلف مي‌توانند با استفاده از روشهاي خاصي كه در ادامه اين قسمت توضيح داده مي‌شوند در اين ساختار درختي قرار بگيرند (mount شوند) و بعد از اين عمل كاربر متوجه نمي‌شود كه فايلها در پارتيشن‌هاي جداگانه قرار دارند. پارتيشن mount شده هم يك سيستم فايل درختي مخصوص به خود دارد كه داخل ساختار درختي واحد سيستم ما قرار گرفته است. تبديل اين دو به هم وظيفه مدير فايل ‌سيستم‌عامل است و از ديد كاربر پنهان مي‌ماند. براي رسيدن به اين مقصود بايد سيستم مديريت فايل را از نوع سخت افزار و فرمت آن مستقل كنيم؛ يعني فرمتي كه ساختار درختي فايل در آن قرار مي‌گيرد حالت مجازي داشته و وابستگي به نوع ديسك، محل قرار گرفتن آن و نوع فايل‌سيستم آن نداشته باشد. اين پديده اين امكان را به ما مي‌دهد كه فايل‌سيستمهاي مختلفي را حتي از روي شبكه بتوانيم mount كنيم. براي هر نوع فايل‌سيستم يك مبدل به اين سيستم فايل مجازي در نظر مي‌گيريم كه بتواند فرمت اين دو را به يكديگر تبديل كند. ابتدا ببينيم خود فايل‌سيستم Unix با فايلها چگونه رفتار مي‌كند.

 

2- ساختار سيستم مديريت فايل در Unix

 فايل‌سيستم شامل يك سري بلاكهاي پشت سرهم است. اندازه هر بلاك مي‌تواند 512، 1024، 2048، و يا هر مضرب ديگري از 512 باشد و اين اندازه داخل هر پارتيشن ثابت است. هرقدر اندازه بلاك بزرگتر باشد سرعت خواندن از ديسك بيشتر مي‌شود، چون يك بار خواندن 1024 بايت سريعتر از دوبار خواندن 512 بايت است. از طرف ديگر با افزايش طول بلاك مقدار تلف شده داخل بلاكها بيشتر مي‌شود[1]. براي مثال براي ذخيره كردن يك فايل به طول 1025 بايت در بلاكهايي به طول 1024، 1023 بايت تلف مي‌شود. اين مقدار تلف شده براي يك پارتيشن به طور متوسط نصف بلاك به ازاي هر فايل است. اگر طول بلاك را 4096 بايت در نظر بگيريم فضاي تلف شده مي‌تواند بسته به اندازه فايلها تا 45% كل حجم پارتيشن هم افزايش يابد. پس در انتخاب طول بلاكها خيلي بايد دقت شود كه متناسب با طول متوسط فايلهايي باشد كه قرار است در آن پارتيشن قرار بگيرند.

 

يكي از مفاهيم كليدي فايل‌سيستم Unix، inode[2] است. هر فايل با يك inode مشخص مي‌شود و اطلاعات مربوط به يك فايل از جمله بلاكهايي كه اطلاعات فايل در آنها نوشته شده، اندازه فايل، اجازه‌هاي دسترسي و زمانهاي دسترسي به فايل در آن inode ذخيره مي‌شوند. شماي كلي فايل‌سيستم Unix ‌چيزي شبيه به شكل زير است:

 

boot block در ابتداي پارتيشن قرار مي‌گيرد. در صورتي كه پارتيشن مربوطه قابل بوت شدن باشد اطلاعات مربوط به اجرا شدن سيستم‌عامل در اين قسمت قرار مي‌گيرد.

super block خصوصيات فايل‌سيستم را مشخص مي‌كند (اندازه آن، حداكثر تعداد فايلهايي كه مي‌توانند در آن قرار بگيرند، بلاكهاي خالي، inode هاي خالي و اطلاعات ديگر).

inode list ليست inode هاي موجود در فايل‌سيستم مربوطه است. اندازه و تعداد آنها هنگام فرمت كردن پارتيشن تعيين مي‌شود. kernel با شماره انديس inode ها در اين آرايه به آنها مراجعه مي‌كند. يكي از اين inode ها (inode شماره 2) inode ريشه فايل‌سيستم است كه معادل با ديركتوري / مي‌باشد. اگر اين پارتيشن قرار است روي يك فايل‌سيستم ديگر mount شود، اين inode ارتباط بين ساختار درختي اين پارتيشن را با جايي كه قرار است روي آن mount شود برقرار مي‌كند.

data blocks فضايي است كه اطلاعات مربوط به فايل در آن قرار مي‌گيرد. هر بلاك داده فقط به يك فايل تعلق دارد.

 

3- نحوه ذخيره سازي يك فايل

 همانطور كه قبلا نيز ذكر كرديم ليست بلاكهايي كه اطلاعات فايل در آنها نوشته شده است در inode وجود دارد. مي‌توان شماره بلاكها را پشت سر هم در inode قرارداد، ولي محاسبات ساده نشان ميدهد كه در اين حالت مديريت اين ليست خيلي سخت است. اگر اندازه هر بلاك را 1K بايت در نظر بگيريم، براي يك فايل به طول 10K بايت نياز به 10 شماره بلاك و براي يك فايل به طول 100K بايت نياز به 100 شماره بلاك در فهرست بلاكها داريم. براي مديرت چنين سيستمي، يا بايد تعداد inode ها را كه بين يك طيف وسيعي در تغيير هستند تحمل كنيم و يا اندازه فايل را محدود كنيم. براي اينكه هم اندازه inode را كوچك نگهداريم و نيز امكان ايجاد فايلهاي بزرگ را داشته باشيم، فهرست بلاكها را در فرمتي كه در شكل زير نشان داده شده قرار مي‌دهيم. در اين فرمت  كه متعلق به System V Unix است، فهرست بلاكها شامل 13 شماره بلاك يا نود است.

   نودهاي مستقيم كه تعدادشان 10  تاست به بلاكهاي داده اشاره مي‌كنند. نودهاي غير مستقيم به بلاكهايي اشاره مي‌كنند كه شامل يك سري نود مي‌باشند و اين نودها نيز مي‌توانند مستقيم يا غير مستقيم باشند. نودهاي غيرمستقيم مرتبه اول به بلاكهايي اشاره مي‌كنند كه شامل نودهاي مستقيم مي‌باشند. نودهاي غير مستقيم مرتبه دوم به بلاكهايي اشاره مي‌كنند كه شامل نودهاي غير مستقيم مرتبه اول مي‌باشند. نودهاي غير مستقيم مرتبه سوم به بلاكهايي اشاره مي‌كنند كه شامل نودهاي غير مستقيم مرتبه دوم مي‌باشند. از نظر تئوري نودهاي غير مستقيم مرتبه چهارم و پنجم و … نيز مي‌توان داشت ولي با همين سه نوع نود غير مستقيم نيز مي‌توان فايلهاي نسبتا بزرگي را آدرس دهي كرد. فرض كنيد هر بلاك داده شامل 1K بايت اطلاعات باشد و نيز هر بلاك با 32‌ بيت قابل آدرس دهي باشد (يعني حجم پارتيشن بيشتر از 4G بايت نباشد)، بنابراين هر بلاك ميتواند شامل 256 ‌نود باشد. در اين شرايط اندازه فايلي كه توسط اين سيستم قابل آدرس دهي است چيزي بيشتر از 16G بايت مي‌باشد. البته اين مقدار توسط يك فاكتور ديگر محدود مي‌شود، فضايي كه جهت نگهداري اندازه فايل در inode در نظر گرفته شده 32 بيت است و اين عامل اندازه فايل را به 4G بايت محدود مي‌كند، يعني به اندازه كل پارتيشن.

 در اين سيستم براي دسترسي به فايلهايي كه كمتر از 10K بايت هستند براي بدست آوردن شماره بلاكهايي كه فايل در آنها ذخيره شده است، فقط نياز به يك بار دسترسي به ديسك داريم و آن هم براي خواندن خود inode مي‌باشد، چون براي ذخيره كردن فهرست بلاكها فقط از نودهاي مستقيم استفاده شده است. در دسترسي به يك فايل نسبتا بزرگ، براي پيدا كردن آدرس يك بلاك كه بوسيله نود غير مستقيم مرتبه سوم آدرس دهي مي‌شود علاوه بر خواندن inode نياز به سه بار دسترسي ديگر به ديسك داريم. اينجا اين سوال به ذهن مي‌رسد كه اين روش در عمل چقدر مفيد است.  پاسخ اين سوال بستگي به اين دارد كه چگونه از سيستم استفاده مي‌شود و اندازه ميانگين فايلها در سيستم چقدر است و نيز فايلهاي كوچك و بزرگ هر كدام به چه نسبتي استفاده مي‌شوند. در Unix اندازه خيلي از فايلها كمتر از 10K بايت است و بيشتر شان حتي كمتر از 1K بايت مي‌باشند. در يك بررسي نمونه ميان 19978 فايل، مشخص شد كه 85% فايلها كمتر از 10K بايت و 48% آنها كمتر از 1K بايت بوده اند. هرچند اندازه فايلها در سيستمهاي مختلف متفاوت است، ولي مي‌توان پيش بيني كرد كه اين مقادير نبايد در سيستمهاي مختلف تفاوت فاحشي داشته باشند. پس سيستمي كه در اينجا عنوان مي‌شود فقط چيزي در حدود 10% مواقع مجبور است به نودهاي غير مستقيم دسترسي پيدا كند. اگر اندازه فايلها به طور معمول خيلي بيشتر از مقاديري است كه در اينجا ذكر شده (مثلا يك پارتيشن كه فايلهاي log در آن ذخيره مي‌شود چنين خصوصيتي را دارد) مي‌توان با افزودن اندازه بلاكها كارآيي سيستم را بالا برد. اگر اندازه يك بلاك به جاي 1K بايت، 8K بايت باشد فايلهاي تا سقف 80K بايت نيز مي‌توانند فقط بوسيله نودهاي مستقيم آدرس دهي شوند.  بايد دقت كرد كه اين افزايش متناسب با اندازه فايلهاي باشد، چون اگر اين افزايش بيشتر از حد معمول باشد، موجب تلف شدن فضاي داخل بلاكها مي‌شود.

 

3-1- دايركتوريها

 داير كتوريها ، فايلهايي هستند كه ساختار درختي و سلسله مراتبي فايل‌سيستم را ايجاد مي‌كنند. آنها نقش مهمي را در تبديل نام فايل به شماره inode بازي مي‌كنند. يك دايركتوري شامل يك سري ركورد است كه هر ركورد شامل نام فايل و شماره inode متناظر با آن فايل است. هر فايلي كه داخل دايركتوري است يك ركورد مخصوص به خود داخل inode مربوط به دايركتوري دارد.

 

File Names

Inode Number

(2 Bytes)

Bytes Offset

in Directory

    .

83

0

    ..

2

16

    init

1798

32

    fsck

1276

48

    ciri

85

64

    motd

1268

80

    mount

1799

96

    mknod

88

112

    passwd

2114

128

    umount

1717

144

    checklist

1851

160

    fsdblb

92

176

    config

84

192

    getty

1432

208

    crash

0

224

    mkfs

95

240

    inittab

188

256

 شكل فوق قسمتي از محتويات دايركتوري etc را نمايش مي‌دهد. هر دايركتوري شامل دو فايل ”.” و ”..”  مي‌باشد كه شماره inode متناظر با آنها به ترتيب به خود دايركتوري و پدر آن اشاره مي‌كند. در System V Unix طول اسم يك فايل نمي‌تواند بيشتر از 14 حرف باشد، بنابراين هر ركورد داخل دايركتوري بيشتر از 16 بايت فضا اشغال نمي‌كند. اگر به شكل هم نگاه كنيد متوجه مي‌شويد كه ركورد مربوط به ”.” از بايت 0  و ركورد مربوط به ”..” از بايت 16 شروع شده است. فايلهاي داخل دايركتوري مي‌توانند خالي باشند كه در اينصورت با inode شماره 0 مشخص ميشوند. در اين مثال فايل crash خالي است. دايركتوريها هم عينا مانند فايلها ذخيره و خوانده مي‌شوند.

 

4- سيستم مديريت فايل شبكه

 براي پياده سازي NFS ‌بايد راهي براي پشتيباني از فايل‌سيستم شبكه علاوه بر فايل‌سيستم Unix پيدا كنيم. هدف اين است كه فايلهاي شبكه و فايلهاي Unix از ديد يك برنامه كاربردي يكسان باشند. فايلهايي كه بر روي شبكه وجود دارند در فرمتهاي مختلفي هستند و توسط سيستمهاي مختلف مديريت فايل اداره ميشوند. تنها راه اين است كه واسط سيستم مديريت فايل را از نحوه پياده سازي آن جدا كنيم. اين واسط جديد كه توسط شركت Sun براي مديريت NFS طراحي شد واسط VFS/VNODE[3] نام دارد. ساختار VFS/VNODE‌در شكل زير نشان داده شده است. inode ها هنوز هم استفاده مي‌شوند ولي در يك لايه پايينتر از VFS. همچنين واسط فايل در kernel در سطح بالايي از تجريد قرار دارد.

  در اين شكل مشخص است كه Unix File VFS و Remote File VFS هر دو در يك سطح قرار دارند. NFS به جاي inode از rnode براي دسترسي به فايلها استفاده مي‌كند ولي عملكرد هر دو از لحاظ مفهومي يكسان است. واسط VFS به Sun اجازه مي‌دهد كه يك واسط فايل‌سيستم يكپارچه براي مديريت سيستمهاي مختلف مديريت فايل داخل kernel بوجود بياورد. علاوه بر اين با اين روش از نظر يك برنامه كاربردي فايلهاي Unix، فايلهاي شبكه و يا فايلهاي يك پارتيشن DOS هيچگونه تفاوتي با هم ندارند. همه در فرمت VFS/VNODE مي‌باشند.

 

5- سيستم مديريت فايل مجازي (VFS)

 ساختار داخلي VFS نيز از ديد كلي مانند فايل‌سيستم Unix است؛ يعني در اينجا هم فضاي ديسك به شكل يك سري inode و بلاك داده در نظر گرفته مي‌شود. هر فايل‌سيستم جديد هم كه بخواهد داخل اين سيستم اضافه شود (mount شود) بايد آرايش داخلي فايل‌سيستم مربوطه به اين شيوه تبديل شود و اين كار توسط يك سري توابع كه يا داخل kernel وجود دارند و يا به شكل ماجول قابل بارگذاري هستند انجام مي‌شود. پشتيباني نكردن از يك فايل‌سيستم خاص بدين معني است كه اين توابع براي آن فايل‌سيستم خاص در kernel وجود ندارد. براي اينكه بتوان به فايل‌سيستم يك پارتيشن خاص دسترسي پيدا كرد بايد آن پارتيشن را روي ساختار درختي اصلي كه توسط VFS مديريت مي‌شود mount  كرد. براي مثال دستور زير CD-ROM را كه داراي فايل‌سيستم iso9660 است روي دايركتوري /mnt/cdrom،mount  مي‌كند:

# mount -t iso9660 ro /dev/cdrom /mnt/cdrom

اطلاعاتي كه از طريق اين دستور به kernel پاس داده مي‌شوند عبارتند از نام فايل‌سيستم موجود بر روي CD-ROM (iso9660)، سخت افزار مربوطه (/dev/cdrom)، و نام دايركتوري‌اي از ساختار درختي موجود كه اين پارتيشن قرار است در آن نقطه قرار بگيرد (/mnt/cdrom). بعنوان يك مثال ديگر دستور زير يك دايركتوري را از طريق NFS و از روي يك سيستم ديگر mount مي‌كند:

# mount –t nfs 213.29.6.10:/redhat_CD /mnt

 

وقتي  يك فايل‌سيستم جديد را روي يك دايركتوري mount مي‌كنيم محتويات فعلي آن دايركتوري پنهان مي‌شوند و پس از unmount‌ كردن فايل‌سيستم مربوطه مي‌توان به محتويات دايركتوري مجددا دسترسي پيدا كرد. اين كار بدين صورت انجام مي‌پذيرد كه kernel همواره ليستي از فايل‌سيستمهاي mount شده را نگهداري مي‌كند. به هنگام مراجعه به يك دايركتوري اگر نام آن دايركتوري در اين ليست نبود محتويات خود دايركتوري نشان داده مي‌شود، در غير اينصورت دايركتوري ريشه پارتيشن mount شده به جاي آن قرار مي‌گيرد. همراه با اطلاعاتي كه براي هر پارتيشن mount شده نگهداري مي‌شود نوع فايل‌سيستم، مشخصات كلي، و توابع مخصوص خواندن ونوشتن آن فايل‌سيستم خاص وجود دارند كه رابطه بين VFS و آن سيستم خاص مديريت فايل را برقرار مي‌سازند.

 

6- VFS Inode Cache

 Inode cache يك جدول hash مي‌باشد كه هر عنصر اين جدول يك ليست پيوندي از inode هاي با مقدار hash يكسان مي‌باشد. مقدار hash يك inode نيز تابع شماره ديسك و شماره inode است. هنگامي كه قرار است يك inode از ديسك خوانده شود ابتدا مقدار hash آن محاسبه شده و سپس تمامي اعضاي ليست پيوندي متناظر با آن مقدار چك مي‌شوند. در صورت موجود بودن inode مربوطه در ليست، مقدار آن از حافظه خوانده مي‌شود. در غير اينصورت يك نود جديد در ليست متناظر با مقدار hash اين inode تشكيل شده و اطلاعات مربوط به inode در آن كپي مي‌شود. عملكرد اين cache بگونه‌اي است كه inode هايي كه بيشتر به آنها مراجعه مي‌شود در cache باقي مي‌مانند و به محض اينكه kernel با كمبود فضا در حافظه براي ذخيره inode جديد مواجه شود inode هايي را كه كمتر استفاده مي‌شوند از cache خارج كرده و inode هاي جديد را به جاي آنها قرار مي‌دهد. در اينجا ذكر اين نكته ضروري است كه به هنگام دسترسي به inode مربوط به يك فايل ممكن است مجبور شويم inode هاي ديگري را هم بخوانيم، مثلا براي دسترسي به يك فايل مجبوريم inode تمام دايركتوريهايي را كه به آن فايل ختم ميشوند بخوانيم.

 

7- Directorg Cache

 براي سرعت بخشيدن به عمليات دسترسي به دايركتوريهايي كه مكررا استفاده مي‌شوند VFS‌ از يك Dirctory Cache ‌استفاده مي‌كند. هنگامي كه دسترسي به يك دايركتوري انجام مي‌شود جزئيات مربوط به آن در  Directory Cache‌ قرار مي‌گيرد. دفعه بعد اطلاعات مربوط به دايركتوري از Directory Cache خوانده مي‌شود نه از ديسك. البته فقط دايركتوريهايي كه نامشان  كمتر از 15 حرف است مي‌توانند داخل اين cache قرار بگيرند (هر چند، بيشتر دايركتوريهايي كه بيشتر به آنها مراجعه مي‌شود كمتر از 15  حرف مي‌باشند مثلا /usr/X11R6/bin). مكانيزم اين cache نيز عينا مانند Inode Cache‌ مي‌باشد. از يك جدول hash استفاده مي‌شود كه مقادير hash مربوط به دايركتوريها تابع شماره ديسك و نام دايركتوري مي‌باشد و هر ركورد اين جدول يك ليست پيوندي از داير كتوريهاي با مقدار hash يكسان است.

 

7- فايل‌سيستم /proc

 فايل‌سيستم /proc قدرت سيستم مديريت فايل مجازي Unix را نشان مي‌دهد. دايركتوري /proc و هيچكدام از زيردايركتوريهايش عملا وجود خارجي ندارند. فايل‌سيستم /proc مانند يك سيستم واقعي مديريت فايل خود را به VFS معرفي مي‌كند، ولي وقتي VFS قصد دارد از طريق inode ها به فايلهاي موجود در اين دايركتوري دسترسي پيدا كند. فايل‌سيستم /proc آنها را با استفاده از اطلاعات موجود در kernel مي‌سازد. براي مثال فايل /proc/devices ‌با استفاده از اطلاعات kernel در مورد سخت افزار سيستم تشكيل مي‌شود. در اصل فايل‌سيستم /proc يك پنجره قابل درك براي كاربر از آنچه درون kernel اتفاق مي‌افتد تشكيل مي‌دهد.

 

8- خلاصه  

اين مقاله به بررسي نحوه عملكرد سيستم مديريت فايل در Unix مي‌پرداخت. به دنبال بررسي نحوه دسترسي به فايلها در Unix راه حلي براي مشكل پشتيباني از سيتمهاي مختلف مديريت فايل ارائه شد. جهت نيل به اين منظور ساختاري به نام VFS/VNODE‌مطرح مي شود كه تحت اين مفهوم تمامي روشها و سيستمهاي مديريت فايل مي توانند با هم جمع شوند و يك ساختار درختي واحد را تشكيل دهند. VFS اين امكان را به ما مي دهد كه بتوانيم ديكسهايي را كه بر روي شبكه قرار دارند با پروتكل NFS روي ساختار درختي خود mount كنيم. در مجموع VFS يك ديد كلي و انتزاعي از سيستم مديريت فايل را در قالب VFS inode فراهم مي كند.