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