 So today we're gonna keep talking about file systems and I'm still in the front of the room where I usually am. Yeah I'm up here again. I'm sorry it's so nice outside. It's just like a tough time of year for you guys, right? It's like it's getting nicer outside. It's not as much fun to be inside hacking on your really boring OS assignments but it is nicer outside so my suggestion is just finish as fast as you can, right? I can definitely predict what's gonna happen outside which is that it's gonna keep being nice. Okay so today we're gonna talk, we're gonna finish talking sort of about core file system data structures. Next time we'll talk a little bit about file system caching on Wednesday and then we're gonna start sort of mixing in for the rest of the semester some research papers about various types of computer systems. So we'll talk, we'll read some file system related papers, we'll read some papers about sort of random other stuff as we go on, sort of up to my discretion. If there's anything you guys want to learn about through the rest. So once we get through file systems it doesn't take too much longer talking about them at a very high level then we're sort of into a grab bag and there's a lot of different things that we can talk about so if you guys have ideas I know there's more interest in sort of OS containers now because people are, how many people have used Docker before? I have no idea what Docker is. Okay so that would be kind of fun to talk about. We'll definitely talk about virtualization, we'll have a couple lectures on virtualization I think that's pretty important but if you guys have ideas about things you want to know about I'll put up a discourse right and you guys can, we can happy to add things, remove things, some of the lectures just sort of boring out of date. Alright so please get started on assignment 3.2. Assignment 3.2 is significantly harder than assignment 3.1. How many people are at least on their way with assignment 3.2? Done, they're sort of semi working. Okay cool great. Good but if you haven't gotten there please get moving. For, I might as well say this now, for assignment 3.2 and 3.3 we will provide late credit. It'll be sort of on the order of what we did for assignment 2. So any questions? Logistics? These are coming to a close like, what is it? One more week for assignment 3.2 and then two weeks for assignment 3.3 when they're done and they say XAM, it's May, weather's even nicer. Okay alright so last time when we wrapped up we were talking about EXT-4 I-notes so we'll sort of get, get right into it kind of where we left off. So what's an I-node? I-node, it's like then like an iPod, like an iMac, what's an I-node? Let's be more specific than that. There were a couple of good words in that answer that I like. No an I-node is typically considered a general file system data structure but what is it? Like what does it contain? Remember file system, disk, array of blocks, 256 bytes, 512 bytes, 1k, whatever. File system built on top of that has to add all of these features like files, like names, like growing and shrinking things. So what is an I-node? Yeah. Yeah so an I-node you can think of as a bunch of different, it's a data structure, it's a core data structure that the file system uses internally that represents certain information about one file. So we talked about last time there are other file system data structures that the file system needs to maintain that are not I-nodes. So what's an example, can anyone remember, an example of a file system data structure that's not an I-node? So what else does the file system have to know about the disk blocks that it's managing? What's one sort of core piece of information that I might, the file system needs to know, needs to maintain information about these disk blocks. What's one of the pieces of information I need to know? Simple. Something you guys maintain in your core map, I hope, while you have to, I think. Yeah, like a free map, right? So information about whether blocks on disk are currently allocated as part of the files themselves or as part of other file system data structures or whether or not those blocks are free. That's not what we're talking about. So something called, usually called the free block bitmap. We're talking about an I-node. So there's one I-node for file, as we hope, because I-node contains all the information about the file. The I-nodes in the XC4 are 256 bytes. This is another data structure that we want to do a little bit of work to try to keep as compact as possible. Because the larger the I-nodes are, remember, the I-nodes and some of the data structures we're talking about are all wasted space on disk. They're parts of their disk blocks that take up space that cannot be used for file content. Users typically don't care about those as long as the rest of the file system works. So we try to keep these fairly small. Whoa, whoa, whoa, slow down there. All right, so here's some of the information that was in, and here's an example. So if you have your Ubuntu VM, you can install, I don't know if DebugFS comes by default, but you can install it with apt-get. This is a fun tool you can use to poke around your system. So what this command does is it tells me to pronounce some information about I-node number two, and it's pulling data from the file system that's mounted on this particular device. And so every I-node has a number. We're going to come back to that when we talk about how we do path name translation. There are two types of quote-unquote file for EXD4. There are normal files and directories. So directories are just files, and again we'll come back and talk about that more today. And this has a bunch of information about the timestamps associated with it and a list of blocks. So these are actual data blocks on disk that store the content of this quote-unquote file, despite the fact that the file is a directory. So you might think about what content a directory would be expected to store. Okay, so I-nodes are numbered. Data blocks are also numbered. How does the file system translate I-node numbers into a location of an I-node? And this is something that we'll come back to later. So it's frequently required for the file system to be able to look up information for a particular I-node. That's essentially what I just did right here with this command. How do I locate an I-node? How does EXD4 locate an I-node? Whoa, sorry. I don't know what's going on with this today. Somebody has hacked into my pointer system. How do I locate I-nodes? How does EXD4 do it? You guys would really rather be outside, wouldn't you? Is that what you guys are doing? You're looking at your laptops? It's like a live feed of, like, outdoor UB. Sunshine. It's warmer outside than it is in here. Okay, perk up. Let's go. How do I do this? Just think about your design in this. What's one simple way to do this? Yeah. Index into some array somewhere, right? Yikes. Jeez. Relax. Okay. Yeah, so on EXD4, all the I-nodes that the system will ever have are created when you format the drive. That's one source of lost space is these banks of I-nodes. And EXD4 puts them in specific places. So there are parts of the disk where, if you pulled blocks from the disk, what you would find is those blocks contain data for arrays of I-nodes. Remember, the I-node certificate is six bytes. The block size that EXD4 uses is 4K. And so 4K block contains, can contain like 16 I-nodes. So what are some interesting consequences of this? So on some level, this is nice, right? Because if I know where I put these blocks of I-nodes, and that's one of the other things that gets written to the disk when I format it, it's the location of all the banks of I-nodes. You can think of them that way. So that's nice. It makes it easier to look up. But what else does, what is another implication of this? Yeah. Yeah, so that's a great point. So there's specific parts of the disk that are sort of more valuable than other parts. So for example, if one of the blocks that I-nodes are sitting on goes bad, I may suddenly lose a bunch of files. Because they're just going to vanish. Their I-nodes are corrupted. And so I'm not going to be able to find them anymore. The other interesting thing is that I-nodes may not be located near file contents. An I-node and the contents of a file are two. The I-nodes and the data blocks for a file, hold on a second, are frequently accessed together. But because of how EXT4 lays things out, those accesses may require seeks between two different parts of the disk. Yeah. Yeah, so the lookups are very easy, right? Yeah. So the nice, the reason why EXT4 does this is it makes it very, very simple to take an I-node number and convert it to a disk block in an offset in order to find it. That's very simple. This also means that there's a fixed number of I-nodes for the system. And I think we talked a little bit about this last time. So at format time, I choose the number of I-nodes of the system. If I run out of I-nodes, I can't add new files to the file system, regardless of how many data blocks are available. So this is a sort of a configuration parameter that I have to choose carefully. This may be different now. So at the time that I wrote this slide, EXT4 was by default creating one I-node per 16K of disk space. So it's making an assumption about the average file size that I'm going to see over time. And this may, this may be different now because files are, may have gotten bigger. Yeah. Okay, good question. So why can't I have a dynamic number of I-nodes? I mean, first of all, can I have a dynamic number of I-nodes? Like in the world, right? If you, can you write a file system that has a dynamic number of I-nodes? Absolutely. What becomes trickier if I have a dynamic number of I-nodes? Yeah. Yeah, I can, why can you, you can imagine I can add little arrays here and there. Actually, well, come back to that because the picture I put up before is a little bit misleading because EXT4 doesn't actually put all the I-nodes in one place. It puts them in these groups, right? This is just a design decision for EXT4. There's no, who asked the question? Yeah, yeah, there's no real reason. There's no technical limitation. As you point out, I can certainly write a file system that doesn't have this problem, right? This is just how EXT4 chooses to do things. Okay, so, so what's a directory? Yeah, sorry. Yeah, when we come back to caching on Wednesday, yeah. I-nodes are typically data structures that are very, very heavily cached, right? So if you look, and I'm not sure that's done by design or it just happens naturally, right? Because as soon as I touch an I-node, I pull the entire block into the cache, that block actually has a bunch of other I-nodes on it. And as long as I'm touching that frequently, those blocks are going to stay in the cache. Yeah, but absolutely. One way to reduce the number of seek times and improve disperformance in general is by using memory as a cache. We're going to come back and talk about that in one sec. And one day part, so caching file system data structures can be very beneficial. Now, there's some, there's some drawbacks associated with that, particularly with consistency, but we'll come back to that and talk about it more. So, directory on EXT4 are just special types of files. They're not really treated any differently. You can't edit their contents in the normal way. You can't open them with your file editor and edit their contents. Their contents are modified in different ways, but EXT4 kind of uses this concept of a file to store directory information. So you can think of directories as a file that has a special structure to it. So based on this, so I ran this sort of funky LS command. What is the directory actually store? So this is asking me to list out the directory root. So root directory of the file system. And the dash i option tells me to print iNo numbers for all the contents of root. So based on this, what would you guess is the structure of a directory file? What is the directory designed to do? For each entry, I see two pieces of information. What are the two pieces of information? So here's an example for home. 393219 home. What are the two pieces of information that the directories maintain? Yeah. So it's an iNo number, that's this guy and a name. So a directory is just a special file that maps names to iNo numbers. And the nice thing about, I mean, has anyone noticed how large are most directories on the file systems you guys use? If you guys do an LS-L, usually directories show up as how big. Anyone know? Especially 4k. Why is it 4k? One data block. File system data block size is 4k. So the smallest directory can be is 4k. Yeah. Ah, hold on, we'll come back to that. Yeah, good question. Good eye though. Yeah, there's something weird about this, right? Yeah, so and the nice, but has anyone seen a directory that's larger than 4k before? Those exist. You can actually have this happen. The directory is just a normal file. So once the mapping between name and iNo number gets too big, or once I have too many of them for a 4k file, I just add more contents to it. So you can think of it as just a data structure that can grow in size like the rest of the files, but these files have a special format to them. And again, you can't open it up in a text editor and start messing around in it. You know, the file system itself modifies these files in very well defined ways when you move and create files, files and directories. Okay, good question. So what's going on here? I've got proc and sys that have both have iNo number one. Weird. That seems like it's wrong. How can two separate files have the same iNo number? No? Yeah. They're not mount points either. Proc and sys. So remember, what's the lowest iNo number? What's the root iNo number? Zero, I think, is reserved and never given out. One is also maybe then special. If I start with two, I mean, you can see that I have three. Three is dev, right? I don't know where four is. Four is probably inside dev. I've gotten 11. That may also be special. That's that lost and found directory that we talked about. That's there too. The rest of these are kind of much larger. I mean, I suspect that these are being given out in the order they were created. VM Linux is pretty small, right? That's one of the first files that's created on the system. That's the actual compressed Linux kernel that's sitting there. It's special about one. Yeah, these are these pseudo file systems. Remember, we talked about proc. How proc is something that looks like a file system. It is actually being maintained by the kernel. So you can go in there, you can CD around, but the information in proc is not stored on disk anywhere. sys is the same way. So sys and proc. proc is a way that the kernel exposes information to user processes through a file system like abstraction. sys is a way that the kernel exposes controls to processes. So if you start poking around in sys, you'll find ways to like turn your Wi-Fi on and off if you have the correct permissions. There's a file in sys, where if you write a zero into it, like the computer, like if you write a one into it, the computer will go to sleep, right? I'm serious. You can try this at home. Actually, I did that once, I think it was kind of fun. And like if you write a zero into a certain file, the Wi-Fi will turn off, or the screen will turn off, right? And so this is an interesting way of having the kernel be able to expose this big control surface that processes can then use, again, with the appropriate permissions. You don't want people to be able to go into Timberlake and like, hey, let's reboot. But yeah, there's a bunch of different functionality that's exposed through sys, but it's in many ways very similar to proc. You can both read from it, but unlike proc, where most of it is read-only, sys has a bunch of files that are writable, assuming, again, you have the correct permissions. Okay. So file system names are INO numbers, and directories are this way to map human readable names, the names you guys use, to the INO numbers that the file system wants to use. So this is our directory. Okay, we already saw that. Yeah, so debugFS will print just a small aside, a bunch of different sort of interesting things. So this is this, so there's this other file system data structure, it's called the superblock. And the superblock kind of is what it sounds like. It contains a bunch of interesting metadata about the entire file system. So for example, one of the things that the superblock contains is the location of all the different metadata that's on all the different other file system data structures. So this is the second page of the information about the superblock on this particular drive. And you'll see that it stores information about where the INODE table is. Remember the block bitmap? That's the bitmap that stores what blocks are in use in this particular part of the disk. What do you think the INODE bitmap is? If the block bitmap stores information about whether blocks are free or used, what is the INODE bitmap store? Yeah, the free or busy for the INODE it's themselves, right? So this, for this particular, now again, we'll come back to the group thing. So for this particular disk, it tells me there's a block bitmap at block 513. There's an INODE bitmap at block 529. The INODE table is block 545. For this particular part of the disk, there are about 18,000 free blocks, no free INODES, and 703 used directories, and no unused INODES. So, and again, you can look through this and just, you know, tells me let's see here. The block size is here, it's 4k, the number of blocks per group. So this is kind of interesting. So what is the, anybody know what the groups are here? So I can see group zero, and that has some of the data structures that we've been talking about the entire disk having, but then I see group one, and actually if you looked at the rest of the output, you would see group two, group three, there's like 16 or 32, I can't remember how many. What are these? Well, so this group one looks very similar to group zero, right? It has the location of a block bitmap, an INODE bitmap, an INODE table. EXT4 divides the disk into smaller pieces and then creates data structures for each one of them. So this stores information about one part of the disk, the next group stores information about another part of the disk. It does this partly to distribute the information about some of the data structures throughout the disk, so they're not all in the same place. All right. Yeah, that is a great question and I do not know. Yeah, no clue. Free INODE and unused INODE. Luckily they're both the same here. If you ran this and put it off, I bet you could figure it out. If we found one that actually had them, the numbers weren't the same. Okay, so now let's talk about path name translation. I think at this point you guys understand the core data structures that are required to translate a path. Okay, now when you open a file, you provide a name. What does the file system have to do and actually open this file and return the contents? What's the first thing I have to do? You call open, I pass open to VFS open. What is the file system have to do? Yeah. Yeah, so it has to translate something to something. That's to translate this name into what? A block on disk yet. An INODE number. File system thinks in INODE. The file system has everything named very nicely in terms of INODE numbers. The human readable names you use are not part of its naming scheme. So it has to translate this for... It has to translate this. Once it finds the INODE number, then I can locate the data structure associated with the file. That data structure has pointers to all the data blocks. We're going to talk about that later today. So once I find the INODE number, I'm good. But the first thing I have to do is look up this path. So here's how we do this. You guys might have sort of glommed on to this based on some of the earlier slides. So I have to bootstrap this process somehow. So the file system needs to know the INODE number for the root directory. This is why this is usually hard-coded. So root on EXT4 is 2. So I start with 2. Then what do I do? There's an iterative algorithm here. So I know the INODE number for the root directory. Therefore I can locate and load the contents for the root directory. Then what do I do? It's the next step. Okay, so how do I get the INODE number for ETC? How do I do that? I know root. I can find the root directory. How do I find the INODE number for ETC? That is the next step. Yeah, exactly. I open that directory. I read the directory contents. The directory contents are a series of mappings between name and number. And so I look up ETC in that mapping. It's possible that ETC does not exist in that mapping, in which case what do I do? It's a bad path. I mean path name translation can fail anywhere. So it's possible that I fact-fingered it and I gave you ECT instead of ETC or something like that. So it's possible I can just fail. I can say and at that point the file system knows that this is an invalid path because there's no way for there to be anything anchored off a non-existent directory. Okay, so I open that directory. I look for ETC. So now let's say the ETC is INODE number. I think this is actually drawn from the slides 39,000, 39,000, 2,000, 18. So now what do I do? What's the next step? How do I ratchet forward? Yeah, so now I open. Now okay, so I have an INODE number. Now in order to continue translating this path, what has to be true about that INODE? I'm trying to open this. It should be a directory, right? So that's the first thing. If this is a normal file, I have to stop and fail because I know that I want to keep going. I need to, there's another slash and so I need to keep walking this path. If this isn't a directory I fail. So if ETC is a directory then what do I do? Yeah, then I look for default, exactly. I just continue this process. So open, you know, take the INODE I'm starting with at that particular point, make sure it points to a directory, open the directory, use that directory to translate the next part of the path, find a new INODE number and repeat this process until I get to the end. And at some point where this journey is going to lead me is either to failure somewhere along the way, either because I, you know, I can fail because something's not a directory, I can fail because the directory doesn't translate the next part of the name that I need to translate. But if all goes well, what I do is I find my way to an INODE number and the INODE number refers to the file that I want to translate. Yeah, what about dot and dot dot? Ah, great question. How do you think those work? Yeah, yeah, dot I actually think can be, well so, so the interesting thing about dot and dot dot is dot and dot dot can be, so if I take your current working directory and I add any path to it with an arbitrary number of dots and dot dots, assuming that path is valid, I can actually condense that path down to what's referred to as a canonical path that contains no dots or dot dots in it. This may be a little confusing because you guys are used to going like cd dot dot slash dot dot slash dot dot and you're like how would the file system know where that path is? But that's not what, you know, that's not what gets passed in to change working directory. What gets passed in is my current directory dot dot dot dot dot whatever, right? And so if I take that, I can just run some clever string sort of... I can run clever path functions that are implemented in most modern languages to condense that path down to a canonical path. Like if you guys use Python, Python has like helper functions to do, so does JavaScript, right? So there's actually no real reason for the file system to have to be able to process dot dot or dot dot during this process, right? Usually what it gets is a canonical path, right? And they can always start at root and work forward. But even if I had to process dot and dot dot, it's not that hard to do. Well, it's symbolic links. Does anyone know how symbolic links work? I'll just sort of stick this in here for a second. Yeah. Oh no, okay, so that's actually what's called a hard link. So a hard link, there are two types of links. There are what are called hard links and there are what are called soft links or symbolic links. Hard links are cases where there are two entries in two different directories that point to the same I know. So if you imagine I'm opening a file, there are two different ways for the file system to point on to another directory or another file and I just continue the process, right? So that's a hard link. What about a soft link? So I'll give you a hint. So hard links, so what do hard links require? I'm mapping a name to a different I know number so that I know number is specific to the file system I'm on. So for example, if I have four file systems mounted on my system, can I use a hard link to map from one file system to the other file system? I wouldn't want to do that. I mean in theory you could but you wouldn't. So those I know numbers, so soft links on the other hand can be mapped from one file system to another. So how do soft, anyone take a guess on how soft links work? Yeah, it's a name to a name, exactly. So soft link files contain another file name in them. So when you go to a soft link, all the path name translation does is start over with a new name. That's why you can create soft links that point to nothing, right? You can create totally, you can create soft links that have dots in them. You can create a symbolic link to dot, dot, dot, dot, dot, right? It won't always work. If you put it in root, it's not going to work, right? Because you're going to try to walk, you know, up past the top of the tree. Yeah, symbolic links are literally just a special type of file that just contains another file name in it. When I get there, I just take that file name and I, you know, I start trying to open it from wherever I am. Alright, so any questions about path name translation? One of the sort of basic features of hierarchical file systems. Okay, let's talk about, so that's one of the core file system functionalities, right, is mapping human readable names, file names, two I know numbers and being able to locate the contents of the file and other information about it. The other thing is from time to time users actually want to also know what the contents of a file are, right, that's pretty useful. And so now the second thing we're going to talk about is how do I start with an inode and get a list of data blocks that are associated with the file. And I want an ordered list of data blocks because I want to be able to reassemble the file in the correct order, right? Okay, so now let's say I'm reading and writing to a particular point in the file. I added this 3, 4, 5 as a location. What does this command have to do? So at this point, you know, I'm assuming I have some sort of lower level file system data structure that identifies the file that I'm using, but every time I modify a file, what does the file system have to be able to do? What do I have to, what's the translation step that has to refer here? I mean where is the, where is this, where is this file modification going to go? It's going to go to disk, it's going to go to some data block on disk. So what do I need to, what do I need to be able to translate here? Yeah. Well, it's not just an inode, right? Because an inode can refer to multiple data blocks. So I need an inode and a what? An inode and an offset. An inode offset pair, assuming that that's within the file, should uniquely identify a data block on disk. There is some data block on disk that holds the content of that file, that particular offset. And if I'm going to modify the file or read from it, I need to be able to find this data block. Now this is a case where, you know, there's some difference in terms of data structures that file systems can use to do this. And the core challenge that I'm trying to address here, or the file systems we're trying to address, is the fact that files can vary in size, in an enormous amount, right? So we talked about this a little bit last time. I can have tiny little files, and then I can have multi terabyte files. And in both cases I need to be able to find all the data blocks associated with the file, but you can think, you know, you can probably sort of expect or guess that the simple data structures that work in one case don't work very well in another. Okay. So, and this is kind of a fun little, one of these fun little algorithms in real life, sort of design exercises. So one way is that I can organize all the data blocks into a linked list. And probably I don't organize the data blocks into a linked list, but I have some sort of other data structure that the file system builds in other data blocks that then become or use for its own data structures, and I essentially use that to link all of the data blocks together in some way. So what's good about this? What are the, so here's how this would work. So I contain a pointer to the first data block, and then every data block contains a pointer to the previous and next data box. Okay, so actually let's embed, let's embed the list inside the data box themselves. This is kind of gross, right? Because why? What would make you sad if you did this? Yeah. Well, of course, but I mean that would always make me sad whenever I had a linked list. But what makes me particularly sad about this linked list? I had 4k data blocks, and I felt good about that. And then what did I have to do to them? I have, now I have like 4,094 byte blocks, which just is a little gross. So I probably wouldn't do this, because I like powers of two, right? Anyway, so yeah. So I have to put these inside the data block, just make some of the, like it's, this is totally doable, right? It's not a problem. I can have data blocks that are like seven bytes long. It doesn't matter, right? I can do math, I'm cool. But this is just a little, yeah. So I have to, I have to put the links inside the data box themselves. I lose a little bit of space. Now, every data box needs to point to the previous and next data block. So starting from the inode, keeping track of where I am, I can walk the list of data blocks to find the offset that I'm looking for. So what's nice about this? Yeah, it's very easy to implement, simple. It doesn't, so the inode in this case has a very small amount of information in it. All it has to have is one pointer, right? What are some problems with this? What could take a very long time? Yeah. Yeah, so let's say you open up that legally downloaded movie that you got from, from BitTorrent and you seek all the way to the end. You want to watch the end again, right? That's all I do when I rewatch old movies. I just watch the end, right? That's usually the best part. So you seek all the way to like, you know, three minutes from the end and then you wait for like half an hour, right? While your disk follows this incredible blockchain all over the place. The disk heads like, you know, and by the time you're done you've basically read the entire movie. I'm going to start to finish to get to the very end. So not, not good. Seeking is not good, right? The link lists have this problem in general, right? They don't have a lot of structure in them, so it's difficult to seek inside a link list. I'll have to follow a report. Yeah, okay. So another simple solution, just a flat array, right? We like flat arrays. Flat arrays are simple easy data structures that solve a large number of problems. Maybe not this one. Alright, what's good? So again, simple, I just have, you know, a bunch of blocks on disk that store pointers, that store an array of pointers into the file. So what, what's good about this? Yeah, so I just solved my seek problem, right? Which is awesome. You know, I can potentially seek into, I mean the first thing I do is I convert the offset to an offset into my array and that array points me directly to a data block and I'm done. So I have solved the offset problem. I have very fast offset lookups. Unfortunately, the large portion of the array might be unused, right, depending on how big it is. And I have to choose in a, I probably have to choose the size for this array. Now you can argue that I can make this array expandable, I guess, right? But once I, once I start making the array expandable, then the array itself is sort of like the linked list that we just didn't like a minute ago, where I have to follow pointers and stuff like that. So, or I can just choose a small file size. So this is one of those solutions that doesn't scale very well to big files. Works fine for small files, doesn't work fine for big files. Okay. So the solution that a lot of, I mean file systems vary in terms of how they implement this, but the solution that a lot of them use is based on this assumption that a lot of files are fairly small. Remember, EXT4 average file size that's built into its iNode calculation is just 16k. Where's Dave? You did that calculation, right? What was the most common file size? 4 to 16k. So Dave has some sort of server that he maintains, stop me if I'm saying something that's totally untrue, that has like people's backups for people's home machines and he ran that file statistics calculation that we were talking about and these are windows machines and the most common file size range was 4 to 16k. So a lot of small files out there, right? There were also some bumps up a little bit bigger, right? That we conjectured corresponded to photos, right? Photosize files are a lot of people back up pictures, pictures for most people, you know, have a particular size like my wife's pictures are massive because she takes them in this fancy camera, really good resolution but a lot of people, you know, photos are small. So most files are small but we want to let files get very big, right? We want to, I think like ZFS now has like a maximum file size that's into the Zeta bytes, right? So I think you'll tear up how to Zeta. So Zeta is just like lots of bytes. It just doesn't really matter at that point. If you can find yourself a Zeta byte drive, just buy it, right? Like, you know, it's all that you should need for a while. So the inode stores some pointers to blocks and then some pointers to and these refer to as direct blocks. So starting with the inode, I get pointers to some data structures that have pointers to blocks. But the direct blocks can also contain pointers to blocks that contain pointers to blocks. So we call those indirect blocks. And then on some system, the indirect blocks can also contain pointers to blocks that contain pointers to blocks that contain pointers to blocks, right? We refer to these as doubly indirect blocks. And on some systems, you can have triply direct blocks, right? Every time you add a level of block, you're getting, you know, several orders of magnitude of expansion in terms of the size that the rest of that data structure maps. So here's an example, right? So here's my inode. This inode has two pointers to data blocks. It has one direct block. That direct block has two pointers to data blocks. And if I hung another direct block off here, that would be a direct block, et cetera. Does this make sense? It's kind of a neat data structure. And offset lookups in here touch like, oh, log n numbers of data blocks. Right? As the file gets bigger and bigger, you know, you imagine getting into a particular point, I not only have to follow a pointer. So for small files, all I have to do is touch the inode potentially. And I have a pointer right to the beginning parts of the file. But as the file gets bigger, the number of extra blocks that I have to touch to do offset lookups grows slowly. Right? It doesn't grow linearly in the size of the file, but it grows more slowly than the size of the file. So this is nice. The index scales with the size of the file. You can also notice that the number of waste space that I have to use just to store, you know, metadata is growing more slowly than it did before when I was doing the, when I was doing the flat array. And offset lookups are still pretty fast. Right? They get slower towards the end of the file potentially. And with this approach, I can potentially, you know, store pointers to arbitrarily large files, which is pretty cool. Yeah. Yeah. And then you can take you with space on disk, right? Which is sort of a pain. Yeah. Yeah. I mean, this is why people like file systems, right? I mean, you start thinking about these data structures. I mean, there are a lot of file systems that use bee trees and all sorts of fancy data structures to organize stuff on disk. That doesn't always work out all that well. So does it. Okay. I finished a little early today. I think that's okay. It's warm outside. On Wednesday, we'll talk about caching and a little bit about journaling. And then on Friday, well, I think we're going to do sort of FFS, LFS, but I'll post this on discourse. At some point, I think for next Monday, I'm going to assign you guys to do some sort of research outside of class on RAID. How many people have heard of RAID? How many people know how RAID works? Okay. Well, you're going to find out. So I'll see you guys on Wednesday.