[537] File-System APIs
Persistence:
File System API
Questions answered in this lecture:
How to name files?
What are inode numbers?
How to lookup a file based on pathname?
What is a file descriptor?
What is the difference between hard and soft links?
CSE 2431
Systems 2
Based on slides by Andrea C. Arpaci-Dusseau
Remzi H. Arpaci-Dusseau
What is a File?
Array of persistent bytes that can be read/written
File system consists of many files
Refers to collection of files
Also refers to part of OS that manages those files
Files need names to access correct one
File Names
Three types of names
Unique id: inode numbers
Path
File descriptor
Inode Number
Each file has exactly one inode number
Inodes are unique (at a given time) within file system
Different file system may use the same number,
numbers may be recycled after deletes
See inodes via “ls –i”; see them increment…
What does “i” stand for?
“In truth, I don’t know either. It was just a term that we started to use. ‘Index’ is my best guess, because of the slightly unusual file system structure that stored the access information of files as a flat array on the disk…”
~ Dennis Ritchie
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
file
file
inode number
Data
Meta-data
File API (attempt 1)
read(int inode, void *buf, size_t nbyte)
write(int inode, void *buf, size_t nbyte)
seek(int inode, off_t offset)
seek does not cause disk seek until read/write
Disadvantages?
names hard to remember
no organization or meaning to inode numbers
semantics of offset across multiple processes?
Paths
String names are friendlier than number names
File system still interacts with inode numbers
Store path-to-inode mappings in predetermined “root” file (typically inode 2)
Directory!
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
inode number
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
inode number
“readme.txt”: 3, “hello”: 0, …
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
inode number
“readme.txt”: 3, “hello”: 0, …
Paths
Generalize!
Directory Tree instead of single root directory
Only file name needs to be unique
/usr/dusseau/file.txt
/tmp/file.txt
Store file-to-inode mapping for each directory
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
read /etc/bashrc
reads: 0
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
read /etc/bashrc
reads: 1
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
read /etc/bashrc
reads: 2
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
read /etc/bashrc
reads: 3
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
read /etc/bashrc
reads: 4
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
read /etc/bashrc
reads: 5
location
size=12
inodes
0
location
size
1
location
size
2
location
size=6
3
…
“bashrc”: 3, …
# settings: …
inode number
“etc”: 0, …
read /etc/bashrc
reads: 6
Read root dir (inode and data);
read etc dir (inode and data);
read bashrc file (indode and data)
Reads for getting final inode called “traversal”
Directory Calls
mkdir: create new directory
readdir: read/parse directory entries
Why no writedir?
Special Directory Entries
$ ls -la
total 728
drwxr-xr-x 34 trh staff 1156 Oct 19 11:41 .
drwxr-xr-x+ 59 trh staff 2006 Oct 8 15:49 ..
-rw-r–r–@ 1 trh staff 6148 Oct 19 11:42 .DS_Store
-rw-r–r– 1 trh staff 553 Oct 2 14:29 asdf.txt
-rw-r–r– 1 trh staff 553 Oct 2 14:05 asdf.txt~
drwxr-xr-x 4 trh staff 136 Jun 18 15:37 backup
…
cd /; ls -lia
File API (attempt 2)
pread(char *path, void *buf, off_t offset, size_t nbyte)
pwrite(char *path, void *buf, off_t offset, size_t nbyte)
Disadvantages?
Expensive traversal!
Goal: traverse once
File Names
Three types of names:
– inode
– path
– file descriptor
File Descriptor (fd)
Idea:
Do expensive traversal once (open file)
store inode in descriptor object (kept in memory).
Do reads/writes via descriptor, which tracks offset
Each process:
File-descriptor table contains pointers to open file descriptors
Integers used for file I/O are indexes into this table
stdin: 0, stdout: 1, stderr: 2
FD Table
struct file {
…
struct inode *ip;
uint off;
};
// Per-process state
struct proc {
…
struct file *ofile[NOFILE]; // Array of pointers to open files
…
}
Code Snippet
int fd1 = open(“file.txt”); // returns 3
read(fd1, buf, 12);
int fd2 = open(“file.txt”); // returns 4
int fd3 = dup(fd2); // returns 5
Code Snippet
0
1
2
3
4
5
offset = 0
inode =
fds
fd table
location = …
size = …
inode
“file.txt” also points here
int fd1 = open(“file.txt”); // returns 3
Code Snippet
0
1
2
3
4
5
offset = 12
inode =
fds
fd table
location = …
size = …
inode
int fd1 = open(“file.txt”); // returns 3
read(fd1, buf, 12);
Code Snippet
0
1
2
3
4
5
offset = 12
inode =
offset = 0
inode =
fds
fd table
location = …
size = …
inode
int fd1 = open(“file.txt”); // returns 3
read(fd1, buf, 12);
int fd2 = open(“file.txt”); // returns 4
Code Snippet
int fd1 = open(“file.txt”); // returns 3
read(fd1, buf, 12);
int fd2 = open(“file.txt”); // returns 4
int fd3 = dup(fd2); // returns 5
0
1
2
3
4
5
offset = 12
inode =
offset = 0
inode =
fds
fd table
location = …
size = …
inode
File API (attempt 3)
int fd = open(char *path, int flag, mode_t mode)
read(int fd, void *buf, size_t nbyte)
write(int fd, void *buf, size_t nbyte)
close(int fd)
advantages:
– string names
– hierarchical
– traverse once
– different offsets precisely defined
Deleting Files
There is no system call for deleting files!
Inode (and associated file) is garbage collected when there are no references (from paths or fds)
Paths are deleted when: unlink() is called
fd’s are deleted when: close() or process quits
Links: Demonstrate
Show hard links: Both path names use same inode number
File does not disappear until all removed; cannot hard link directories
Echo “Beginning…” > file1
“ln file1 link”
“cat link”
“ls –li” to see reference count
Echo “More info…” >> file1
“mv file1 file2”
“rm file2” decreases reference count
Soft or symbolic links: Point to second path name; can softlink to dirs
“ln –s oldfile softlink”
Confusing behavior: “file does not exist”!
Confusing behavior: “cd linked_dir; cd ..; in different parent!
Summary
Using multiple types of name provides
– convenience
– efficiency
Links provide flexibility.