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