Ext2 uses the page cache for block metadata
[akaros.git] / kern / src / ext2fs.c
1 /* Copyright (c) 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Ext2, VFS required functions, internal functions, life, the universe, and
6  * everything! */
7
8 #include <vfs.h>
9 #include <ext2fs.h>
10 #include <blockdev.h>
11 #include <kmalloc.h>
12 #include <assert.h>
13 #include <kref.h>
14 #include <endian.h>
15 #include <error.h>
16 #include <pmap.h>
17
18 /* These structs are declared again and initialized farther down */
19 struct page_map_operations ext2_pm_op;
20 struct super_operations ext2_s_op;
21 struct inode_operations ext2_i_op;
22 struct dentry_operations ext2_d_op;
23 struct file_operations ext2_f_op_file;
24 struct file_operations ext2_f_op_dir;
25 struct file_operations ext2_f_op_sym;
26
27 /* EXT2 Internal Functions */
28
29 /* Useful helper functions. */
30
31 /* This returns the block group containing the inode, BGs starting at 0.  Note
32  * the inodes are indexed starting at 1. */
33 static unsigned int ext2_ino2bg(unsigned int inode_num, unsigned int ino_p_grp)
34 {
35         return (inode_num - 1) / ino_p_grp;
36 }
37
38 /* This returns the 0-index within a block group */
39 static unsigned int ext2_ino2idx(unsigned int inode_num, unsigned int ino_p_grp)
40 {
41         return (inode_num - 1) % ino_p_grp;
42 }
43
44 /* Slabs for ext2 specific info chunks */
45 struct kmem_cache *ext2_i_kcache;
46
47 /* One-time init for all ext2 instances */
48 void ext2_init(void)
49 {
50         ext2_i_kcache = kmem_cache_create("ext2_i_info", sizeof(struct ext2_i_info),
51                                           __alignof__(struct ext2_i_info), 0, 0, 0);
52 }
53
54 /* Helper op to read one ext2 block, 0-indexing the block numbers.  Kfree your
55  * answer.
56  *
57  * TODO: consider taking a buffer_head, or having a generic block_dev function
58  * for this.  Currently this is just using the BH to talk to breq, need to make
59  * it use the page mapping. */
60 void *__ext2_read_block(struct block_device *bdev, int block_num, int blocksize)
61 {
62         int retval;
63         void *buffer = kmalloc(blocksize, 0);
64         struct block_request *breq = kmem_cache_alloc(breq_kcache, 0);
65         struct buffer_head *bh = kmem_cache_alloc(bh_kcache, 0);
66         assert(buffer && breq && bh);
67
68         /* Build the BH describing the mapping we want */
69         bh->bh_buffer = buffer; // TODO: have a real page
70         bh->bh_sector = block_num * (blocksize >> SECTOR_SZ_LOG);
71         bh->bh_nr_sector = blocksize >> SECTOR_SZ_LOG;
72         /* Build and submit the request */
73         breq->flags = BREQ_READ;
74         breq->bhs = breq->local_bhs;
75         breq->bhs[0] = bh;
76         breq->nr_bhs = 1;
77         retval = make_request(bdev, breq);
78         assert(!retval);
79         kmem_cache_free(breq_kcache, breq);
80         kmem_cache_free(bh_kcache, bh); /* TODO: shouldn't disconnect this */
81         return buffer;
82 }
83
84 /* TODO: pull these metablock functions out of ext2 */
85 /* Makes sure the FS block of metadata is in memory.  This returns a pointer to
86  * the beginning of the requested block.  Release it with put_metablock().
87  * Internally, the kreffing is done on the page. */
88 void *__ext2_get_metablock(struct block_device *bdev, unsigned long blk_num,
89                            unsigned int blk_sz)
90 {
91         struct page *page;
92         struct page_map *pm = &bdev->b_pm;
93         unsigned int blk_per_pg = PGSIZE / blk_sz;
94         unsigned int blk_offset = (blk_num % blk_per_pg) * blk_sz;
95         int error;
96         assert(blk_offset < PGSIZE);
97         error = pm_load_page(pm, blk_num / blk_per_pg, &page); 
98         if (error) {
99                 warn("Failed to read metablock! (%d)", error);
100                 return 0;
101         }
102         /* return where we are within the page for the given block */
103         return page2kva(page) + blk_offset;
104 }
105
106 /* Convenience wrapper */
107 void *ext2_get_metablock(struct super_block *sb, unsigned long block_num)
108 {
109         return __ext2_get_metablock(sb->s_bdev, block_num, sb->s_blocksize);
110 }
111
112 /* Decrefs the buffer from get_metablock().  Call this when you no longer
113  * reference your metadata block/buffer */
114 void ext2_put_metablock(void *buffer)
115 {
116         page_decref(kva2page(buffer));
117 }
118
119 /* Will dirty the block/BH/page for the given metadata block/buffer.  Will have
120  * to be careful with the page reclaimer - if someone holds a reference, they
121  * can still dirty it. */
122 void ext2_dirty_metablock(void *buffer)
123 {
124         struct page *page = kva2page(buffer);
125         /* TODO: race on flag modification, and consider dirtying the BH. */
126         page->pg_flags |= PG_DIRTY;
127 }
128
129 /* Reads a block of file data.  TODO: Function name and guts will change soon */
130 void *ext2_read_fileblock(struct super_block *sb, unsigned int block_num)
131 {
132         /* note, we might get rid of this read block, if all files use pages */
133         return __ext2_read_block(sb->s_bdev, block_num, sb->s_blocksize);
134 }
135
136 /* Helper for read_ino_block(). 
137  *
138  * This walks a table stored at block 'blkid', returning which block you should
139  * walk next in 'blkid'.  rel_inoblk is where you are given the current level of
140  * indirection tables, and returns where you should be for the next one.  Reach
141  * is how many items the current table's *items* can index (so if we're on a
142  * 3x indir block, reach should be for the doubly-indirect entries, and
143  * rel_inoblk will tell you where within that double block you want). */
144 static void ext2_walk_inotable(struct inode *inode, unsigned int *blkid,
145                                unsigned int *rel_inoblk, unsigned int reach)
146 {
147         uint32_t *blk_buf = ext2_get_metablock(inode->i_sb, *blkid);
148         assert(blk_buf);
149         *blkid = le32_to_cpu(blk_buf[*rel_inoblk / reach]);
150         *rel_inoblk = *rel_inoblk % reach;
151         ext2_put_metablock(blk_buf);
152 }
153
154 /* Reads a file's block, determined via walking the inode's tables.  The general
155  * idea is that if the ino_block num is above a threshold, we'll need to go into
156  * indirect tables (1x, 2x, or 3x (triply indirect) tables).  Block numbers
157  * start at 0.
158  *
159  * One thing that might suck with this: if there's a 0 in the array, we should
160  * stop.  This function isn't really checking if we "went too far."
161  *
162  * Horrendously untested, btw. */
163 void *ext2_read_ino_block(struct inode *inode, unsigned int ino_block)
164 {
165         struct ext2_i_info *e2ii = (struct ext2_i_info*)inode->i_fs_info;
166
167         unsigned int blkid;
168         void *blk;
169         /* The 'reach' is how many blocks a given table can 'address' */
170         int ptrs_per_blk = inode->i_sb->s_blocksize / sizeof(uint32_t);
171         int reach_1xblk = ptrs_per_blk;
172         int reach_2xblk = ptrs_per_blk * ptrs_per_blk;
173         /* thresholds are the first blocks that require a level of indirection */
174         int single_threshold = 12;
175         int double_threshold = single_threshold + reach_1xblk;
176         int triple_threshold = double_threshold + reach_2xblk;
177         /* this is the desired block num lookup within a level of indirection */
178         unsigned int rel_inoblk = ino_block;
179
180         if (ino_block >= triple_threshold) {
181                 /* ino_block requires a triply-indirect lookup */
182                 blkid = e2ii->i_block[14];
183                 ext2_walk_inotable(inode, &blkid, &rel_inoblk, reach_2xblk);
184                 ext2_walk_inotable(inode, &blkid, &rel_inoblk, reach_1xblk);
185                 ext2_walk_inotable(inode, &blkid, &rel_inoblk, 1);
186         } else if (ino_block >= double_threshold) {
187                 /* ino_block requires a doubly-indirect lookup  */
188                 blkid = e2ii->i_block[13];
189                 ext2_walk_inotable(inode, &blkid, &rel_inoblk, reach_1xblk);
190                 ext2_walk_inotable(inode, &blkid, &rel_inoblk, 1);
191         } else if (ino_block >= single_threshold) {
192                 /* ino_block requires a singly-indirect lookup */
193                 blkid = e2ii->i_block[12];
194                 ext2_walk_inotable(inode, &blkid, &rel_inoblk, 1);
195         } else {
196                 /* Direct block, straight out of the inode */
197                 blkid = e2ii->i_block[ino_block];
198         }
199         return ext2_read_fileblock(inode->i_sb, blkid);
200 }
201
202 /* This checks an ext2 disc SB for consistency, optionally printing out its
203  * stats.  It also will also read in a copy of the block group descriptor table
204  * from its first location (right after the primary SB copy) */
205 void ext2_check_sb(struct ext2_sb *e2sb, struct ext2_block_group *bg,
206                    bool print)
207 {
208         int retval;
209         unsigned int blksize, blks_per_group, num_blk_group, num_blks;
210         unsigned int inodes_per_grp, blks_per_grp, inode_size;
211         unsigned int sum_blks = 0, sum_inodes = 0;
212
213         assert(le16_to_cpu(e2sb->s_magic) == EXT2_SUPER_MAGIC);
214         num_blks = le32_to_cpu(e2sb->s_free_blocks_cnt);
215         blksize = 1024 << le32_to_cpu(e2sb->s_log_block_size);
216         blks_per_group = le32_to_cpu(e2sb->s_blocks_per_group);
217         num_blk_group = num_blks / blks_per_group + (num_blks % blks_per_group ? 1 : 0);
218         
219         if (print) {
220                 printk("EXT2 info:\n-------------------------\n");
221                 printk("Total Inodes:     %8d\n", le32_to_cpu(e2sb->s_inodes_cnt));
222                 printk("Total Blocks:     %8d\n", le32_to_cpu(e2sb->s_blocks_cnt));
223                 printk("Num R-Blocks:     %8d\n", le32_to_cpu(e2sb->s_rblocks_cnt));
224                 printk("Num Free Blocks:  %8d\n", le32_to_cpu(e2sb->s_free_blocks_cnt));
225                 printk("Num Free Inodes:  %8d\n", le32_to_cpu(e2sb->s_free_inodes_cnt));
226                 printk("First Data Block: %8d\n",
227                        le32_to_cpu(e2sb->s_first_data_block));
228                 printk("Block Size:       %8d\n",
229                        1024 << le32_to_cpu(e2sb->s_log_block_size));
230                 printk("Fragment Size:    %8d\n",
231                        1024 << le32_to_cpu(e2sb->s_log_frag_size));
232                 printk("Blocks per group: %8d\n",
233                        le32_to_cpu(e2sb->s_blocks_per_group));
234                 printk("Inodes per group: %8d\n",
235                        le32_to_cpu(e2sb->s_inodes_per_group));
236                 printk("Block groups:     %8d\n", num_blk_group);
237                 printk("Mount state:      %8d\n", le16_to_cpu(e2sb->s_state));
238                 printk("Rev Level:        %8d\n", le32_to_cpu(e2sb->s_minor_rev_level));
239                 printk("Minor Rev Level:  %8d\n", le16_to_cpu(e2sb->s_minor_rev_level));
240                 printk("Creator OS:       %8d\n", le32_to_cpu(e2sb->s_creator_os));
241                 printk("First Inode:      %8d\n", le32_to_cpu(e2sb->s_first_ino));
242                 printk("Inode size:       %8d\n", le16_to_cpu(e2sb->s_inode_size));
243                 printk("This block group: %8d\n", le16_to_cpu(e2sb->s_block_group_nr));
244                 printk("BG ID of 1st meta:%8d\n", le16_to_cpu(e2sb->s_first_meta_bg));
245                 printk("Volume name:      %s\n", e2sb->s_volume_name);
246                 printk("\nBlock Group Info:\n----------------------\n");
247         }
248         
249         for (int i = 0; i < num_blk_group; i++) {
250                 sum_blks += le16_to_cpu(bg[i].bg_free_blocks_cnt);
251                 sum_inodes += le16_to_cpu(bg[i].bg_free_inodes_cnt);
252                 if (print) {
253                         printk("*** BG %d at %08p\n", i, &bg[i]);
254                         printk("Block bitmap:%8d\n", le32_to_cpu(bg[i].bg_block_bitmap));
255                         printk("Inode bitmap:%8d\n", le32_to_cpu(bg[i].bg_inode_bitmap));
256                         printk("Inode table: %8d\n", le32_to_cpu(bg[i].bg_inode_table));
257                         printk("Free blocks: %8d\n", le16_to_cpu(bg[i].bg_free_blocks_cnt));
258                         printk("Free inodes: %8d\n", le16_to_cpu(bg[i].bg_free_inodes_cnt));
259                         printk("Used Dirs:   %8d\n", le16_to_cpu(bg[i].bg_used_dirs_cnt));
260                 }
261         }
262         
263         /* Sanity Assertions.  A good ext2 will always pass these. */
264         inodes_per_grp = le32_to_cpu(e2sb->s_inodes_per_group);
265         blks_per_group = le32_to_cpu(e2sb->s_blocks_per_group);
266         inode_size = le32_to_cpu(e2sb->s_inode_size);
267         assert(le32_to_cpu(e2sb->s_inodes_cnt) <= inodes_per_grp * num_blk_group);
268         assert(le32_to_cpu(e2sb->s_free_inodes_cnt) == sum_inodes);
269         assert(le32_to_cpu(e2sb->s_blocks_cnt) <= blks_per_group * num_blk_group);
270         assert(le32_to_cpu(e2sb->s_free_blocks_cnt) == sum_blks);
271         if (blksize == 1024)
272                 assert(le32_to_cpu(e2sb->s_first_data_block) == 1);
273         else
274                 assert(le32_to_cpu(e2sb->s_first_data_block) == 0);
275         assert(inode_size <= blksize);
276         assert(inode_size == 1 << LOG2_UP(inode_size));
277         assert(blksize * 8 >= inodes_per_grp);
278         assert(inodes_per_grp % (blksize / inode_size) == 0);
279         if (print)
280                 printk("Passed EXT2 Checks\n");
281 }
282
283 /* VFS required Misc Functions */
284
285 /* Creates the SB.  Like with Ext2's, we should consider pulling out the
286  * FS-independent stuff, if possible. */
287 struct super_block *ext2_get_sb(struct fs_type *fs, int flags,
288                                char *dev_name, struct vfsmount *vmnt)
289 {
290         struct block_device *bdev;
291         struct ext2_sb *e2sb;
292         struct ext2_block_group *e2bg;
293
294         static bool ran_once = FALSE;
295         if (!ran_once) {
296                 ran_once = TRUE;
297                 ext2_init();
298         }
299         bdev = get_bdev(dev_name);
300         assert(bdev);
301         /* Read the SB.  It's always at byte 1024 and 1024 bytes long.  Note we do
302          * not put the metablock (we pin it off the sb later).  Same with e2bg. */
303         e2sb = (struct ext2_sb*)__ext2_get_metablock(bdev, 1, 1024);
304         if (!(le16_to_cpu(e2sb->s_magic) == EXT2_SUPER_MAGIC)) {
305                 warn("EXT2 Not detected when it was expected!");
306                 return 0;
307         }
308         /* Read in the block group descriptor table.  Which block the BG table is on
309          * depends on the blocksize */
310         unsigned int blksize = 1024 << le32_to_cpu(e2sb->s_log_block_size);
311         e2bg = __ext2_get_metablock(bdev, blksize == 1024 ? 2 : 1, blksize);
312         assert(e2bg);
313         ext2_check_sb(e2sb, e2bg, FALSE);
314
315         /* Now we build and init the VFS SB */
316         struct super_block *sb = get_sb();
317         sb->s_dev = 0;                  /* what do we really want here? */
318         sb->s_blocksize = blksize;
319         /* max file size for a 1024 blocksize FS.  good enough for now (TODO) */
320         sb->s_maxbytes = 17247252480;
321         sb->s_type = &ext2_fs_type;
322         sb->s_op = &ext2_s_op;
323         sb->s_flags = flags;    /* from the disc too?  which flags are these? */
324         sb->s_magic = EXT2_SUPER_MAGIC;
325         sb->s_mount = vmnt;     /* Kref?  also in KFS */
326         sb->s_syncing = FALSE;
327         kref_get(&bdev->b_kref, 1);
328         sb->s_bdev = bdev;
329         strlcpy(sb->s_name, "EXT2", 32);
330         sb->s_fs_info = kmalloc(sizeof(struct ext2_sb_info), 0);
331         assert(sb->s_fs_info);
332         /* store the in-memory copy of the disk SB and bg desc table */
333         ((struct ext2_sb_info*)sb->s_fs_info)->e2sb = e2sb;
334         ((struct ext2_sb_info*)sb->s_fs_info)->e2bg = e2bg;
335
336         /* Final stages of initializing the sb, mostly FS-independent */
337         init_sb(sb, vmnt, &ext2_d_op, EXT2_ROOT_INO, 0);
338
339         printk("EXT2 superblock loaded\n");
340         kref_put(&bdev->b_kref);
341         return sb;
342 }
343
344 void ext2_kill_sb(struct super_block *sb)
345 {
346         /* don't forget to kfree the s_fs_info and its two members */
347         panic("Killing an EXT2 SB is not supported!");
348 }
349
350 /* Every FS must have a static FS Type, with which the VFS code can bootstrap */
351 struct fs_type ext2_fs_type = {"EXT2", 0, ext2_get_sb, ext2_kill_sb, {0, 0},
352                                TAILQ_HEAD_INITIALIZER(ext2_fs_type.fs_supers)};
353
354 /* Page Map Operations */
355
356 /* Fills page with its contents from its backing store file.  Note that we do
357  * the zero padding here, instead of higher in the VFS.  Might change in the
358  * future. */
359 int ext2_readpage(struct page_map *pm, struct page *page)
360 {
361         I_AM_HERE;
362         #if 0
363         size_t pg_idx_byte = page->pg_index * PGSIZE;
364         struct ext2_i_info *k_i_info = (struct ext2_i_info*)
365                                       file->f_dentry->d_inode->i_fs_info;
366         uintptr_t begin = (size_t)k_i_info->filestart + pg_idx_byte;
367         /* If we're beyond the initial start point, we just need a zero page.  This
368          * is for a hole or for extending a file (even though it won't be saved).
369          * Otherwise, we want the data from Ext2, being careful to not copy from
370          * beyond the original EOF (and zero padding anything extra). */
371         if (pg_idx_byte >= k_i_info->init_size) {
372                 memset(page2kva(page), 0, PGSIZE);
373         } else {
374                 size_t copy_amt = MIN(PGSIZE, k_i_info->init_size - pg_idx_byte);
375                 memcpy(page2kva(page), (void*)begin, copy_amt);
376                 memset(page2kva(page) + copy_amt, 0, PGSIZE - copy_amt);
377         }
378         /* This is supposed to be done in the IO system when the operation is
379          * complete.  Since we aren't doing a real IO request, and it is already
380          * done, we can do it here. */
381         page->pg_flags |= PG_UPTODATE;
382         unlock_page(page);
383         #endif
384         return 0;
385 }
386
387 /* Super Operations */
388
389 /* Creates and initializes a new inode.  FS specific, yet inode-generic fields
390  * are filled in.  inode-specific fields are filled in in read_inode() based on
391  * what's on the disk for a given i_no.  i_no and i_fop are set by the caller.
392  *
393  * Note that this means this inode can be for an inode that is already on disk,
394  * or it can be used when creating.  The i_fop depends on the type of file
395  * (file, directory, symlink, etc). */
396 struct inode *ext2_alloc_inode(struct super_block *sb)
397 {
398         struct inode *inode = kmem_cache_alloc(inode_kcache, 0);
399         memset(inode, 0, sizeof(struct inode));
400         inode->i_op = &ext2_i_op;
401         inode->i_pm.pm_op = &ext2_pm_op;
402         return inode;
403 }
404
405 /* FS-specific clean up when an inode is dealloced.  this is just cleaning up
406  * the in-memory version, and only the FS-specific parts.  whether or not the
407  * inode is still on disc is irrelevant. */
408 void ext2_dealloc_inode(struct inode *inode)
409 {
410         kmem_cache_free(ext2_i_kcache, inode->i_fs_info);
411 }
412
413 /* reads the inode data on disk specified by inode->i_ino into the inode.
414  * basically, it's a "make this inode the one for i_ino (i number)" */
415 void ext2_read_inode(struct inode *inode)
416 {
417         unsigned int bg_num, bg_idx, ino_per_blkgrp, ino_per_blk, my_ino_blk;
418         struct ext2_sb_info *e2sbi = (struct ext2_sb_info*)inode->i_sb->s_fs_info;
419         struct ext2_sb *e2sb = e2sbi->e2sb;
420         struct ext2_block_group *my_bg;
421         struct ext2_inode *ino_tbl_chunk, *my_ino;
422
423         /* Need to compute the blockgroup and index of the requested inode */
424         ino_per_blkgrp = le32_to_cpu(e2sb->s_inodes_per_group);
425         ino_per_blk = inode->i_sb->s_blocksize / le16_to_cpu(e2sb->s_inode_size);
426         bg_num = ext2_ino2bg(inode->i_ino, ino_per_blkgrp);
427         bg_idx = ext2_ino2idx(inode->i_ino, ino_per_blkgrp);
428         my_bg = &e2sbi->e2bg[bg_num];
429         /* Figure out which FS block of the inode table we want and read in that
430          * chunk */
431         my_ino_blk = le32_to_cpu(my_bg->bg_inode_table) + bg_idx / ino_per_blk;
432         ino_tbl_chunk = ext2_get_metablock(inode->i_sb, my_ino_blk);
433         my_ino = &ino_tbl_chunk[bg_idx % ino_per_blk];
434
435         /* Have the disk inode now, let's put its info into the VFS inode: */
436         inode->i_mode = le16_to_cpu(my_ino->i_mode);
437         switch (inode->i_mode & __S_IFMT) {
438                 case (__S_IFDIR):
439                         inode->i_fop = &ext2_f_op_dir;
440                         break;
441                 case (__S_IFREG):
442                         inode->i_fop = &ext2_f_op_file;
443                         break;
444                 case (__S_IFLNK):
445                         inode->i_fop = &ext2_f_op_sym;
446                         break;
447                 case (__S_IFCHR):
448                 case (__S_IFBLK):
449                 default:
450                         inode->i_fop = &ext2_f_op_file;
451                         warn("[Calm British Accent] Look around you.  Unhandled filetype.");
452         }
453         inode->i_nlink = le16_to_cpu(my_ino->i_links_cnt);
454         inode->i_uid = le16_to_cpu(my_ino->i_uid);
455         inode->i_gid = le16_to_cpu(my_ino->i_gid);
456         /* technically, for large F_REG, we should | with i_dir_acl */
457         inode->i_size = le32_to_cpu(my_ino->i_size);
458         inode->i_atime.tv_sec = le32_to_cpu(my_ino->i_atime);
459         inode->i_atime.tv_nsec = 0;
460         inode->i_mtime.tv_sec = le32_to_cpu(my_ino->i_mtime);
461         inode->i_mtime.tv_nsec = 0;
462         inode->i_ctime.tv_sec = le32_to_cpu(my_ino->i_ctime);
463         inode->i_ctime.tv_nsec = 0;
464         inode->i_blocks = le32_to_cpu(my_ino->i_blocks);
465         inode->i_flags = le32_to_cpu(my_ino->i_flags);
466         inode->i_socket = FALSE;                /* for now */
467         /* Copy over the other inode stuff that isn't in the VFS inode.  For now,
468          * it's just the block pointers */
469         inode->i_fs_info = kmem_cache_alloc(ext2_i_kcache, 0);
470         struct ext2_i_info *e2ii = (struct ext2_i_info*)inode->i_fs_info;
471         for (int i = 0; i < 15; i++)
472                 e2ii->i_block[i] = le32_to_cpu(my_ino->i_block[i]);
473         /* TODO: (HASH) unused: inode->i_hash add to hash (saves on disc reading) */
474         /* TODO: we could consider saving a pointer to the disk inode and pinning
475          * its buffer in memory, but for now we'll just free it. */
476         ext2_put_metablock(ino_tbl_chunk);
477 }
478
479 /* called when an inode in memory is modified (journalling FS's care) */
480 void ext2_dirty_inode(struct inode *inode)
481 {
482         // presumably we'll ext2_dirty_metablock(void *buffer) here
483 }
484
485 /* write the inode to disk (specifically, to inode inode->i_ino), synchronously
486  * if we're asked to wait */
487 void ext2_write_inode(struct inode *inode, bool wait)
488 {
489 I_AM_HERE;
490 }
491
492 /* called when an inode is decref'd, to do any FS specific work */
493 void ext2_put_inode(struct inode *inode)
494 {
495 I_AM_HERE;
496 }
497
498 /* Unused for now, will get rid of this if inode_release is sufficient */
499 void ext2_drop_inode(struct inode *inode)
500 {
501 I_AM_HERE;
502 }
503
504 /* delete the inode from disk (all data) */
505 void ext2_delete_inode(struct inode *inode)
506 {
507 I_AM_HERE;
508         // would remove from "disk" here
509         /* TODO: give up our i_ino */
510 }
511
512 /* unmount and release the super block */
513 void ext2_put_super(struct super_block *sb)
514 {
515         panic("Shazbot! Ext2 can't be unmounted yet!");
516 }
517
518 /* updates the on-disk SB with the in-memory SB */
519 void ext2_write_super(struct super_block *sb)
520 {
521 I_AM_HERE;
522 }
523
524 /* syncs FS metadata with the disc, synchronously if we're waiting.  this info
525  * also includes anything pointed to by s_fs_info. */
526 int ext2_sync_fs(struct super_block *sb, bool wait)
527 {
528 I_AM_HERE;
529         return 0;
530 }
531
532 /* remount the FS with the new flags */
533 int ext2_remount_fs(struct super_block *sb, int flags, char *data)
534 {
535         warn("Ext2 will not remount.");
536         return -1; // can't remount
537 }
538
539 /* interrupts a mount operation - used by NFS and friends */
540 void ext2_umount_begin(struct super_block *sb)
541 {
542         panic("Cannot abort a Ext2 mount, and why would you?");
543 }
544
545 /* inode_operations */
546
547 /* Little helper, used for initializing new inodes for file-like objects (files,
548  * symlinks, etc).  We pass the dentry, since we need to up it. */
549 static void ext2_init_inode(struct inode *dir, struct dentry *dentry)
550 {
551 #if 0
552         struct inode *inode = dentry->d_inode;
553         inode->i_ino = ext2_get_free_ino();
554 #endif
555 }
556
557 /* Called when creating a new disk inode in dir associated with dentry.  We need
558  * to fill out the i_ino, set the type, and do whatever else we need */
559 int ext2_create(struct inode *dir, struct dentry *dentry, int mode,
560                struct nameidata *nd)
561 {
562 I_AM_HERE;
563         #if 0
564         struct inode *inode = dentry->d_inode;
565         ext2_init_inode(dir, dentry);
566         SET_FTYPE(inode->i_mode, __S_IFREG);
567         inode->i_fop = &ext2_f_op_file;
568         /* fs_info->filestart is set by the caller, or else when first written (for
569          * new files.  it was set to 0 in alloc_inode(). */
570         #endif
571         return 0;
572 }
573
574 /* Searches the directory for the filename in the dentry, filling in the dentry
575  * with the FS specific info of this file.  If it succeeds, it will pass back
576  * the *dentry you should use (which might be the same as the one you passed in).
577  * If this fails, it will return 0, but not free the memory of "dentry."
578  *
579  * Callers, make sure you alloc and fill out the name parts of the dentry.  We
580  * don't currently use the ND.  Might remove it in the future.  */
581 struct dentry *ext2_lookup(struct inode *dir, struct dentry *dentry,
582                            struct nameidata *nd)
583 {
584         assert(S_ISDIR(dir->i_mode));
585         struct ext2_dirent *dir_buf, *dir_i;
586         unsigned int dir_block = 0;
587         bool found = FALSE;
588         dir_buf = ext2_read_ino_block(dir, dir_block++);
589         dir_i = dir_buf;
590         /* now we have the first block worth of dirents.  We'll get another block if
591          * dir_i hits a block boundary */
592         for (unsigned int bytes = 0; bytes < dir->i_size; ) {
593                 /* On subsequent loops, we might need to advance to the next block */
594                 if ((void*)dir_i >= (void*)dir_buf + dir->i_sb->s_blocksize) {
595                         kfree(dir_buf);
596                         dir_buf = ext2_read_ino_block(dir, dir_block++);
597                         dir_i = dir_buf;
598                         assert(dir_buf);
599                 }
600                 /* Test if we're the one (TODO: use d_compare) */
601                 if (!strncmp((char*)dir_i->dir_name, dentry->d_name.name,
602                              dir_i->dir_namelen)){
603                         load_inode(dentry, le32_to_cpu(dir_i->dir_inode));
604                         /* TODO: (HASH) add dentry to dcache (maybe the caller should) */
605                         kfree(dir_buf);
606                         return dentry;
607                 }
608                 /* Get ready for the next loop */
609                 bytes += dir_i->dir_reclen;
610                 dir_i = (void*)dir_i + dir_i->dir_reclen;
611         }
612         printd("EXT2: Not Found, %s\n", dentry->d_name.name);   
613         kfree(dir_buf);
614         return 0;
615 }
616
617 /* Hard link to old_dentry in directory dir with a name specified by new_dentry.
618  * At the very least, set the new_dentry's FS-specific fields. */
619 int ext2_link(struct dentry *old_dentry, struct inode *dir,
620              struct dentry *new_dentry)
621 {
622 I_AM_HERE;
623         assert(new_dentry->d_op = &ext2_d_op);
624         return 0;
625 }
626
627 /* Removes the link from the dentry in the directory */
628 int ext2_unlink(struct inode *dir, struct dentry *dentry)
629 {
630 I_AM_HERE;
631         return 0;
632 }
633
634 /* Creates a new inode for a symlink dir, linking to / containing the name
635  * symname.  dentry is the controlling dentry of the inode. */
636 int ext2_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
637 {
638 I_AM_HERE;
639         #if 0
640         struct inode *inode = dentry->d_inode;
641         SET_FTYPE(inode->i_mode, __S_IFLNK);
642         inode->i_fop = &ext2_f_op_sym;
643         strncpy(string, symname, len);
644         string[len] = '\0';             /* symname should be \0d anyway, but just in case */
645         #endif
646         return 0;
647 }
648
649 /* Called when creating a new inode for a directory associated with dentry in
650  * dir with the given mode.  Note, we might (later) need to track subdirs within
651  * the parent inode, like we do with regular files.  I'd rather not, so we'll
652  * see if we need it. */
653 int ext2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
654 {
655 I_AM_HERE;
656         #if 0
657         struct inode *inode = dentry->d_inode;
658         inode->i_ino = ext2_get_free_ino();
659         SET_FTYPE(inode->i_mode, __S_IFDIR);
660         inode->i_fop = &ext2_f_op_dir;
661         #endif
662         return 0;
663 }
664
665 /* Removes from dir the directory 'dentry.'  Ext2 doesn't store anything in the
666  * inode for which children it has.  It probably should, but since everything is
667  * pinned, it just relies on the dentry connections. */
668 int ext2_rmdir(struct inode *dir, struct dentry *dentry)
669 {
670 I_AM_HERE;
671         return 0;
672 }
673
674 /* Used to make a generic file, based on the type and the major/minor numbers
675  * (in rdev), with the given mode.  As with others, this creates a new disk
676  * inode for the file */
677 int ext2_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
678 {
679 I_AM_HERE;
680         return -1;
681 }
682
683 /* Moves old_dentry from old_dir to new_dentry in new_dir */
684 int ext2_rename(struct inode *old_dir, struct dentry *old_dentry,
685                struct inode *new_dir, struct dentry *new_dentry)
686 {
687 I_AM_HERE;
688         return -1;
689 }
690
691 /* Returns the char* for the symname for the given dentry.  The VFS code that
692  * calls this for real FS's might assume it's already read in, so if the char *
693  * isn't already in memory, we'd need to read it in here.  Regarding the char*
694  * storage, the char* only will last as long as the dentry and inode are in
695  * memory. */
696 char *ext2_readlink(struct dentry *dentry)
697 {
698 I_AM_HERE;
699         struct inode *inode = dentry->d_inode;
700         if (!S_ISLNK(inode->i_mode))
701                 return 0;
702         return 0;
703 }
704
705 /* Modifies the size of the file of inode to whatever its i_size is set to */
706 void ext2_truncate(struct inode *inode)
707 {
708 }
709
710 /* Checks whether the the access mode is allowed for the file belonging to the
711  * inode.  Implies that the permissions are on the file, and not the hardlink */
712 int ext2_permission(struct inode *inode, int mode, struct nameidata *nd)
713 {
714         return -1;
715 }
716
717
718 /* dentry_operations */
719 /* Determines if the dentry is still valid before using it to translate a path.
720  * Network FS's need to deal with this. */
721 int ext2_d_revalidate(struct dentry *dir, struct nameidata *nd)
722 { // default, nothing
723         return -1;
724 }
725
726 /* Produces the hash to lookup this dentry from the dcache */
727 int ext2_d_hash(struct dentry *dentry, struct qstr *name)
728 {
729         return -1;
730 }
731
732 /* Compares name1 and name2.  name1 should be a member of dir. */
733 int ext2_d_compare(struct dentry *dir, struct qstr *name1, struct qstr *name2)
734 { // default, string comp (case sensitive)
735         return -1;
736 }
737
738 /* Called when the last ref is deleted (refcnt == 0) */
739 int ext2_d_delete(struct dentry *dentry)
740 { // default, nothin
741         return -1;
742 }
743
744 /* Called when it's about to be slab-freed */
745 int ext2_d_release(struct dentry *dentry)
746 {
747         return -1;
748 }
749
750 /* Called when the dentry loses it's inode (becomes "negative") */
751 void ext2_d_iput(struct dentry *dentry, struct inode *inode)
752 { // default, call i_put to release the inode object
753 }
754
755
756 /* file_operations */
757
758 /* Updates the file pointer.  Ext2 doesn't let you go past the end of a file
759  * yet, so it won't let you seek past either.  TODO: think about locking. */
760 off_t ext2_llseek(struct file *file, off_t offset, int whence)
761 {
762 I_AM_HERE;
763         off_t temp_off = 0;
764         #if 0
765         switch (whence) {
766                 case SEEK_SET:
767                         temp_off = offset;
768                         break;
769                 case SEEK_CUR:
770                         temp_off = file->f_pos + offset;
771                         break;
772                 case SEEK_END:
773                         temp_off = file->f_dentry->d_inode->i_size + offset;
774                         break;
775                 default:
776                         set_errno(EINVAL);
777                         warn("Unknown 'whence' in llseek()!\n");
778                         return -1;
779         }
780         /* make sure the f_pos isn't outside the limits of the existing file.
781          * techincally, if they go too far, we should return EINVAL */
782         temp_off = MAX(MIN(temp_off, file->f_dentry->d_inode->i_size), 0);
783         file->f_pos = temp_off;
784         #endif
785         return temp_off;
786 }
787
788 /* Fills in the next directory entry (dirent), starting with d_off.  Like with
789  * read and write, there will be issues with userspace and the *dirent buf.
790  * TODO: (UMEM) */
791 int ext2_readdir(struct file *dir, struct dirent *dirent)
792 {
793         void *buffer;
794         /* Not enough data at the end of the directory */
795         if (dir->f_dentry->d_inode->i_size <
796             dirent->d_off + sizeof(struct ext2_dirent))
797                 return -ENOENT;
798         
799         /* Figure out which block we need to read in for dirent->d_off */
800         int block = dirent->d_off / dir->f_dentry->d_sb->s_blocksize;
801         buffer = ext2_read_ino_block(dir->f_dentry->d_inode, block);
802         assert(buffer);
803         off_t f_off = dirent->d_off % dir->f_dentry->d_sb->s_blocksize;
804         /* Copy out the dirent info */
805         struct ext2_dirent *e2dir = (struct ext2_dirent*)(buffer + f_off);
806         dirent->d_ino = le32_to_cpu(e2dir->dir_inode);
807         dirent->d_off += le16_to_cpu(e2dir->dir_reclen);
808         /* note, dir_namelen doesn't include the \0 */
809         dirent->d_reclen = e2dir->dir_namelen;
810         strncpy(dirent->d_name, (char*)e2dir->dir_name, e2dir->dir_namelen);
811         assert(e2dir->dir_namelen <= MAX_FILENAME_SZ);
812         dirent->d_name[e2dir->dir_namelen] = '\0';
813         kfree(buffer);
814         
815         /* At the end of the directory, sort of.  ext2 often preallocates blocks, so
816          * this will cause us to walk along til the end, which isn't quite right. */
817         if (dir->f_dentry->d_inode->i_size == dirent->d_off)
818                 return 0;
819         if (dir->f_dentry->d_inode->i_size < dirent->d_off) {
820                 warn("Issues reaching the end of an ext2 directory!");
821                 return 0;
822         }
823         return 1;                                                       /* normal success for readdir */
824 }
825
826 /* This is called when a VMR is mapping a particular file.  The FS needs to do
827  * whatever it needs so that faults can be handled by read_page(), and handle all
828  * of the cases of MAP_SHARED, MAP_PRIVATE, whatever.  It also needs to ensure
829  * the file is not being mmaped in a way that conflicts with the manner in which
830  * the file was opened or the file type. */
831 int ext2_mmap(struct file *file, struct vm_region *vmr)
832 {
833         if (S_ISREG(file->f_dentry->d_inode->i_mode))
834                 return 0;
835         return -1;
836 }
837
838 /* Called by the VFS while opening the file, which corresponds to inode,  for
839  * the FS to do whatever it needs. */
840 int ext2_open(struct inode *inode, struct file *file)
841 {
842         /* TODO: check to make sure the file is openable, and maybe do some checks
843          * for the open mode (like did we want to truncate, append, etc) */
844         return 0;
845 }
846
847 /* Called when a file descriptor is closed. */
848 int ext2_flush(struct file *file)
849 {
850 I_AM_HERE;
851         return -1;
852 }
853
854 /* Called when the file is about to be closed (file obj freed) */
855 int ext2_release(struct inode *inode, struct file *file)
856 {
857         return 0;
858 }
859
860 /* Flushes the file's dirty contents to disc */
861 int ext2_fsync(struct file *file, struct dentry *dentry, int datasync)
862 {
863         return -1;
864 }
865
866 /* Traditionally, sleeps until there is file activity.  We probably won't
867  * support this, or we'll handle it differently. */
868 unsigned int ext2_poll(struct file *file, struct poll_table_struct *poll_table)
869 {
870         return -1;
871 }
872
873 /* Reads count bytes from a file, starting from (and modifiying) offset, and
874  * putting the bytes into buffers described by vector */
875 ssize_t ext2_readv(struct file *file, const struct iovec *vector,
876                   unsigned long count, off_t *offset)
877 {
878         return -1;
879 }
880
881 /* Writes count bytes to a file, starting from (and modifiying) offset, and
882  * taking the bytes from buffers described by vector */
883 ssize_t ext2_writev(struct file *file, const struct iovec *vector,
884                   unsigned long count, off_t *offset)
885 {
886         return -1;
887 }
888
889 /* Write the contents of file to the page.  Will sort the params later */
890 ssize_t ext2_sendpage(struct file *file, struct page *page, int offset,
891                      size_t size, off_t pos, int more)
892 {
893         return -1;
894 }
895
896 /* Checks random FS flags.  Used by NFS. */
897 int ext2_check_flags(int flags)
898 { // default, nothing
899         return -1;
900 }
901
902 /* Redeclaration and initialization of the FS ops structures */
903 struct page_map_operations ext2_pm_op = {
904         ext2_readpage,
905 };
906
907 struct super_operations ext2_s_op = {
908         ext2_alloc_inode,
909         ext2_dealloc_inode,
910         ext2_read_inode,
911         ext2_dirty_inode,
912         ext2_write_inode,
913         ext2_put_inode,
914         ext2_drop_inode,
915         ext2_delete_inode,
916         ext2_put_super,
917         ext2_write_super,
918         ext2_sync_fs,
919         ext2_remount_fs,
920         ext2_umount_begin,
921 };
922
923 struct inode_operations ext2_i_op = {
924         ext2_create,
925         ext2_lookup,
926         ext2_link,
927         ext2_unlink,
928         ext2_symlink,
929         ext2_mkdir,
930         ext2_rmdir,
931         ext2_mknod,
932         ext2_rename,
933         ext2_readlink,
934         ext2_truncate,
935         ext2_permission,
936 };
937
938 struct dentry_operations ext2_d_op = {
939         ext2_d_revalidate,
940         ext2_d_hash,
941         ext2_d_compare,
942         ext2_d_delete,
943         ext2_d_release,
944         ext2_d_iput,
945 };
946
947 struct file_operations ext2_f_op_file = {
948         ext2_llseek,
949         generic_file_read,
950         generic_file_write,
951         ext2_readdir,
952         ext2_mmap,
953         ext2_open,
954         ext2_flush,
955         ext2_release,
956         ext2_fsync,
957         ext2_poll,
958         ext2_readv,
959         ext2_writev,
960         ext2_sendpage,
961         ext2_check_flags,
962 };
963
964 struct file_operations ext2_f_op_dir = {
965         ext2_llseek,
966         generic_dir_read,
967         0,
968         ext2_readdir,
969         ext2_mmap,
970         ext2_open,
971         ext2_flush,
972         ext2_release,
973         ext2_fsync,
974         ext2_poll,
975         ext2_readv,
976         ext2_writev,
977         ext2_sendpage,
978         ext2_check_flags,
979 };
980
981 struct file_operations ext2_f_op_sym = {
982         ext2_llseek,
983         generic_file_read,
984         generic_file_write,
985         ext2_readdir,
986         ext2_mmap,
987         ext2_open,
988         ext2_flush,
989         ext2_release,
990         ext2_fsync,
991         ext2_poll,
992         ext2_readv,
993         ext2_writev,
994         ext2_sendpage,
995         ext2_check_flags,
996 };