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