29e0bd4b3f044bdf68f69bef8a9d17b4cbb0ad88
[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  * For now, just a lot of debugging / bootstrapping functions for ext2.
6  */
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 /* deallocs and cleans up after an inode. */
371 void ext2_dealloc_inode(struct inode *inode)
372 {
373         static bool ran_once = FALSE;
374         if (!ran_once) {
375                 ran_once = TRUE;
376                 warn("Implement %s(), you're leaking memory!\n", __FUNCTION__);
377         }
378 /* too verbose, but it's a TODO... */
379 //I_AM_HERE;
380         #if 0
381         /* If we're a symlink, give up our storage for the symname */
382         if (S_ISLNK(inode->i_mode))
383                 kfree(((struct ext2_i_info*)inode->i_fs_info)->filestart);
384         kmem_cache_free(ext2_i_kcache, inode->i_fs_info);
385         #endif
386 }
387
388 /* reads the inode data on disk specified by inode->i_ino into the inode.
389  * basically, it's a "make this inode the one for i_ino (i number)" */
390 void ext2_read_inode(struct inode *inode)
391 {
392         unsigned int bg_num, bg_idx, ino_per_blkgrp, ino_per_blk, my_ino_blk;
393         struct ext2_sb_info *e2sbi = (struct ext2_sb_info*)inode->i_sb->s_fs_info;
394         struct ext2_sb *e2sb = e2sbi->e2sb;
395         struct ext2_block_group *my_bg;
396         struct ext2_inode *ino_tbl_chunk, *my_ino;
397
398         /* Need to compute the blockgroup and index of the requested inode */
399         ino_per_blkgrp = le32_to_cpu(e2sb->s_inodes_per_group);
400         ino_per_blk = inode->i_sb->s_blocksize / le16_to_cpu(e2sb->s_inode_size);
401         bg_num = ext2_ino2bg(inode->i_ino, ino_per_blkgrp);
402         bg_idx = ext2_ino2idx(inode->i_ino, ino_per_blkgrp);
403         my_bg = &e2sbi->e2bg[bg_num];
404         /* Figure out which FS block of the inode table we want and read in that
405          * chunk */
406         my_ino_blk = le32_to_cpu(my_bg->bg_inode_table) + bg_idx / ino_per_blk;
407         ino_tbl_chunk = ext2_read_block(inode->i_sb, my_ino_blk);
408         my_ino = &ino_tbl_chunk[bg_idx % ino_per_blk];
409
410         /* Have the disk inode now, let's put its info into the VFS inode: */
411         inode->i_mode = le16_to_cpu(my_ino->i_mode);
412         switch (inode->i_mode & __S_IFMT) {
413                 case (__S_IFDIR):
414                         inode->i_fop = &ext2_f_op_dir;
415                         break;
416                 case (__S_IFREG):
417                         inode->i_fop = &ext2_f_op_file;
418                         break;
419                 case (__S_IFLNK):
420                         inode->i_fop = &ext2_f_op_sym;
421                         break;
422                 case (__S_IFCHR):
423                 case (__S_IFBLK):
424                 default:
425                         inode->i_fop = &ext2_f_op_file;
426                         warn("[Calm British Accent] Look around you.  Unhandled filetype.");
427         }
428         inode->i_nlink = le16_to_cpu(my_ino->i_links_cnt);
429         inode->i_uid = le16_to_cpu(my_ino->i_uid);
430         inode->i_gid = le16_to_cpu(my_ino->i_gid);
431         /* technically, for large F_REG, we should | with i_dir_acl */
432         inode->i_size = le32_to_cpu(my_ino->i_size);
433         inode->i_atime.tv_sec = le32_to_cpu(my_ino->i_atime);
434         inode->i_atime.tv_nsec = 0;
435         inode->i_mtime.tv_sec = le32_to_cpu(my_ino->i_mtime);
436         inode->i_mtime.tv_nsec = 0;
437         inode->i_ctime.tv_sec = le32_to_cpu(my_ino->i_ctime);
438         inode->i_ctime.tv_nsec = 0;
439         inode->i_blocks = le32_to_cpu(my_ino->i_blocks);
440         inode->i_flags = le32_to_cpu(my_ino->i_flags);
441         inode->i_socket = FALSE;                /* for now */
442         /* Copy over the other inode stuff that isn't in the VFS inode.  For now,
443          * it's just the block pointers */
444         inode->i_fs_info = kmem_cache_alloc(ext2_i_kcache, 0);
445         struct ext2_i_info *e2ii = (struct ext2_i_info*)inode->i_fs_info;
446         for (int i = 0; i < 15; i++)
447                 e2ii->i_block[i] = le32_to_cpu(my_ino->i_block[i]);
448         /* TODO: (HASH) unused: inode->i_hash add to hash (saves on disc reading) */
449         /* TODO: (BUF) we could consider saving a pointer to the disk inode and
450          * pinning its buffer in memory, but for now we'll just free it */
451         kfree(ino_tbl_chunk);
452 }
453
454 /* called when an inode in memory is modified (journalling FS's care) */
455 void ext2_dirty_inode(struct inode *inode)
456 {
457 }
458
459 /* write the inode to disk (specifically, to inode inode->i_ino), synchronously
460  * if we're asked to wait */
461 void ext2_write_inode(struct inode *inode, bool wait)
462 {
463 I_AM_HERE;
464 }
465
466 /* called when an inode is decref'd, to do any FS specific work */
467 void ext2_put_inode(struct inode *inode)
468 {
469 I_AM_HERE;
470 }
471
472 /* called when an inode is about to be destroyed.  the generic version ought to
473  * remove every reference to the inode from the VFS, and if the inode isn't in
474  * any directory, calls delete_inode */
475 void ext2_drop_inode(struct inode *inode)
476 { // TODO: should call a generic one instead.  or at least do something...
477         // remove from lists
478 I_AM_HERE;
479 }
480
481 /* delete the inode from disk (all data) and deallocs the in memory inode */
482 void ext2_delete_inode(struct inode *inode)
483 {
484 I_AM_HERE;
485         // would remove from "disk" here
486         ext2_dealloc_inode(inode);
487         /* TODO: give up our i_ino */
488 }
489
490 /* unmount and release the super block */
491 void ext2_put_super(struct super_block *sb)
492 {
493         panic("Shazbot! Ext2 can't be unmounted yet!");
494 }
495
496 /* updates the on-disk SB with the in-memory SB */
497 void ext2_write_super(struct super_block *sb)
498 {
499 I_AM_HERE;
500 }
501
502 /* syncs FS metadata with the disc, synchronously if we're waiting.  this info
503  * also includes anything pointed to by s_fs_info. */
504 int ext2_sync_fs(struct super_block *sb, bool wait)
505 {
506 I_AM_HERE;
507         return 0;
508 }
509
510 /* remount the FS with the new flags */
511 int ext2_remount_fs(struct super_block *sb, int flags, char *data)
512 {
513         warn("Ext2 will not remount.");
514         return -1; // can't remount
515 }
516
517 /* interrupts a mount operation - used by NFS and friends */
518 void ext2_umount_begin(struct super_block *sb)
519 {
520         panic("Cannot abort a Ext2 mount, and why would you?");
521 }
522
523 /* inode_operations */
524
525 /* Little helper, used for initializing new inodes for file-like objects (files,
526  * symlinks, etc).  We pass the dentry, since we need to up it. */
527 static void ext2_init_inode(struct inode *dir, struct dentry *dentry)
528 {
529 #if 0
530         struct inode *inode = dentry->d_inode;
531         inode->i_ino = ext2_get_free_ino();
532 #endif
533 }
534
535 /* Called when creating a new disk inode in dir associated with dentry.  We need
536  * to fill out the i_ino, set the type, and do whatever else we need */
537 int ext2_create(struct inode *dir, struct dentry *dentry, int mode,
538                struct nameidata *nd)
539 {
540 I_AM_HERE;
541         #if 0
542         struct inode *inode = dentry->d_inode;
543         ext2_init_inode(dir, dentry);
544         SET_FTYPE(inode->i_mode, __S_IFREG);
545         inode->i_fop = &ext2_f_op_file;
546         /* fs_info->filestart is set by the caller, or else when first written (for
547          * new files.  it was set to 0 in alloc_inode(). */
548         #endif
549         return 0;
550 }
551
552 /* Searches the directory for the filename in the dentry, filling in the dentry
553  * with the FS specific info of this file.  If it succeeds, it will pass back
554  * the *dentry you should use.  If this fails, it will return 0 and will take
555  * the ref to the dentry for you.  Either way, you shouldn't use the ref you
556  * passed in anymore.
557  *
558  * Callers, make sure you alloc and fill out the name parts of the dentry.  We
559  * don't currently use the ND.  Might remove it in the future.  */
560 struct dentry *ext2_lookup(struct inode *dir, struct dentry *dentry,
561                            struct nameidata *nd)
562 {
563         assert(S_ISDIR(dir->i_mode));
564         struct ext2_dirent *dir_buf, *dir_i;
565         unsigned int dir_block = 0;
566         bool found = FALSE;
567         dir_buf = ext2_read_ino_block(dir, dir_block++);
568         dir_i = dir_buf;
569         /* now we have the first block worth of dirents.  We'll get another block if
570          * dir_i hits a block boundary */
571         for (unsigned int bytes = 0; bytes < dir->i_size; ) {
572                 /* On subsequent loops, we might need to advance to the next block */
573                 if ((void*)dir_i >= (void*)dir_buf + dir->i_sb->s_blocksize) {
574                         kfree(dir_buf);
575                         dir_buf = ext2_read_ino_block(dir, dir_block++);
576                         dir_i = dir_buf;
577                         assert(dir_buf);
578                 }
579                 /* Test if we're the one (TODO: use d_compare) */
580                 if (!strncmp((char*)dir_i->dir_name, dentry->d_name.name,
581                              dir_i->dir_namelen)){
582                         load_inode(dentry, le32_to_cpu(dir_i->dir_inode));
583                         /* TODO: (HASH) add dentry to dcache (maybe the caller should) */
584                         kfree(dir_buf);
585                         return dentry;
586                 }
587                 /* Get ready for the next loop */
588                 bytes += dir_i->dir_reclen;
589                 dir_i = (void*)dir_i + dir_i->dir_reclen;
590         }
591         printd("EXT2: Not Found, %s\n", dentry->d_name.name);   
592         kref_put(&dentry->d_kref);
593         kfree(dir_buf);
594         return 0;
595 }
596
597 /* Hard link to old_dentry in directory dir with a name specified by new_dentry.
598  * At the very least, set the new_dentry's FS-specific fields. */
599 int ext2_link(struct dentry *old_dentry, struct inode *dir,
600              struct dentry *new_dentry)
601 {
602 I_AM_HERE;
603         assert(new_dentry->d_op = &ext2_d_op);
604         return 0;
605 }
606
607 /* Removes the link from the dentry in the directory */
608 int ext2_unlink(struct inode *dir, struct dentry *dentry)
609 {
610 I_AM_HERE;
611         return 0;
612 }
613
614 /* Creates a new inode for a symlink dir, linking to / containing the name
615  * symname.  dentry is the controlling dentry of the inode. */
616 int ext2_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
617 {
618 I_AM_HERE;
619         #if 0
620         struct inode *inode = dentry->d_inode;
621         SET_FTYPE(inode->i_mode, __S_IFLNK);
622         inode->i_fop = &ext2_f_op_sym;
623         strncpy(string, symname, len);
624         string[len] = '\0';             /* symname should be \0d anyway, but just in case */
625         #endif
626         return 0;
627 }
628
629 /* Called when creating a new inode for a directory associated with dentry in
630  * dir with the given mode.  Note, we might (later) need to track subdirs within
631  * the parent inode, like we do with regular files.  I'd rather not, so we'll
632  * see if we need it. */
633 int ext2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
634 {
635 I_AM_HERE;
636         #if 0
637         struct inode *inode = dentry->d_inode;
638         inode->i_ino = ext2_get_free_ino();
639         SET_FTYPE(inode->i_mode, __S_IFDIR);
640         inode->i_fop = &ext2_f_op_dir;
641         #endif
642         return 0;
643 }
644
645 /* Removes from dir the directory 'dentry.'  Ext2 doesn't store anything in the
646  * inode for which children it has.  It probably should, but since everything is
647  * pinned, it just relies on the dentry connections. */
648 int ext2_rmdir(struct inode *dir, struct dentry *dentry)
649 {
650 I_AM_HERE;
651         return 0;
652 }
653
654 /* Used to make a generic file, based on the type and the major/minor numbers
655  * (in rdev), with the given mode.  As with others, this creates a new disk
656  * inode for the file */
657 int ext2_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
658 {
659 I_AM_HERE;
660         return -1;
661 }
662
663 /* Moves old_dentry from old_dir to new_dentry in new_dir */
664 int ext2_rename(struct inode *old_dir, struct dentry *old_dentry,
665                struct inode *new_dir, struct dentry *new_dentry)
666 {
667 I_AM_HERE;
668         return -1;
669 }
670
671 /* Returns the char* for the symname for the given dentry.  The VFS code that
672  * calls this for real FS's might assume it's already read in, so if the char *
673  * isn't already in memory, we'd need to read it in here.  Regarding the char*
674  * storage, the char* only will last as long as the dentry and inode are in
675  * memory. */
676 char *ext2_readlink(struct dentry *dentry)
677 {
678 I_AM_HERE;
679         struct inode *inode = dentry->d_inode;
680         if (!S_ISLNK(inode->i_mode))
681                 return 0;
682         return 0;
683 }
684
685 /* Modifies the size of the file of inode to whatever its i_size is set to */
686 void ext2_truncate(struct inode *inode)
687 {
688 }
689
690 /* Checks whether the the access mode is allowed for the file belonging to the
691  * inode.  Implies that the permissions are on the file, and not the hardlink */
692 int ext2_permission(struct inode *inode, int mode, struct nameidata *nd)
693 {
694         return -1;
695 }
696
697
698 /* dentry_operations */
699 /* Determines if the dentry is still valid before using it to translate a path.
700  * Network FS's need to deal with this. */
701 int ext2_d_revalidate(struct dentry *dir, struct nameidata *nd)
702 { // default, nothing
703         return -1;
704 }
705
706 /* Produces the hash to lookup this dentry from the dcache */
707 int ext2_d_hash(struct dentry *dentry, struct qstr *name)
708 {
709         return -1;
710 }
711
712 /* Compares name1 and name2.  name1 should be a member of dir. */
713 int ext2_d_compare(struct dentry *dir, struct qstr *name1, struct qstr *name2)
714 { // default, string comp (case sensitive)
715         return -1;
716 }
717
718 /* Called when the last ref is deleted (refcnt == 0) */
719 int ext2_d_delete(struct dentry *dentry)
720 { // default, nothin
721         return -1;
722 }
723
724 /* Called when it's about to be slab-freed */
725 int ext2_d_release(struct dentry *dentry)
726 {
727         return -1;
728 }
729
730 /* Called when the dentry loses it's inode (becomes "negative") */
731 void ext2_d_iput(struct dentry *dentry, struct inode *inode)
732 { // default, call i_put to release the inode object
733 }
734
735
736 /* file_operations */
737
738 /* Updates the file pointer.  Ext2 doesn't let you go past the end of a file
739  * yet, so it won't let you seek past either.  TODO: think about locking. */
740 off_t ext2_llseek(struct file *file, off_t offset, int whence)
741 {
742 I_AM_HERE;
743         off_t temp_off = 0;
744         #if 0
745         switch (whence) {
746                 case SEEK_SET:
747                         temp_off = offset;
748                         break;
749                 case SEEK_CUR:
750                         temp_off = file->f_pos + offset;
751                         break;
752                 case SEEK_END:
753                         temp_off = file->f_dentry->d_inode->i_size + offset;
754                         break;
755                 default:
756                         set_errno(EINVAL);
757                         warn("Unknown 'whence' in llseek()!\n");
758                         return -1;
759         }
760         /* make sure the f_pos isn't outside the limits of the existing file.
761          * techincally, if they go too far, we should return EINVAL */
762         temp_off = MAX(MIN(temp_off, file->f_dentry->d_inode->i_size), 0);
763         file->f_pos = temp_off;
764         #endif
765         return temp_off;
766 }
767
768 /* Fills in the next directory entry (dirent), starting with d_off.  Like with
769  * read and write, there will be issues with userspace and the *dirent buf.
770  * TODO: (UMEM) */
771 int ext2_readdir(struct file *dir, struct dirent *dirent)
772 {
773         void *buffer;
774         /* Not enough data at the end of the directory */
775         if (dir->f_dentry->d_inode->i_size <
776             dirent->d_off + sizeof(struct ext2_dirent))
777                 return -ENOENT;
778         
779         /* Figure out which block we need to read in for dirent->d_off */
780         int block = dirent->d_off / dir->f_dentry->d_sb->s_blocksize;
781         buffer = ext2_read_ino_block(dir->f_dentry->d_inode, block);
782         assert(buffer);
783         off_t f_off = dirent->d_off % dir->f_dentry->d_sb->s_blocksize;
784         /* Copy out the dirent info */
785         struct ext2_dirent *e2dir = (struct ext2_dirent*)(buffer + f_off);
786         dirent->d_ino = le32_to_cpu(e2dir->dir_inode);
787         dirent->d_off += le16_to_cpu(e2dir->dir_reclen);
788         /* note, dir_namelen doesn't include the \0 */
789         dirent->d_reclen = e2dir->dir_namelen;
790         strncpy(dirent->d_name, (char*)e2dir->dir_name, e2dir->dir_namelen);
791         assert(e2dir->dir_namelen <= MAX_FILENAME_SZ);
792         dirent->d_name[e2dir->dir_namelen] = '\0';
793         kfree(buffer);
794         
795         /* At the end of the directory, sort of.  ext2 often preallocates blocks, so
796          * this will cause us to walk along til the end, which isn't quite right. */
797         if (dir->f_dentry->d_inode->i_size == dirent->d_off)
798                 return 0;
799         if (dir->f_dentry->d_inode->i_size < dirent->d_off) {
800                 warn("Issues reaching the end of an ext2 directory!");
801                 return 0;
802         }
803         return 1;                                                       /* normal success for readdir */
804 }
805
806 /* This is called when a VMR is mapping a particular file.  The FS needs to do
807  * whatever it needs so that faults can be handled by read_page(), and handle all
808  * of the cases of MAP_SHARED, MAP_PRIVATE, whatever.  It also needs to ensure
809  * the file is not being mmaped in a way that conflicts with the manner in which
810  * the file was opened or the file type. */
811 int ext2_mmap(struct file *file, struct vm_region *vmr)
812 {
813         if (S_ISREG(file->f_dentry->d_inode->i_mode))
814                 return 0;
815         return -1;
816 }
817
818 /* Called by the VFS while opening the file, which corresponds to inode,  for
819  * the FS to do whatever it needs. */
820 int ext2_open(struct inode *inode, struct file *file)
821 {
822         /* TODO: check to make sure the file is openable, and maybe do some checks
823          * for the open mode (like did we want to truncate, append, etc) */
824         return 0;
825 }
826
827 /* Called when a file descriptor is closed. */
828 int ext2_flush(struct file *file)
829 {
830 I_AM_HERE;
831         return -1;
832 }
833
834 /* Called when the file is about to be closed (file obj freed) */
835 int ext2_release(struct inode *inode, struct file *file)
836 {
837         return 0;
838 }
839
840 /* Flushes the file's dirty contents to disc */
841 int ext2_fsync(struct file *file, struct dentry *dentry, int datasync)
842 {
843         return -1;
844 }
845
846 /* Traditionally, sleeps until there is file activity.  We probably won't
847  * support this, or we'll handle it differently. */
848 unsigned int ext2_poll(struct file *file, struct poll_table_struct *poll_table)
849 {
850         return -1;
851 }
852
853 /* Reads count bytes from a file, starting from (and modifiying) offset, and
854  * putting the bytes into buffers described by vector */
855 ssize_t ext2_readv(struct file *file, const struct iovec *vector,
856                   unsigned long count, off_t *offset)
857 {
858         return -1;
859 }
860
861 /* Writes count bytes to a file, starting from (and modifiying) offset, and
862  * taking the bytes from buffers described by vector */
863 ssize_t ext2_writev(struct file *file, const struct iovec *vector,
864                   unsigned long count, off_t *offset)
865 {
866         return -1;
867 }
868
869 /* Write the contents of file to the page.  Will sort the params later */
870 ssize_t ext2_sendpage(struct file *file, struct page *page, int offset,
871                      size_t size, off_t pos, int more)
872 {
873         return -1;
874 }
875
876 /* Checks random FS flags.  Used by NFS. */
877 int ext2_check_flags(int flags)
878 { // default, nothing
879         return -1;
880 }
881
882 /* Redeclaration and initialization of the FS ops structures */
883 struct page_map_operations ext2_pm_op = {
884         ext2_readpage,
885 };
886
887 struct super_operations ext2_s_op = {
888         ext2_alloc_inode,
889         ext2_dealloc_inode,
890         ext2_read_inode,
891         ext2_dirty_inode,
892         ext2_write_inode,
893         ext2_put_inode,
894         ext2_drop_inode,
895         ext2_delete_inode,
896         ext2_put_super,
897         ext2_write_super,
898         ext2_sync_fs,
899         ext2_remount_fs,
900         ext2_umount_begin,
901 };
902
903 struct inode_operations ext2_i_op = {
904         ext2_create,
905         ext2_lookup,
906         ext2_link,
907         ext2_unlink,
908         ext2_symlink,
909         ext2_mkdir,
910         ext2_rmdir,
911         ext2_mknod,
912         ext2_rename,
913         ext2_readlink,
914         ext2_truncate,
915         ext2_permission,
916 };
917
918 struct dentry_operations ext2_d_op = {
919         ext2_d_revalidate,
920         ext2_d_hash,
921         ext2_d_compare,
922         ext2_d_delete,
923         ext2_d_release,
924         ext2_d_iput,
925 };
926
927 struct file_operations ext2_f_op_file = {
928         ext2_llseek,
929         generic_file_read,
930         generic_file_write,
931         ext2_readdir,
932         ext2_mmap,
933         ext2_open,
934         ext2_flush,
935         ext2_release,
936         ext2_fsync,
937         ext2_poll,
938         ext2_readv,
939         ext2_writev,
940         ext2_sendpage,
941         ext2_check_flags,
942 };
943
944 struct file_operations ext2_f_op_dir = {
945         ext2_llseek,
946         generic_dir_read,
947         0,
948         ext2_readdir,
949         ext2_mmap,
950         ext2_open,
951         ext2_flush,
952         ext2_release,
953         ext2_fsync,
954         ext2_poll,
955         ext2_readv,
956         ext2_writev,
957         ext2_sendpage,
958         ext2_check_flags,
959 };
960
961 struct file_operations ext2_f_op_sym = {
962         ext2_llseek,
963         generic_file_read,
964         generic_file_write,
965         ext2_readdir,
966         ext2_mmap,
967         ext2_open,
968         ext2_flush,
969         ext2_release,
970         ext2_fsync,
971         ext2_poll,
972         ext2_readv,
973         ext2_writev,
974         ext2_sendpage,
975         ext2_check_flags,
976 };