 It's a really thin crowd today. It must be either the rain or how boring Monday's lecture was. One of those two things drove people away today. So today will be more interesting, I promise. So what we're going to talk about today will start to talk about some of the challenges in implementing file systems and how things actually work on disk. So we have some idea that there are blocks of data that are stored on the disk. You could probably assume or have guessed that not all of those blocks of data are things that are stored in files. And that's what sets different file system designs apart from each other. It's just how they use the disk, where they put things, the type of data structures they use to accomplish some of the common tasks. Because as you guys have probably noticed, I mean, if you install five or six different file systems, they all feel pretty much the same. They support pretty much some of the same interfaces. And you don't really notice what's different about them. But we're going to talk today about what actually makes them different, even if the interface they provide to you as a user and to applications is pretty much identical. All right, so I think we're done grading the midterms. I think Guru has finally wrapped up the last question. So I am going to, somebody will enter the grades in today. Then we take them over to get scanned. Once they're back, you guys can pick them up. So probably Friday, actually, depends, I guess, now on how long it takes to do the scanning. Once they're available, we'll have them for you. You can come pick it up during office hours. And I'll let you know when that happens. What's that? Is there a midterm grade for the course? What do you mean? What does that even mean? Oh, I did that. Yeah, I gave you guys midterm grades. Yeah, they were just unsat. Yeah, no, they're out there. I did that. Come on, give me some credit. You didn't even check. You just assumed I hadn't done it. I'm insulting. I did that for the first time this year. Yeah, so I did. And I emailed about this, or I posted something on Piazza. I'm pointing with my little finger that needs to make. Yeah, so I did use this feature of the hub. It's very exciting. And I should say, I managed to use the feature of the hub, because at one point, I got stuck and couldn't figure out how to proceed. So the hub won again. It's way ahead of me, in terms of points. So yeah, no, there are midterm grades up. And I only use sat unsat, because that's sort of where we are in the semester. I don't want to give you guys a letter grade that's sort of meaningless, but yeah. So those are a good one. OK, yeah, cool. Cool, we're all good. Yeah, so I checked today. Max score on assignment three, currently 26. So you guys have a ways to go, as far as. Yeah, I kept putting in lower and lower filters, and I was like, really? Anyway, so apparently, this is good. Apparently, you can only get about 26 points if you submit Dumbia, which is good. OK, so any questions about files? Probably not, because you guys already know that stuff. Any questions about files? We're not really going to do any review today, because I think you guys understand about files. We're just going to plunge onward and talk about cooler stuff. OK, so just to finish up, we were talking about the other class. The last thing we finished up with was talking about why I need a tree with a root, so I can produce a unique file name. If I have this, I can't do it. I have circles. I don't know where to start. Even if I know where to start, if I cycle from the graph, I can't necessarily do it. So once I have this sort of structure, now I can actually produce a canonical file. And we distinguish between a couple of different names. So the canonical name is the name that's anchored at the root, does not contain any sim links, and identifies the file uniquely. We also have plenty of relative names. So once you start using dot and dot dot, you can create all sorts of funny names like this. And these are the types of names you guys are familiar with. If you get good at tab completion, you'll get even better at being able to construct these wild and crazy relative path names. So that's another reason to get your tab finger working. Because that's the best way to construct these. And then you can CD anywhere on the system in one command. And I just thought I'd put up the poem that I use for this example because it's cute. You guys can find this on your own. OK, so when we talk about what file systems try to accomplish, so now we know what a file is, now we know how files are named, and some of the conventions about how that works. There's a set of common goals that file systems try to accomplish, and there's a bunch of different interesting designs for achieving these things. So translating names to contents. This is something that happens all the time. Every time you open, every time you navigate through the file system, change directories, there's a constant process where the file system is being asked by the operating system, I have this string. And what do I do with it? Or the file system has to take that string and convert it to a number. And we'll talk later today about how that works through a couple of common cases. So that's one thing that the file system needs to be able to do. I need to allow files to change. So files grow, files, the names of files change. Files have content appended to them, they are destroyed. I want to be able to support these type of operations to files efficiently. That's the second goal. To some degree, there is a certain amount of attention paid to improving performance for single files. So if I think about the type of benchmarks I could write or the type of tests that would stress one file, reading the files sequentially, opening a file a bunch of times, various types of things, there are things that the file system will try to do to optimize this type of usage. You can also start to try to optimize access to multiple files. This starts to get a little more complex because I have to see relationships between multiple files in order to do this. But this is certainly something that file systems are aware of and potentially will try to do. So see patterns, see connections between multiple files, and improve the performance of access to related files. And finally, consistency and fault tolerance. So survive failures and provide a consistent view of the file system. Now, consistency and maintaining all of your data are sometimes at war with each other because sometimes in order to maintain it, the file system at a consistent state, I may need to forget about some of the things that you tried to do right when the system was in the process of crashing. But the worst thing that can happen to a file system is somehow you do something that corrupts its internal data structures and it forgets where things are. So when I was your age, I had a big, again a big 20 gigabyte drive with all my MP3s on it. I was very proud of this. It took me a long time to find all those MP3s, of course, in completely legal ways, right? Downloading music was legal in the 90s. And at some point, I accidentally overwrote some of the file system meta data structures. I didn't know what I was doing at the time and now I understand what happened. And the disk, I couldn't recover with the drive. So I bought some software online, that software said, oh, it's gonna help me find, it's gonna find all my data and I was like, this is awesome. So I ran it and it found a lot of the data on the drive. So I was pretty excited. Until I started listening to the MP3s because what I had noticed when I recovered the drive was that there were some of the MP3s had gone missing. They were gone. So maybe 95% of the files were still there but the other five weren't able to be recovered. Well, it turned out that the other five were still there. They were just in tiny little pieces sprinkled out throughout all of the other files. So you'd be listening to, I don't know, Taylor Swift and in the middle, there'd be a little step out of Britney Spears. Just a tiny little bit and then you go back. And of course, this was incredibly irritating and I eventually just deleted everything and started over. But yeah, so that is the worst possible thing that can happen. There was really nothing to do at that point. And of course, this was my fault, not the file systems but if it had been the file systems fault I would have been pretty upset. Okay, so the file systems that we're gonna talk about, as I mentioned before, support a pretty consistent feature set. There are probably some differences. A lot of times those differences involve things that you guys don't really even notice as users. Storing content and hierarchical names. These are sort of the consistent things that we associate with the file. File systems today support a whole bunch of features that you guys probably don't even notice. For example, how many people have ever used snapshots on a network file system? How many people even know that this is happening? Yeah, maybe a lot. So a lot of network file systems and a lot of certain commodity file systems will periodically record copies of your files. So if you delete something, that file is actually still there. You have to know where to find it. So it's a feature kind of similar to the Trashcan or whatever is supported on Mac and Windows but there are files that support this by default. And those files are usually hidden in special directories that you have to know where they are. All right, now despite the fact that they support this very common feature set there's a lot of differences in terms of what actually happens on disk. So how the disk blocks are used, the data structures that are used and this is the thing that sets different file systems apart from each other. When we start talking about specific file systems we'll point out these differences and talk about how they impact performance and reliability and other features that the file system is trying to provide. Okay, so broadly speaking when we start to talk about file systems you can, so remember the disk provides me essentially with an array of blocks. And there are some performance implications to how that array is laid out but you can think of the disk as just a big array of fixed size blocks of binary data. That's it. The file system to implement a file system we divide those blocks into two categories. If you took your disk and you looked at every block in it roughly those blocks fall into two groups. The first group contain file data. So these blocks contain data that you could access through the file system that's inside a file. Clearly some of the blocks have to be used for this purpose. And then there's other. And sometimes we use the term inodes for as a general term for this although inodes actually have a little bit more of a specific meaning. But then there's the inodes and the metadata blocks that the file system uses to store information that it needs to record names to record other metadata about the file and for its own internal data structures. So there are blocks of data on your disk that do not correspond to file contents. What's one way that you can potentially that you might have noticed this in the past? There's something that, you know, I'm sure you guys have done this where the box from New Egg shows up and there's this new one terabyte hard drive inside and you're really psyched and you plug it in and what do you do? What's that? Well, okay, but in order to make it usable what do you have to do? Format. And then what do you do? Then you're so excited to have a one terabyte disk and then you look at how much free space and how much free space is there? Less than one terabyte. Okay, so why is this? Well there's two reasons why this is actually. The first reason is a little bit of silliness on the part of device makers because hard disk drives are sold in thousands of bytes for some inane reason. So a one terabyte drive is actually one trillion bytes or something like that or one million one K blocks. So when you convert that to actual normal bytes that we talk about megabytes, you lose something already. But it also turns out that when you format the drive one of the things that happens is a certain number of the blocks on disk get converted from general storage into these metadata and nine nodes. And so when the disk reports capacity it's reporting the amount of storage it has available for data. And so some of the storage on the disk has been used for the file system's own internal data structures. This is one of the reasons that your file, your disk is immediately smaller and more disappointing than the disk that you bought. You're so excited about a one terabyte and you only ended up with 998 gigabytes or whatever. Still probably plenty. Okay, so, and again what makes file systems different is how they do this, right? What, how their data structures work on disk and how they recover from crashes. So this is the significant feature that we'll talk about in more detail later. This is something that, you know, the early sort of, you know, I probably characterize early stage file system design is really interested in the first two and more mature file system design is very much interested in crash recovery in fault times. So a lot of techniques for maintaining the consistency of the file system emerged a little bit later in the file system design history. So if you, now what makes this hard, right? So if you think about what a file system is actually doing, it's maintaining this big complex data structure. That data structure needs to be able to find files. It needs to be able to allow files to expand, to shrink, and that data structure is located on disk. That disk is unreliable, that disk sometimes behaves in ways that the file system doesn't quite understand. And the hard part about this is partly because updating, making changes to the file system usually requires updating a bunch of different structures. So let's talk our way through an example white operation. So let's say I want to append some data to the end of a file. I have a chunk of data, you've made a right system call, that right system call eventually is bounced down into a file system implementation. What are some of the things that the file system has to do in order to complete this right? Got one K of data I'm appending to the end of the file. What is one thing the file system has to do? Well, okay, the first thing I need to do is find a block. I need an available block on the disk to store your information, that much is pretty simple. So I need to find that block, how am I gonna do that? Well, that requires probably accessing some data structure stored somewhere else on the disk. Now, actually what Isaac said comes in two parts. So now I have to associate that block where the new data is with the rest of the file, which may or may not be anywhere close to where that block is. Who knows? I have to adjust the size of the file because when the right completes, the metadata associated with the file should reflect the fact that the file is bigger. I actually have to put data into that block. That's important in order for the right to finish. Now from the perspective of the process, all this stuff needs to happen synchronously. When the right completes, all of these changes should be made. There should be fewer free data blocks on the file system. The file that I wrote to should have some new data associated with it. The file size should be updated. But doing all these things takes multiple, involves writing or reading data that's located in multiple spots on the disk. And so in reality, there's a bunch of things that have to happen sort of atomically here. And that creates two problems. The first, which we'll talk about a little bit later, is of course this problem with consistency, where if I get interrupted in the middle of this, it's possible that I've left the file system in an inconsistent state, and there's something wrong. The file size doesn't match the amount of data. There's some blocks hanging out in the file system that don't belong to a file. It's sort of hanging out, marked as used, but not actually associated with any file. I don't want to do that. I want to use the entire capacity of the disk. There's also a performance issue here, because doing this requires now potentially visiting and updating multiple locations on the disk. And so with the spinning disk, that means that my head's gonna bounce around from here to there, and this is gonna be potentially slow. So this is, in a nutshell, what makes file system design difficult, and also really interesting, is trying to optimize on disk layout and the usage of the disk, both to improve performance and to maintain consistency when things go wrong. Okay, so let's start looking actually at some on-disk data structures, and today we're gonna talk about how we translate names, so how we take a name, and we find the block or blocks on disk that store the content and other information associated with this name. So that's a, as I mentioned before, this is something that the file system is doing repeatedly all the time. So once we find some information about the file, we're actually, of course, gonna want to find all the data blocks associated with the file, and we'll talk about how those are organized, and we'll talk a little bit about how iNodes and other on-disk data structures are allocated. So when I'm using examples today, I'm gonna be drawing them from EXT4, which is the, I think, still most up-to-date Linux file system that's what's used in your virtual machine and by default. And this is a nice example of a fairly mature, but also fairly straightforward file system that we can look at. Okay, so some terminology here. A sector is the smallest amount of, the smallest unit that the disk will allow you to write. So a disk has a smallest amount of data. You can't write a byte. You have to write 256 bytes together. If you want to modify one byte, you have to read those bytes, change one, and write it back. This is just a standard feature of disks. However, the file system usually will not write amounts that small. Usually the file system will pick a larger amount that's a multiple of the sector size. We'll call this a block. So this is the smallest amount that the file system will actually write, even if the disk would allow it to write smaller units. And finally, modern file systems, as disks have gotten really big, have introduced this idea of an extent. So an extent is an even bigger chunk of contiguous blocks on disk. So blocks that are right next to each other, whether on the same track or on neighboring tracks, that are used to store content for one file. So frequently now when I create a new file on disk, I allocate a bunch of contiguous space on the drive to store contents that might be associated with that file. So the first question is, why would the file system probably want to avoid writing small chunks of data? Why would I pick, now again, I mean, this sounds awesome. I have all these teeny little 256 byte blocks. They're so cute, right? I've got so many of them, it's awesome. Why wouldn't I take advantage of the ability to write these small amounts of data? Why would a file system choose a block size that in this case is 16 times larger or maybe eight times larger than the sector size? Well, okay, so all this is to make things faster, right? But how, right? Why does that make things faster? Yeah, so remember, or maybe I haven't pointed this out before, contiguous writes are good. Once I've moved the heads to a particular spot on the disk and I've paid that whole latency cost to get the heads there, I wanna write a bunch of stuff. I'm there, I'm hanging out, I'm on this track, the track is spinning around. It's faster to move to nearby tracks than it is to jump all the way across the disk. So I don't wanna write tiny little pieces because if I write tiny little pieces, there's even a big chance those pieces are gonna get scattered all over the disk, which I don't want. And that's the same motivation for extents. So blocks were essentially this earlier idea where I would use something like 4K. Now, why 4K? I mean, the answer's up on the slide. But when I put 4K up there immediately, little red light should have gone off in your head. What is 4K? Yeah, the page size. And when we talk about file system caching, it's also gonna be pretty convenient to use 4K as our block size because it means that a page in the cache now is written to a single place on disk. So if I use a single page to cache file contents, I can write that into one location on disk, which is nice, as opposed to 16 or eight. Extents really motivated by the same reason. Contiguous reads and writes are good and jumping all over the disk is bad. And as files have gotten bigger, file systems have responded by saying, hey, let's just allocate bigger chunks altogether. There's maybe a little bit of a capacity trade-off because I may not fill the extent with data from the file, but it's still probably worth it. Discs are pretty big. Okay, so for EXD4, I have one inode profile. That inode is 256 bytes. And so I store 16 in a block. Actually, did I say, ah, sorry. The sector size that EXD4 uses is actually 512. So I can store two of these in a sector or I store 16 per 4K block. The inode contains, the inode is designed to contain all of the metadata information about the file, that the file system needs to modify it, properties of the file that I might be interested in, and other such things. So the inode has to allow me to find the rest of the file. So starting from the inode, I should be able to find out where all the other data for the file is. Clearly it's not in the inode, the inode is only 256 bytes. The inode contains metadata like permissions, and also timestamps. So creation time, modified time, other types of things. So this is all stored in the inode, and again there's one inode per file. Like everything on your computer, inodes are named and organized by number. So there's no name in the inode. The inode on this system has a number. So here is an example of using, this is something that you guys can try at home, using a tool called debugfs. What I'm doing here is I'm asking it to tell me about inode number two for the file system that's mounted on this device. So this is inside, this was an EC2 virtual machine. So inode number two tells me it's a directory, which we're gonna talk more about in a minute. It gives me information about the mode. So these are the permissions associated with the directory. Who's good with their octal modes? Who can tell me what this is? Oh, Doug, no, no, no, no, no, you. Somebody from this year. Oh, come on, seven, five, five. Yeah. Really? Man, you guys gotta put the unit's bootcamp here. Yeah. What's that? Nope, seven, five, five is not a user. It is most definitely not a user. Yeah. Yep. Yep. Right, so seven indicates that the user can, the user who owns the file can read, write, and execute it. Read is four, write is two, execute is one. Five indicates that the other users in the same group can read, read is four, and execute. What does it mean to execute a directory? Who knows? Directories are not executable. So how have I overloaded this bit? Yeah. It means I can list the contents of the directory. So a seven, five, five directory, any user can list the contents. So five is for other. So ignore the top zero, that's for sort of special flags. The bottom three octal nibbles here describe the permissions for the user who owns the file, for other users in the same group, and then for everybody else. So everybody else is allowed to read and list the contents of this directory, which is good in this case. And we'll talk about why that is later, because this is an important directory to be able to read the contents. Okay, so the user and group zero and zero. Again, whose sysadmin hand is very dirty? You can tell me, who is user zero? Root, it's group zero, wheel. So this is the root, this directory is owned by the root user. The size of the directory here is what? 4K, right, one block. So I've only allocated one block to this particular directory. There's some other set of information and then here are all these timestamps that are associated with the directory. And I'm going to admit that I cannot remember what these mean without checking Google. One of them, you'd be tempted to say, oh, it's the creation time, it's the access time and the modification time, and you'd be almost right, except one of them is not the creation time. And it'll always throw you off. Yeah, so I think the C time, I think this is actually the creation time. This is January 8th, Sunday, 2012. And then down here, it's telling me blocks, right? So remember, from the inode, I need to be able to find all of the other blocks that store the data associated with this file. Now again, in this case, this file is a directory, but don't let that confuse you because as we'll point out, minute directories are just special types of files. So there is one block, data block associated with this file, and this gives me the index of that block. So by finding the inode, not only can I find out a lot of information about the file, but I can find where the file is stored on disk. Any questions about this? Okay. So now the question is, how do I find this data structure? So clearly, once I get to this data structure, I'm good. If I can find this block on disk, I'm in good shape. I can find the rest of the information about the file. So it turns out that for EXT4 and similar file systems, I need to be able to start somewhere. And so what EXT4 does is when you format the file system, it creates all the inodes that that file system is ever going to have. And it stores them at well-known locations. So without any other information, or just by reading a small amount of information that's always stored at the same place on the disk, the EXT4 file system can map every inode number to the inode location on disk. This is part of the storage capacity of the drive that you lose when you format it. So when you format a drive using the EXT4, some amount of it is reserved for inodes. So this is what your drive might look like after you format it. There are some inodes here, I've allocated eight of them and the rest of the drive is set aside for actual data. Some amount of capacity is gone. So what are some consequences of this fact? So I create all the inodes at format time and remember there's one inode per file. Yeah, what's that? Oh yeah, no, of course, yeah. If you blow away inodes, you're gone, right? It's just, it's not good. But that's true of most things on disks, to be honest with you. Well, actually, I guess that's, yeah. If you fired a random byte of data at the disk and you hit a metadata data structure, you better hope you hit a timestamp because otherwise you're in trouble. I mean, most of this stuff's pretty important. But what else? All the inodes are created at format time. They're all put there on the disk, yeah. Yeah, so, well, there's two consequences. One is that I can run out of inodes. This actually happened to me once. I had a file system that had a lot of very small files and it turned out that I ran out of inodes before I ran out of data blocks because when you format the disk, the file system has to make a guess about the average file size because it's gonna say, okay, I've got 16 gigabytes of disk space here. How many inodes do I need? And so the file, when you format, you can actually specify this as a parameter. So I don't remember, okay, there it is. The XD4 creates one inode per 16K of data blocks. So if your average file size is a lot smaller than 16K, you're gonna run out of inodes and the disk will report being full. It's not full. It's really irritating. It'll say the disk is full and you'll run your handy DF command and it'll say 50% of it's free. And you'll start scratching your head, but then you'll remember that we had this conversation and you'll run DF-I, which gives you the number of free inodes and you'll see it's zero. And then you'll be in a lot of trouble, actually, because there's really nothing to do at that point. So yeah, so you can run out of inodes before you run out of file contents. The other consequence for how we use the disk is that the inodes are not necessarily going to be close to the contents of the files that they're describing. Remember, the inodes are all of these fixed locations throughout the disk. So in my little diagram, I put them all here. Now, as disks get bigger and bigger, would it still make sense to have all the inodes at the beginning of the disk? No. So what EXD4 actually does is it puts inodes, it puts groups of inodes at various points throughout the drive. It takes the big drive, it sort of carves it up into little mini drives, and then each mini drive has a group of inodes. And I think it tries to use inodes for, it tries to match up the data blocks with the inodes that are close by. But I don't think it's required to do that. It can potentially use an inode close to the beginning of the disk with data blocks that are at the end. Of course, the performance of that file is gonna be potentially problematic. Okay, so now let's come back to talking about directories. You guys might think Howard Directory is implemented, and I just showed you some information about an inode that actually belongs to a directory. So file systems implement directories as just a special kind of file. In a lot of ways, there's nothing different about how directories are named. And there's a special bit in the inode that allows me to tell if this inode, if this inode is a directory. But other than that, directories are just files, except for the fact that the file system maintains the contents of that directory in a way, as its own sort of separate data structure. So the data blocks associated with the directory make up a data structure that allows the file system to map names to inode numbers. So let's talk about how this works. So here is, here's me, so here's a command that will allow you to list the inode numbers of a particular file or directory. So ls-i, here I'm just doing this for the root directory, and it prints out root and two. Why two? I don't know, actually. It's just a magic number. I think it used to be zero, and then maybe EXT3 used one, and so they used two. We'll talk about this in a minute, but there's always a well-known, hard-coded inode number for the root directory of the file system. This is important because I need somewhere to start when I start translating paths, right? So I have to, the file system needs to know what the inode number of root is. From that point, it can bootstrap itself and I can map other types of names. So now let's look at the contents of root. So here's the root directory on a pretty typical Linux system, and this data structure inside the directory is mapping names, bin, to numbers. So it says, inside this, there is a name called bin, and if you wanna know more about bin, check out inode number 131,073. Why is it nice, sorry, question? Sure. Yeah, I mean, I know it's consumed directories just like files. Yeah, so that's a great question. If I created a file system, like you create like a huge file system of 10 thousands of directors, right? Maybe you could do this as some sort of conceptual art project, right? And you could have a computer with like a million directories and nothing in them, right? Maybe you could all have the same name, right? That'd be kind of weird. And people could sort of play with the system and they could, no matter where you go, there's nothing. Anyway, I know it's like a statement about modern life or something. What's that? Every path is equal. Yeah, yeah. Yeah, just like AAA or something, I don't know. So yeah, if you create a lot of directories, you can run out of bin. The directories do have binos as well. That's a good question. So, but why is it nice to allow directories to be like files? This means directories can grow, they can shrink. I can move directories from place to place. Why is it nice to sort of reuse some of these features for directories? Why do I need to? Why can't I have every directory just be a fixed size data structure? Why wouldn't that work? Yeah. Yeah, I mean, essentially if I have a fixed size, then I have a fixed size for this data structure, and so you might try to create a new sub directory and it would say, sorry, I'm full. And of course, that's not how things work. So directories can get arbitrarily large. Now, if you've ever, you know, you can try this at home. If you look, what is the size that LS reports for directories for most of the directories that you've seen in your life? If you guys ever notice when you do an LS, it'll tell you a size for the directory. What's the size that it reports? Anybody want to guess? Yeah. 4k. And that's because there's one block set up for that directory by default. Now, if you take a directory and you put lots and lots and lots and lots and lots of files inside of it, what you'll see is that size will actually start to grow because the data structure that's required to map all those names to numbers has gotten big enough that it's larger than 4k and the file system has started to allocate extra blocks to that directory. So yeah, you can do this at home. Okay, so now I can see here how I've, this is one particular directory and then here I've done this for a subdirectory of root and it's doing the same thing. It tells me that here is there are two directories in here. One is my home directory, the other is the home directory for some Ubuntu user. I don't know why that's there. And here are the I know numbers. And actually, I should back up. All the directory does is names to I know numbers. So it doesn't say anything about what these things actually are. It just says there is a name called Ubuntu. If you wanna find out more, go to inode 394656. Okay, so yeah, so we already talked about this, right? So going back to stat two, you can see this is a directory. Any questions about directories implemented as files? Yeah, no, no, so okay, that's a great question. The root directory, I don't know if the root directory has to be in the same location on the disk. The convention is that the I know number for the root directory is fixed. So let me go through an example. I think they'll make that clear. Okay, well, I'll come back to this, right? So let's say I wanna open a file. So this is one of the things that file systems have to be able to do, right? I have to be able to translate this path to a number. And specifically now, you guys know that what I want is I want an I know number so that I can find out more about this file or directory potentially and figure out what's in there, okay? So I've given open a path and what I need to do is translate this string to an I know number. Here's where it's critical that the root I know is fixed because if it's not fixed, I don't really know where to start. So I have to have a starting point so I can bootstrap the process. So to translate the root, there's no directory above root so there's no directory to look for the root entry in. Instead, I use a convention where it's fixed to be summed up. Does that make sense? This is how I start. So now I start at root and I open up inode two and I know two is a directory, it's the root directory and I interpret the contents of it and I look for ETC. And let's say that ETC exists and I find out that the I know number corresponding to it is whatever, what's the next thing I do, okay? So now I load the inode for 393218. I found out that this is also a directory. Now this could fail at any point, right? I didn't say that this path had to be valid. It turns out it is valid and it is a file but if at some point, like for example, maybe ETC default is a file, not a directory. So what would happen is I would get here and I would try to continue to translate the path and I would realize, oh, I've hit a file and this would fail. So in this case, I find default, default has its own I know number and then I go and I just continue this process. I get an I know number, I load the directory corresponding that, I use that to map the next component of the path name to an I know number and I continue until either I'm finished and I've consumed the entire path or I have an error occurs and I can't continue. There's a missing name or the name is in a directory or whatever and I just keep going. Questions about this? So what does this mean about I know number two? How often is I know number two used? Like a lot, yeah. So this would be a great structure to cache someone, yeah. Oh no, I can cache anything here and I can cache any part of this process. So it's possible that at any point when I'm doing this, what I find is that the file system cache is returning contents rather than going to disk. No, no. I mean, did you see those I know numbers? Where is this? So lost and found maybe, but I think that's a bogus I know number. I think that's made up because lost and found might be a bogus directory. But home, do you think this is a well-known agreed upon I know number? If so, it's weird. I wouldn't use 39321, I would use like two, like three. What's that? Three is dev, yeah. So PROC is one, right? Well, okay, so it looks like I have a problem here. PROC and Sys had the same I know number. What's that? That's lost and found it. Yeah, and that's because PROC and Sys are both are not real files. They're pseudo files that are provided by the OS. So it doesn't matter. If I try to open something in PROC, EXT4 is not involved anymore. So it just gets out of the way. So it doesn't matter. So I wanna go back and show you a little bit about how I can print out information about an EXT4 file system. So this is a tool that reads information from a part of the disk that's known as the super block. So the super block is a data structure that's read by the file system initially and contains sort of all of the information required to interpret the file system. So for example, the locations of the inode, the blocks of inodes would be stored in the super block. So this gives me where this file system is mounted on. This is a root file system. It's a magic number that identifies it as an EXT4 file system. It says it's clean. That's nice. It's shiny and new. That's not what it means. We'll come back to that. It gives me a inode count and a block count. So this is the number of inodes that have been created on the system and the number of data blocks as well. It tells me how many data blocks are free and how many inodes are free. It tells me the block size. Okay, so blocks per group. So you remember before I said that EXT4 divides the file system into smaller chunks? Each chunk has its own inodes. So this is the number of blocks in each group, the number of inodes in each group. Some information about how many times it's been mounted, the maximum mount count before the file system will run some internal consistency checks to make sure that everything is okay. And then on page two, there's actually a lot of information here. I would encourage you guys to run this yourself. It's kind of cool. The number of writes that have gone onto this file system in its entire lifetime, that's kind of cool, right? And then, so down here, and this goes on for a while, this is actually information about each block, sort of each part of the disk. So group, or sorry, each group, right? So each group, this is group zero. Here's where the block bitmap is. That's the data structure I used to allocate data blocks until which data blocks are free. It tells me where the inode bitmap is. That's the data structure I used to allocate inodes. It tells me where the inode table is. That's the actual array of inodes on the disk. And then it gives me information about this particular group. So in this case, you can see that there are no inodes that are free in this part of the disk. However, notice that there are still free blocks. So this particular group has run out of inodes, despite the fact that there's still blocks that are free. Yeah. What's that? The tree data, there has been no tree data structure that we have talked about yet, but we'll get there. Yeah, I mean, again, there's other ways to do this, right? Like, you could set up fancy trees and other sort of cool data structures that you talked about in your algorithms class or in data structures class, and you could apply them to file system design and people have done that. And it turns out that sometimes these easy things are the things that are easiest to get right. For example, having inodes that fix locations on disk is kind of nice. Makes certain parts of the file system pretty easy to build. Okay, so we did this. So now, let's say that I'm actually trying to modify, I don't think we're gonna get through this today, but I'll just sort of introduce this problem. So this is the next problem, which is we've talked now about how file systems map names to I know numbers. Once I have the I know number, then I can find out all the information about the file I need to know. The other challenge is translating the offset within the file to a data block. So let's say this read wants to write some data to a file handle at a particular offset. I need to be able to find any byte within the file, right? Any range of bytes within the file. If you give me a file name or an I know number, in this case, if you've already done the translation, and you say give me byte 62, I need to be able to do that. And so this is the next thing that we'll talk about and we will start up with this on Friday. I'll see you then.