程序代写 CPSC 313 1

• Today’s Learning Outcomes
• Define superblock.
• Use system calls to:
• Read file system metadata

Copyright By PowCoder代写 加微信 powcoder

• Read file metadata
• Readdirectoryentries
• Code that you can use
• In the course repo (under nov13).
• Readings
• 10.6, 10.7
CPSC 313 1

Examining a File System’s Metadata
• POSIX* provides two APIs to obtain information about a (mounted) system.
• int statfs(const char *path, struct statfs *buf); • int fstatfs(int fd, struct statfs *buf);
• Returns (in the passed structure) metadata about the file system in which the object represented by path (fd) appears.
• statfs takes a file name.
• fstatfs takes the fd for an open file.
* POSIX is the standard that describes what we think of as UNIX-like operating systems (e.g., Linux)
CPSC 313 2

Struct statfs
struct statfs { __fsword_t __fsword_t fsblkcnt_t fsblkcnt_t fsblkcnt_t fsfilcnt_t fsfilcnt_t
__fsword_t
__fsword_t
__fsword_t
__fsword_t
• File system types are things like: ext2, fat, ext4, etc.
CPSC 313 3
f_namelen;
f_spare[xxx]; /* Padding bytes reserved for future use */
/* Type of filesystem (see below) */ /* Optimal transfer block size */
/* Total data blocks in filesystem */ /* Free blocks in filesystem */
/* Free blocks available to unprivileged user */ /* Total file nodes in filesystem */
/* Free file nodes in filesystem */
/* Filesystem ID */
/* Maximum length of filenames */
/* Fragment size (since Linux 2.6) */
/* Mount flags of filesystem(since Linux 2.6.36) */

Whole File System Metadata
• statfs works well if the file system is mounted, but what if I hand you a disk, how does the operating system figure out how to interpret it?
CPSC 313 4

Whole File System Metadata
• statfs works well if the file system is mounted, but what if I hand you a disk, how does the operating system figure out how to interpret it?
• A file system typically begins with a single sector that contains information (metadata) about the file system.
• We call the structure in this block a superblock.
• Many file systems will replicate the superblock many times in
different places in the file system. Why?
CPSC 313 5

EXT2 Metadata
• struct ext2_super_block • number of inodes
• number of blocks
• number of free inodes/blocks
• Ext2 breaks the disks up into groups (allows placing a file’s blocks ‘close’ to each other) — the superblock describes these groups:
• s_blocks_per_group • s_inodes_per_group • s_log_block_size

Examining a File’s metadata
• POSIX* provides two** APIs to obtain information about a file’s metadata.
• int stat(const char *restrict path, struct stat *restrict buf); • int fstat(ind fd, struct stat *buf);
• Returns (in the passed structure) the metadata for a file. • stat lets you access a file by name.
• fstat lets you access the file metadata by file descriptor.
* POSIX is the standard that describes what we think of as UNIX-like operating systems (e.g., Linux)
** Actually more than two, but several are variants of the two I’ll introduce; feel free to use man pages to explore.
CPSC 313 7

Let’s look at the stat structure
struct stat { dev_t ino_t
st_dev; st_ino; st_mode; st_nlink; st_uid; st_gid; st_rdev;
/* device inode resides on */
/* inode’s number */
/* inode protection mode */
/* number of hard links to the file */ /* user-id of owner */
/* group-id of owner */
mode_t nlink_t uid_t gid_t dev_t struct struct struct off_t quad_t u_long u_long u_long
/* device type, for special file inode */ timespec st_atimespec; /* time of last access */
timespec st_mtimespec; /* time of last data modification */ timespec st_ctimespec; /* time of last file status change */
st_size; /* file size, in bytes */
st_blocks; /* blocks allocated for file */ st_blksize;/* optimal file sys I/O ops blocksize */ st_flags; /* user defined flags for file */ st_gen; /* file generation number */

Digression
• st_size versus st_blocks
• We keep track of both the total file size as well as the number of blocks allocated to
the file. Why?
Sparse files:
• Files can have holes in them.
• Consider the following program:
int main(int argc, char *argv[]) {
int fd = open(“myfile”, O_TRUNC | O_WRONLY | O_CREAT, 0644); char c = ‘a’;
(void) write(fd, &c, 1);
(void) lseek(fd, 1024*1024*1024, SEEK_CUR);
(void) write(fd, &c, 1);
(void)close(fd);
• This file claims to be of size 1GB+2, but how many blocks did it need?
CPSC 313 9

Digression (2)
• st_size versus st_blocks
• We keep track of both the total file size as well as the number of blocks
allocated to the file. Why?
What if the last block isn’t full?
• Consider the following program:
int main(int argc, char *argv[]) {
int fd = open(“myfile”, O_TRUNC | O_WRONLY | O_CREAT, 0644);
char c = ‘a’;
(void) write(fd, &c, 1);
(void)close(fd);
• This file claims to be of size 1. Files are allocated in blocks, typically of 4096 bytes; if I don’t tell you the size, you don’t know how many bytes in that block are valid.

Long Digression (3)
• st_size versus st_blocks
• We keep track of both the total file size as well as the number of blocks
allocated to the file. Why?
3. Files consist of both data blocks and indirect blocks
• The total number of blocks allocated to a file (should) include its indirect blocks.
• Reality: The values returned in st_blocks is not the allocation size (it’s the “best performance size.”
• st_blocks is often in 512-byte units
CPSC 313 11

Reading Directories
• In modern file systems, we typically implement directories (folders) as structured files — that is we simply impose structure on top of the byte-stream abstraction that files provide.
• There are two library calls that you need to read directories: • DIR *opendir(const char *name);
• struct dirent *readdir(DIR *dirp);
• opendir opens a directory, returning a handle on which can you can call readdir to return each directory entry.
CPSC 313 12

The directory entry structure (struct dirent)
struct dirent {
ino_t d_ino;
/* file number of entry */
/* length of this record */
/* file type, see below */
/* length of string in d_name */ /* maximum name length */
__uint16_t d_reclen; __uint8_t d_type; __uint8_t d_namlen; char d_name[255 + 1];

Using opendir and readdir
#include #include #include
/* Error checking is omitted. */ int main(int argc, char *argv[]) {
DIR *dirp = opendir(argv[1]); //Check for NULL
while ((struct dirent *dp = readdir(dirp)) != NULL)
printf(“Ino: %llu\tName: %s\n”, dp->d_ino, dp->d_name);

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com