CS2106 Introduction to Operating Systems, Exercises of Operating Systems

Operating Systems ... - Manages resources and coordination (process synchronization, resource sharing). - Simplify programming (abstraction of hardware,.

Typology: Exercises

2022/2023

Uploaded on 05/11/2023

virgyn67
virgyn67 🇺🇸

4.3

(10)

227 documents

1 / 4

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS2106 Introduction to
Operating Systems
Basics
Operating Systems ...
- Manages resources and coordination (process
synchronization, resource sharing)
- Simplify programming (abstraction of hardware,
convenient services)
- Enforce usage policies
- Security of protection
- User program portability (across different hardware)
- Efficiency (optimized for particular usage and hardware)
Kernel mode: complete access to all hardware resources
User mode: limited access to hardware resources
Monolithic OS: Kernel is one big special program
Microkernel OS: Kernel is very small and clean, and only
provide basic and essential facilities (e.g. IPC, address space
management, thread management); higher-level services
(device driver, process management, memory management,
file system) built on top of basic facilities and runs outside
the OS (using IPC to communicate). Kernel is more robust,
and there is more isolation and protection between kernel
and higher-level services, but at lower performance.
Type 1 Hypervisor: Runs directly on hardware
Type 2 Hypervisor: Runs on a host operating system
Process Abstraction
Generic 5-State Process Model:
Running
Ready
Generic 5-State Process Model
48
[ CS2106 L2 -AY1819S1 ]
admit
switch: scheduled exit
event wait
event occurs
create
switch:
release CPU
Notes: generic process states, details vary in actual OS
New
Blocked
Terminated
Process Control Block (PCB): information about a
process: registers, memory region info, PID, process state
Syscall mechanism:
1. User program invokes library call
2. Library call places the syscall number of designated
location (e.g. register)
3. Library call executes TRAP instruction to switch to
kernel mode
4. Appropriate system call handler is determined using the
syscall number as index (usually handled by a dispatcher)
5. Syscall handler is executed (this carries out the actual
request)
6. Control returned to library call, switched back to user
mode
7. Library call returns to user program
Exception: Synchronous (occurs due to program
execution, e.g. arithmetic errors, memory access errors).
Executes an exception handler, like a forced syscall.
Interrupt: Asynchronous (occurs independent of program
execution, e.g. timer, mouse movement, keypress). Executes
an interrupt handler, program execution is suspended.
Process Abstraction in Unix
pid t fork(void):
Parent returns PID of child, child returns zero
int execl(const char *path, const char *arg, ...)
int execv(const char *path, char *const argv[])
e.g. execl("/bin/ls", "ls", "-la", NULL)
init process is the root process (traditionally PID=1)
int wait(int *status)
Set status to NULL to ignore status
Least significant 8 bits is the value passed to exit(int)
Process Scheduling
Non-preemptive (Cooperative): Process stays
scheduled until it blocks or yields
Preemptive: At the end of time quota, the process is
suspended (it is still possible to block or yield early)
Batch Processing
No user interaction, non-preemptive scheduling is predominant
Turnaround time: Total time taken from arrival to finish
(including waiting time)
Throughput: Number of tasks finished per unit time
CPU utilization: Percentage of time CPU is doing work
First-come first-served: Use FIFO queue based on
arrival time (when tasked is blocked it is removed; it is
placed at the back of queue when it is ready again).
Guaranteed to have no starvation
Shortest Job First: Select task with smallest CPU time
(until next I/O). Starvation is possible because long job
may never get a chance (when short jobs keep arriving).
Prediction of CPU time usually uses exponential average of
history
Shortest Remaining Time: Preemptive version of SJF
Convoy effect: Many tasks contend for CPU (while I/O is
idle), and then contend for I/O (while CPU is idle)
Interactive Environment
Preemptive scheduling algorithms are used to ensure good
response time
Response time: Time between request and response by
system
Predictability: Less variation in response time Time
quantum: Execution duration given to a process, must be
a multiple of timer interrupt
Round robin: Like First-come first-served, but will be
interrupted when time quantum elapses
Priority scheduling: Each task gets a priority, highest
priority gets scheduled first.
Preemptive variant: new higher priority process preempts
currently running lower priority process
Non-preemptive variant: new higher priority process has to
wait for next round of scheduling
Low priority process can starve
Priority inversion: higher priority task forced to block while
lower priority task gets to run
Multi-level feedback queue:
If P riority(A)> P riority(B) then Aruns
If P riority(A) == P r iority(B) then round-robin
New job gets highest priority
If a job fully utilized its time slice then priority reduced
If a job yields/blocks then priority retained
Lottery scheduling: Lottery tickets assigned to processes
(possibly unevenly depending on priority), and randomly
chosen winner is allowed to run (preemptive)
Parent can distribute tickets to its child processes, and each
shared resource (CPU, I/O) can have its own set of tickets
Threads
“Lightweight process”
Benefits:
Much less additional resources needed as compared to
processes
No need for additional mechanism to pass information
between threads
Multithreaded programs can appear much more responsive
Multithread programs can take advantage of multiple CPUs
Problems:
Parallel syscall possible - have to guarantee correctness
Process behaviour - fork()/exec()/exit() when there are
multiple threads
User thread: Thread is implemented as a user library
(just library calls); kernel is not aware of the threads
- Implemented by library: more flexible, e.g. customized
thread scheduling policy - One thread blocked -¿ all threads
blocked - Cannot exploit multiple CPUs
Kernel thread: Thread is implemented in the OS (using
syscalls); thread-level scheduling is possible - Multiple
threads from same process can run simultaneously - Thread
operations are syscalls: more resource-intensive and slower -
Less flexible, so it can be generic enough for all
multithreaded programs
Hybrid thread model: User thread can bind to a kernel
thread
Hybrid Thread Model
Have both Kernel and User threads
OS schedule on kernel threads only
User thread can binds to a kernel thread
Offer great flexibility
Can limit the
concurrency
of any process / user
20
[ CS2106 L4 - AY1819S1 ]
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr /*NULL*/,
void *(*start_routine) (void *) /*function ptr*/,
void *arg /*argument for start_routine*/);
int pthread_exit(void *retval);
int pthread_join(pthread_t thread, void **retval);
Inter-Process Communication
Shared memory
Advantages:
Efficient (only the initial steps involves OS)
Easy to use (shared mem region behaves like normal mem)
Disadvantages:
Synchronization (of access)
Implementation is usually harder
int shmget(key_t key /*can be IPC_PRIVATE*/,
size_t size, int shmflg /* IPC_CREAT | 600*/);
//IPC_CREAT means memory will be created if nonexistent
void *shmat(int shmid, const void *shmaddr /*NULL*/,
int shmflg /*0*/);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd /*IPC_RMID*/,
struct shmid_ds *buf /*unused for IPC_RMID*/);
Message passing
Messages stored in kernel memory space
Direct communication:
Sender/receiver explicitly names the other party
One buffer per pair of (sender, receiver)
Indirect communication:
Sender sends to mailbox/port
Receiver receives from mailbox/port
Blocking primitives (synchronous):
Send() blocks until message is received
Receive() blocks until message has arrived
Non-blocking primitives (asynchronous):
Send() does not block
Receive() returns some indication if no message is available
Advantages:
Portable (can implement in distributed system or network)
Easier synchronization (blocking primitives implicitly
synchronize sender/receiver)
Disadvantages:
Inefficient (needs OS intervention)
Harder to use (messages limited in size/format)
Unix Pipes
Pipes function as fixed-size circular byte buffer with implicit
synchronization
- writers wait when buffer is full
- readers wait when buffer is empty
int pipe(int pipefd[2]); // create new pipe
pipefd[0]: file descriptor for reading
pipefd[1]: file descriptor for writing
Unix Signals
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
// returns previous signal handler, or SIG_ERR on error
pf3
pf4

Partial preview of the text

Download CS2106 Introduction to Operating Systems and more Exercises Operating Systems in PDF only on Docsity!

CS2106 Introduction to

Operating Systems

Basics

ˆ Operating Systems ...

  • Manages resources and coordination (process synchronization, resource sharing)
  • Simplify programming (abstraction of hardware, convenient services)
  • Enforce usage policies
  • Security of protection
  • User program portability (across different hardware)
  • Efficiency (optimized for particular usage and hardware)

ˆ Kernel mode: complete access to all hardware resources User mode: limited access to hardware resources

ˆ Monolithic OS: Kernel is one big special program Microkernel OS: Kernel is very small and clean, and only provide basic and essential facilities (e.g. IPC, address space management, thread management); higher-level services (device driver, process management, memory management, file system) built on top of basic facilities and runs outside the OS (using IPC to communicate). Kernel is more robust, and there is more isolation and protection between kernel and higher-level services, but at lower performance.

ˆ Type 1 Hypervisor: Runs directly on hardware Type 2 Hypervisor: Runs on a host operating system

Process Abstraction

ˆ Generic 5-State Process Model:

Ready Running

Generic 5-State Process Model

[ CS2106 L2 - AY1819S1 ] 48

admit switch: scheduled exit

event occurs event wait

create switch: release CPU

Notes: generic process states, details vary in actual OS

New

Blocked

Terminated

ˆ Process Control Block (PCB): information about a process: registers, memory region info, PID, process state

ˆ Syscall mechanism:

  1. User program invokes library call
  2. Library call places the syscall number of designated location (e.g. register)
  3. Library call executes TRAP instruction to switch to kernel mode
  4. Appropriate system call handler is determined using the syscall number as index (usually handled by a dispatcher)
  5. Syscall handler is executed (this carries out the actual request)
  6. Control returned to library call, switched back to user mode
  7. Library call returns to user program

ˆ Exception: Synchronous (occurs due to program execution, e.g. arithmetic errors, memory access errors). Executes an exception handler, like a forced syscall.

ˆ Interrupt: Asynchronous (occurs independent of program execution, e.g. timer, mouse movement, keypress). Executes an interrupt handler, program execution is suspended.

Process Abstraction in Unix

ˆ pid t fork(void): Parent returns PID of child, child returns zero

ˆ int execl(const char *path, const char *arg, ...) int execv(const char *path, char *const argv[]) e.g. execl("/bin/ls", "ls", "-la", NULL)

ˆ init process is the root process (traditionally PID=1)

ˆ int wait(int *status) Set status to NULL to ignore status Least significant 8 bits is the value passed to exit(int)

Process Scheduling

ˆ Non-preemptive (Cooperative): Process stays scheduled until it blocks or yields Preemptive: At the end of time quota, the process is suspended (it is still possible to block or yield early)

Batch Processing

No user interaction, non-preemptive scheduling is predominant

ˆ Turnaround time: Total time taken from arrival to finish (including waiting time) Throughput: Number of tasks finished per unit time CPU utilization: Percentage of time CPU is doing work

ˆ First-come first-served: Use FIFO queue based on arrival time (when tasked is blocked it is removed; it is placed at the back of queue when it is ready again). Guaranteed to have no starvation Shortest Job First: Select task with smallest CPU time (until next I/O). Starvation is possible because long job may never get a chance (when short jobs keep arriving). Prediction of CPU time usually uses exponential average of history Shortest Remaining Time: Preemptive version of SJF

ˆ Convoy effect: Many tasks contend for CPU (while I/O is idle), and then contend for I/O (while CPU is idle)

Interactive Environment

Preemptive scheduling algorithms are used to ensure good response time

ˆ Response time: Time between request and response by system Predictability: Less variation in response time Time quantum: Execution duration given to a process, must be a multiple of timer interrupt

ˆ Round robin: Like First-come first-served, but will be interrupted when time quantum elapses Priority scheduling: Each task gets a priority, highest priority gets scheduled first. Preemptive variant: new higher priority process preempts currently running lower priority process

Non-preemptive variant: new higher priority process has to wait for next round of scheduling Low priority process can starve Priority inversion: higher priority task forced to block while lower priority task gets to run Multi-level feedback queue: If P riority(A) > P riority(B) then A runs If P riority(A) == P riority(B) then round-robin New job gets highest priority If a job fully utilized its time slice then priority reduced If a job yields/blocks then priority retained Lottery scheduling: Lottery tickets assigned to processes (possibly unevenly depending on priority), and randomly chosen winner is allowed to run (preemptive) Parent can distribute tickets to its child processes, and each shared resource (CPU, I/O) can have its own set of tickets

Threads

“Lightweight process” ˆ Benefits: Much less additional resources needed as compared to processes No need for additional mechanism to pass information between threads Multithreaded programs can appear much more responsive Multithread programs can take advantage of multiple CPUs ˆ Problems: Parallel syscall possible - have to guarantee correctness Process behaviour - fork()/exec()/exit() when there are multiple threads ˆ User thread: Thread is implemented as a user library (just library calls); kernel is not aware of the threads

  • Implemented by library: more flexible, e.g. customized thread scheduling policy - One thread blocked -¿ all threads blocked - Cannot exploit multiple CPUs ˆ Kernel thread: Thread is implemented in the OS (using syscalls); thread-level scheduling is possible - Multiple threads from same process can run simultaneously - Thread operations are syscalls: more resource-intensive and slower - Less flexible, so it can be generic enough for all multithreaded programs ˆ Hybrid thread model: User thread can bind to a kernel thread

Hybrid Thread Model

 Have both Kernel and User threads

 OS schedule on kernel threads only

 User thread can binds to a kernel thread

 Offer great flexibility

 Can limit the

concurrency

of any process / user

[ CS2106 L4 - AY1819S1 ] 20 int pthread_create(pthread_t thread, const pthread_attr_t attr /NULL/, void (start_routine) (void ) /function ptr/, void arg /argument for start_routine/); int pthread_exit(void *retval); int pthread_join(pthread_t thread, void **retval);

Inter-Process Communication

Shared memory

ˆ Advantages: Efficient (only the initial steps involves OS) Easy to use (shared mem region behaves like normal mem)

ˆ Disadvantages: Synchronization (of access) Implementation is usually harder

int shmget(key_t key /can be IPC_PRIVATE/, size_t size, int shmflg /* IPC_CREAT | 600/); //IPC_CREAT means memory will be created if nonexistent void shmat(int shmid, const void shmaddr /NULL/, int shmflg /0/); int shmdt(const void shmaddr); int shmctl(int shmid, int cmd /IPC_RMID/, struct shmid_ds buf /unused for IPC_RMID*/);

Message passing

Messages stored in kernel memory space

ˆ Direct communication: Sender/receiver explicitly names the other party One buffer per pair of (sender, receiver) Indirect communication: Sender sends to mailbox/port Receiver receives from mailbox/port

ˆ Blocking primitives (synchronous): Send() blocks until message is received Receive() blocks until message has arrived Non-blocking primitives (asynchronous): Send() does not block Receive() returns some indication if no message is available

ˆ Advantages: Portable (can implement in distributed system or network) Easier synchronization (blocking primitives implicitly synchronize sender/receiver) Disadvantages: Inefficient (needs OS intervention) Harder to use (messages limited in size/format)

Unix Pipes

Pipes function as fixed-size circular byte buffer with implicit synchronization

  • writers wait when buffer is full
  • readers wait when buffer is empty

int pipe(int pipefd[2]); // create new pipe pipefd[0]: file descriptor for reading pipefd[1]: file descriptor for writing

Unix Signals

typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); // returns previous signal handler, or SIG_ERR on error

Synchronization

Critical Sections

ˆ Properties of correct implementation: Mutual exclusion: If there is a process in CS then all other process cannot enter CS Progress: If no process is in CS then one waiting process should be granted access Bounded wait: After a process requests to enter the critical section, there exists an upper bound of number of times other processes can enter the CS before this process Independence: Process not in CS should never block other processes ˆ Symptoms of incorrect synchronization: Deadlock: All processes blocked Livelock: Processes are not blocked, but they keep changing state to avoid deadlock and make no other progress Starvation: Some processes are blocked forever ˆ Test and Set: TestAndSet Reg, Mem

  • Atomically load current content at Mem into Reg, and stores 1 into Mem

ˆ Peterson’s Algorithm:

21

Peterson's Algorithm

 Assumption:  Writing to Turn is an atomic operation

Want[0] 0

Want[0] = 1; Turn = 1; while (Want[1] && Turn == 1);

Want[0] = 0; Process P

Want[1] 0

Turn 0

Want[1] = 1; Turn = 0; while (Want[0] && Turn == 0);

Want[1] = 0; Process P

[ CS2106 L6 - AY1819S1 ]

Critical Section Critical Section

Disadvantages: busy waiting, low level, not general

Semaphores

ˆ Properties of correct implementation: Mutual exclusion: If there is a process in CS then all other process cannot enter CS ˆ Wait()/P()/Down() and Signal()/V()/Up() ˆ Threads queue up on a semaphore (fair scheduling)

ˆ General semaphore: value can be any non-negative integer ˆ Binary semaphore: value can be only 0 or 1 (undefined behaviour to Signal() on binary semaphore which is currently 1) ˆ Producer-Consumer:

38

Producer Consumer: Blocking Version

 Initial Values:  count = in = out = 0mutex = S(1), notFull = S(K), notEmpty = S(0)

while (TRUE) { Produce Item; wait( notFull ); wait( mutex ); buffer[in] = item; in = (in+1) % K; count++; signal( mutex ); signal( notEmpty ); } Producer Process

while (TRUE) { wait( notEmpty ); wait( mutex ); item = buffer[out]; out = (out+1) % K; count--; signal( mutex ); signal( notFull ); Consume Item; } Consumer Process

[ CS2106 L6 - AY1819S1 ]

Memory Management

ˆ Memory regions: Text: for instructions Data: for global variables Heap: for dynamic allocations Stack: for function invocations

ˆ Transient data: variables with automatic storage duration Persistent data: globals, dynamically allocated memory

ˆ Alternatives for memory abstraction: Address relocation: translate all addresses at load time Base + Limit registers: generate instruction to add Base to all memory references at compile time, and check against Limit for validity

ˆ Memory partitioning: every process gets a contiguous memory region Fixed partitioning: physical memory is split into fixed number of partitions, each process occupies exactly one partition

  • Internal fragmentation when process does not need whole partition Dynamic partitioning: partition is created based on actual size of process, OS keeps track of memory regions, and split/merge free regions when necessary
  • External fragmentation unused “holes” in physical memory due to process creation/termination

Dynamic Allocation Algorithms

ˆ Linear search based: First-Fit: take the first hole that is large enough Best-Fit: take the smallest hole that is large enough Worst-Fit: take the largest hole Merging & Compaction: When partition is freed, try merging with adjacent holes Can move occupied partitions around to consolidate holes

ˆ Buddy system:

[ CS2106 L7 - AY1819S1 ] 38

Buddy System: Example

 Assume:

 the largest block is 512 (2 9 )  Only one free block of size 512 initially

… … …

A[9] A[8]

A[1] A[0]

0

Starting address = 0 Size = 2^9

NULL pointer to indicate no free block of this size

Free Memory = 512

0

T1 Request 100 Block P allocated at 0 size = 128

… … …

A[9] A[8]

A[0]

256 A[7] (^128)

P Free Free

0 128 256

  • Each element A[J] is a linked list that keeps track of free blocks of size 2J
  • Each free block is indicated just by the starting address
  • There might be a smallest allocatable block size, i.e. a constant K > 0 such that A[J] exists only when J ≥ K
  • To allocate size 2S^ : find smallest free block with size ≥ 2 S^ , then repeatedly split until there is a block of size 2 S^ , then return that block of size 2S
  • To deallocate: if buddy is also free, merge with buddy and repeat; otherwise add block to the linked list

Paging

ˆ (Physical) frame (Logical) page

  • Frames and pages have the same size
  • Logical memory remains contiguous but physical memory may be disjoint

ˆ Address translation:

  • Make frame size (= page size) a power-of-

Logical Address Translation: Essential Tricks

 Two important design decisions simplifies the

address translation calculation

1. Keep frame size (page size) as a power-of-

2. Physical frame size == Logical page size

p d

Page Number Offset

(m – n) bits n bits Translation mechanism

f d Frame Number Offset

Logical Address

Physical Address

[ CS2106 L8 - AY1819S1 ] (^) 8 ˆ Fragmentation: Paging removes external fragmentation (all free frames can be used without wastage), but pages can still have internal fragmentation (logical memory required may not be a multiple of page size)

ˆ Page table: Stores physical frame for each logical page ˆ Translation look-aside buffer (TLB): cache of a few table entries ˆ Memory access time with TLB: = T LBhit + T LBmiss = 40% × (1ns + 50ns) + 60% × (1ns + 50ns + 50ns)

Translation Look-Aside Buffer: Illustration

[ CS2106 L8 - AY1819S1 ] 14

CPU P^ D

Physical Memory

F D

Page# Frame #

TLB

Frame #

Page Table

P

ˆ Context switching & TLB: On context switch:

  • TLB entries are flushed (so incoming process won’t get incorrect translation)
  • (Optional) Save TLB state to PCB, and restore TLB data for incoming process (to reduce TLB misses)

ˆ (x86) On a TLB miss, the hardware searches through the page table (without invoking the OS); OS is informed only on page fault

ˆ Extensions for protection: Access-right (RWX) bits: memory access is checked against access right bits (by hardware) Valid bit: represent invalid logical addresses, invalid access will be caught by OS

ˆ Page sharing: Several processes use same physical frame

  • e.g. shared libraries, copy-on-write from fork()

Segmentation

  • Each region of memory is placed in a separate segment so they can grow/shrink freely
  • Each memory segment has a segment id and limit
  • Memory references are specified as: segment id + offset
  • Can cause external fragmentation

0 1 2 3 segment table

Base Limit

Logical Address Translation: Illustration

Physical Memory

Assume: User Code Segment = 0 Global Data Segment = 1 Heap Segment = 2 Stack Segment = 3

0 1 2 3

segment table

Base Limit

Memory Access < Segment Id, Offset > (^) User Code Segment

Stack Segment

Heap Segment

Global Data Segment

0

1300

2400

3500

5700

6000

7500

Segmentation with Paging: Illustration^ Segmentation with Paging

[ CS2106 L8 - AY1819S1 ] 33

CPU S P D

Page limit

Pg Table Base

Frame < Number

F D

Yes No Addressing Error!

S

P

Physical Memory

Segment Table

Page Table

Secondary Storage (With Paging)

ˆ Some pages can be stored on secondary storage, so that a process can use more logical memory than what is physically available

ˆ Page table stores memory resident bit:

  • memory resident: page in physical memory (RAM)
  • non-memory resident: page in secondary storage ˆ Page fault: When CPU tries to access non-memory resident page
  • OS locates the page in secondary storage and loads it into physical memory ˆ Thrashing: Page fault happens too often
  • for well-behaved programs it is unlikely to happen due to temporal and spatial locality

Page Table Structure

ˆ Direct paging: All pages in single table, might occupy several memory pages ˆ 2-level paging: Keep a page directory, [[TODO]] ˆ Inverted page table: Single table for all processes, stores (pid, logical page) indexed by frame number

Page Replacement Algorithms

ˆ Optimum (OPT): Replace the page that will not be used again for the longest period of time, not feasible as it needs future knowledge ˆ First In First Out (FIFO): Evict the oldest page first

  • simple to implement, OS maintains a queue of resident page numbers
  • can be tricked: try 3 / 4 frames with 1 2 3 4 1 2 5 1 2 3 4 5 (Belady’s Anomaly)
  • does not exploit temporal locality ˆ Least Recently Used (LRU): Evict the page that has not been used for the longest time
  • makes use of temporal locality
  • does not suffer from Belady’s Anomaly
  • difficult to implement, needs hardware support: (option 1) store “time-of-use” and update it on every access, need to search through all pages to find earliest time-of-use (option 2) maintain a “stack”; when page is accessed, remove from stack (if exists) and push on top of stack

Ext

ˆ LayoutExt2 FS: Layout: MB partition 1 partition 2 partition 3 partition 4 R

BOOT Block Group 0 Block Group 1 Block Group 2 ...

Group Descriptors Data Blocks

Super- Block

Block Bitmap I-node Bitmap

I-node Table [ CS2106 L12 - AY1819S1 ] (^) 21 ˆ Superblock, group desc. duplicated in each block group

ˆ Block, I-node bitmap 1=occupied, 0=free

ˆ I-Node structureExt2: I-Node Structure (128 Bytes):

[ CS2106 L12 - AY1819S1 ] 24

Mode (2)

Owner Info (4) File Size (4/8) Timestamps (3 x 4)

Reference Count (2)

Data Block Pointers (15 x 4)

Other …Fields …

File type (regular, directory, special, etc) + File permission User Id (2 bytes)

  • Group Id (2 bytes) File Size in bytes. Larger for regular file ( 8 bytes ) Creation, Modification & Deletion timestamps Indices of data blocks. 12 x direct, 1 x indirect, 1 x double indirect, 1 x triple indirect

Number of time this I-Node is referenced by directory entry

ˆ Directory entry:

  • size includes all subfields and possible gap to next entry
  • root directory has a fixed I-node number

Directory Entry (Illustration)

91 F 4 Hi.c 39 F 8 lab5.pdf

74 D 3 sub 0

I-Node Number

Entry Size

Entry Type

Name Length

Name (^) Use a 0 I-Node number to indicate unused entry

[ CS2106 L12 - AY1819S1 ] (^) 30 ˆ Deleting a file:

  • remove its directory entry from the parent directory by adjusting previous size to point to next entry
  • update I-node bitmap by marking file’s I-node as free
  • update block bitmap by marking file’s blocks as free

ˆ Hard link: multiple directory entries point to same I-node

ˆ Sym. link: file (not I-node) content is path of target file

  • can become invalid if target is deleted

Journaling

Write information or actual data to separate log file before performing file operation, so it can recover from system crash