Removed the KFS file entries (raw apps)
[akaros.git] / kern / src / kfs.c
1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Implementation of the KFS file system.  It is a RAM based, read-only FS
6  * consisting of files that are added to the kernel binary image.  Might turn
7  * this into a read/write FS with directories someday. */
8
9 #ifdef __SHARC__
10 #pragma nosharc
11 #endif
12
13 #ifdef __DEPUTY__
14 #pragma nodeputy
15 #endif
16
17 #include <vfs.h>
18 #include <kfs.h>
19 #include <slab.h>
20 #include <kmalloc.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <assert.h>
24 #include <error.h>
25 #include <cpio.h>
26
27 #define KFS_MAX_FILE_SIZE 1024*1024*128
28 #define KFS_MAGIC 0xdead0001
29
30 /* VFS required Functions */
31 /* These structs are declared again and initialized farther down */
32 struct super_operations kfs_s_op;
33 struct inode_operations kfs_i_op;
34 struct dentry_operations kfs_d_op;
35 struct file_operations kfs_f_op;
36
37 /* Creates the SB (normally would read in from disc and create).  Ups the refcnt
38  * for whoever consumes this.  Returns 0 on failure.
39  * TODO: consider pulling out more of the FS-independent stuff, if possible.
40  * There are only two things, but the pain in the ass is that you'd need to read
41  * the disc to get that first inode, and it's a FS-specific thing. */
42 struct super_block *kfs_get_sb(struct fs_type *fs, int flags,
43                                char *dev_name, struct vfsmount *vmnt)
44 {
45         /* Ought to check that dev_name has our FS on it.  in this case, it's
46          * irrelevant. */
47         //if (something_bad)
48         //      return 0;
49
50         /* Build and init the SB.  No need to read off disc. */
51         struct super_block *sb = get_sb();
52         sb->s_dev = 0;
53         sb->s_blocksize = 4096; /* or 512.  haven't thought this through */
54         sb->s_maxbytes = KFS_MAX_FILE_SIZE;
55         sb->s_type = &kfs_fs_type;
56         sb->s_op = &kfs_s_op;
57         sb->s_flags = flags;
58         sb->s_magic = KFS_MAGIC;
59         sb->s_mount = vmnt;
60         sb->s_syncing = FALSE;
61         sb->s_bdev = 0;
62         strlcpy(sb->s_name, "KFS", 32);
63         /* store the location of the CPIO archive.  make this more generic later. */
64         extern uint8_t _binary_obj_kern_initramfs_cpio_size[];
65         extern uint8_t _binary_obj_kern_initramfs_cpio_start[];
66         sb->s_fs_info = (void*)_binary_obj_kern_initramfs_cpio_start;
67
68         /* Final stages of initializing the sb, mostly FS-independent */
69         init_sb(sb, vmnt, &kfs_d_op, 1); /* 1 is the KFS root ino (inode number) */
70         printk("KFS superblock loaded\n");
71
72         /* Or whatever.  For now, just check to see the archive worked. */
73         print_cpio_entries(sb->s_fs_info);
74
75         return sb;
76 }
77
78 void kfs_kill_sb(struct super_block *sb)
79 {
80         panic("Killing KFS is not supported!");
81 }
82
83 /* Every FS must have a static FS Type, with which the VFS code can bootstrap */
84 struct fs_type kfs_fs_type = {"KFS", 0, kfs_get_sb, kfs_kill_sb, {0, 0},
85                TAILQ_HEAD_INITIALIZER(kfs_fs_type.fs_supers)};
86
87 /* Super Operations */
88
89 /* creates and initializes a new inode.  generic fields are filled in.  specific
90  * fields are filled in in read_inode() based on what's on the disk for a given
91  * i_no.  i_no is set by the caller. */
92 struct inode *kfs_alloc_inode(struct super_block *sb)
93 {
94         /* arguably, we can avoid some of this init by using the slab/cache */
95         struct inode *inode = kmem_cache_alloc(inode_kcache, 0);
96         memset(inode, 0, sizeof(struct inode));
97         TAILQ_INSERT_HEAD(&sb->s_inodes, inode, i_sb_list);
98         TAILQ_INIT(&inode->i_dentry);
99         inode->i_ino = 0;                                       /* set by caller later */
100         atomic_set(&inode->i_refcnt, 1);
101         inode->i_blksize = 4096;                        /* keep in sync with get_sb() */
102         spinlock_init(&inode->i_lock);
103         inode->i_op = &kfs_i_op;
104         inode->i_fop = &kfs_f_op;
105         inode->i_sb = sb;
106         inode->i_state = 0;                                     /* need real states, want I_NEW */
107         inode->dirtied_when = 0;
108         atomic_set(&inode->i_writecount, 0);
109         inode->i_fs_info = 0;
110         return inode;
111         /* caller sets i_ino, i_list set when applicable */
112 }
113
114 /* deallocs and cleans up after an inode. */
115 void kfs_destroy_inode(struct inode *inode)
116 {
117         kmem_cache_free(inode_kcache, inode);
118 }
119
120 /* reads the inode data on disk specified by inode->i_ino into the inode.
121  * basically, it's a "make this inode the one for i_ino (i number)" */
122 void kfs_read_inode(struct inode *inode)
123 {
124         /* need to do something to link this inode/file to the actual "blocks" on
125          * "disk". */
126
127         /* TODO: what does it mean to ask for an inode->i_ino that doesn't exist?
128          *      possibly a bug, since these inos come from directories */
129         if (inode->i_ino == 1) {
130                 inode->i_mode = 0x777;                  /* TODO: use something appropriate */
131                 inode->i_nlink = 1;                             /* assuming only one hardlink */
132                 inode->i_uid = 0;
133                 inode->i_gid = 0;
134                 inode->i_rdev = 0;
135                 inode->i_size = 0;                              /* make sense for KFS? */
136                 inode->i_atime.tv_sec = 0;
137                 inode->i_atime.tv_nsec = 0;
138                 inode->i_mtime.tv_sec = 0;
139                 inode->i_mtime.tv_nsec = 0;
140                 inode->i_ctime.tv_sec = 0;
141                 inode->i_ctime.tv_nsec = 0;
142                 inode->i_blksize = 0;
143                 inode->i_blocks = 0;
144                 inode->i_bdev = 0;                              /* assuming blockdev? */
145                 inode->dirtied_when = 0;
146                 inode->i_flags = 0;
147                 inode->i_socket = FALSE;
148         } else {
149                 panic("Not implemented");
150         }
151         /* TODO: unused: inode->i_hash add to hash (saves on disc reading)
152          * i_mapping, i_data, when they mean something */
153 }
154
155 /* called when an inode in memory is modified (journalling FS's care) */
156 void kfs_dirty_inode(struct inode *inode)
157 {       // KFS doesn't care
158 }
159
160 /* write the inode to disk (specifically, to inode inode->i_ino), synchronously
161  * if we're asked to wait */
162 void kfs_write_inode(struct inode *inode, bool wait)
163 {       // KFS doesn't care
164 }
165
166 /* called when an inode is decref'd, to do any FS specific work */
167 void kfs_put_inode(struct inode *inode)
168 {       // KFS doesn't care
169 }
170
171 /* called when an inode is about to be destroyed.  the generic version ought to
172  * remove every reference to the inode from the VFS, and if the inode isn't in
173  * any directory, calls delete_inode */
174 void kfs_drop_inode(struct inode *inode)
175 { // TODO: should call a generic one instead.  or at least do something...
176         // remove from lists
177 }
178
179 /* delete the inode from disk (all data) and deallocs the in memory inode */
180 void kfs_delete_inode(struct inode *inode)
181 {
182         // would remove from "disk" here
183         kfs_destroy_inode(inode);
184 }
185
186 /* unmount and release the super block */
187 void kfs_put_super(struct super_block *sb)
188 {
189         panic("Shazbot! KFS can't be unmounted yet!");
190 }
191
192 /* updates the on-disk SB with the in-memory SB */
193 void kfs_write_super(struct super_block *sb)
194 {       // KFS doesn't care
195 }
196
197 /* syncs FS metadata with the disc, synchronously if we're waiting.  this info
198  * also includes anything pointed to by s_fs_info. */
199 int kfs_sync_fs(struct super_block *sb, bool wait)
200 {
201         return 0;
202 }
203
204 /* remount the FS with the new flags */
205 int kfs_remount_fs(struct super_block *sb, int flags, char *data)
206 {
207         warn("KFS will not remount.");
208         return -1; // can't remount
209 }
210
211 /* interrupts a mount operation - used by NFS and friends */
212 void kfs_umount_begin(struct super_block *sb)
213 {
214         panic("Cannot abort a KFS mount, and why would you?");
215 }
216
217 /* inode_operations */
218
219 /* Create a new disk inode in dir associated with dentry, with the given mode.
220  * called when creating or opening a regular file  (TODO probably not open) */
221 int kfs_create(struct inode *dir, struct dentry *dentry, int mode,
222                struct nameidata *nd)
223 {
224         // TODO: how exactly does this work when we open a file?  and what about
225         // when we need an inode to fill in a dentry structure?
226         // seems like we can use this to fill it in, instead of having the inode
227         // filled in at dentry creation
228         //      - diff between dentry creation for an existing path and a new one (open
229         //      vs create)
230         //      - this might just be for a brand new one (find a free inode, give it to
231         //      me, etc)
232         //
233         //      note it is the i_ino that uniquely identifies a file in the system.
234         //              there's a diff between creating an inode (even for an in-use ino)
235         //              and then filling it in, and vs creating a brand new one
236         //
237         //dentry with d_inode == NULL -> ENOENT (negative entry?)
238         //      linux now has a nameidata for this
239         //
240         //presence of a lookup op (in linux) shows it is a directory... np
241         //same with symlink
242         //their link depth is tied to the task_struct (for max, not for one path)
243         return -1;
244 }
245
246 /* Searches the directory for the filename in the dentry, filling in the dentry
247  * with the FS specific info of this file */
248 struct dentry *kfs_lookup(struct inode *dir, struct dentry *dentry,
249                           struct nameidata *nd)
250 {
251         // TODO: does this mean the inode too?
252         // what the hell are we returning?  the passed in dentry?  an error code?
253         // this will have to read the directory, then find the ino, then creates a
254         // dentry for it
255         //
256         // linux now has a nameidata for this
257         return 0;
258 }
259
260 /* Hard link to old_dentry in directory dir with a name specified by new_dentry.
261  * TODO: should this also make the dentry linkage, or just discard everything?*/
262 int kfs_link(struct dentry *old_dentry, struct inode *dir,
263              struct dentry *new_dentry)
264 {
265         return -1;
266 }
267
268 /* Removes the link from the dentry in the directory */
269 int kfs_unlink(struct inode *dir, struct dentry *dentry)
270 {
271         return -1;
272 }
273
274 /* Creates a new inode for a symlink named symname in dir, and links to dentry.
275  * */
276 int kfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
277 {
278         return -1;
279 }
280
281 /* Creates a new inode for a directory associated with dentry in dir with the
282  * given mode */
283 int kfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
284 {
285         return -1;
286 }
287
288 /* Removes from dir the directory specified by the name in dentry. */
289 // TODO: note this isn't necessarily the same dentry, just using it for the
290 // naming (which seems to be a common way of doing things, like in lookup() -
291 // can work either way.
292 int kfs_rmdir(struct inode *dir, struct dentry *dentry)
293 {
294         return -1;
295 }
296
297 /* Used to make a generic file, based on the type and the major/minor numbers
298  * (in rdev), with the given mode.  As with others, this creates a new disk
299  * inode for the file */
300 int kfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
301 {
302         return -1;
303 }
304
305 /* Moves old_dentry from old_dir to new_dentry in new_dir */
306 int kfs_rename(struct inode *old_dir, struct dentry *old_dentry,
307                struct inode *new_dir, struct dentry *new_dentry)
308 {
309         return -1;
310 }
311
312 /* Copies to the userspace buffer the file pathname corresponding to the symlink
313  * specified by dentry. */
314 int kfs_readlink(struct dentry *dentry, char *buffer, size_t buflen)
315 {
316         return -1;
317 }
318
319 /* Translates the symlink specified by sym and puts the result in nd. */
320 int kfs_follow_link(struct dentry *sym, struct nameidata *nd)
321 {
322         return -1;
323 }
324
325 /* Cleans up after follow_link (decrefs the nameidata business) */
326 int kfs_put_link(struct dentry *sym, struct nameidata *nd)
327 {
328         return -1;
329 }
330
331 /* Modifies the size of the file of inode to whatever its i_size is set to */
332 void kfs_truncate(struct inode *inode)
333 {
334 }
335
336 /* Checks whether the the access mode is allowed for the file belonging to the
337  * inode.  Implies that the permissions are on the file, and not the hardlink */
338 int kfs_permission(struct inode *inode, int mode, struct nameidata *nd)
339 {
340         return -1;
341 }
342
343
344 /* dentry_operations */
345 /* Determines if the dentry is still valid before using it to translate a path.
346  * Network FS's need to deal with this. */
347 int kfs_d_revalidate(struct dentry *dir, struct nameidata *nd)
348 { // default, nothing
349         return -1;
350 }
351
352 /* Produces the hash to lookup this dentry from the dcache */
353 int kfs_d_hash(struct dentry *dentry, struct qstr *name)
354 {
355         return -1;
356 }
357
358 /* Compares name1 and name2.  name1 should be a member of dir. */
359 int kfs_d_compare(struct dentry *dir, struct qstr *name1, struct qstr *name2)
360 { // default, string comp (case sensitive)
361         return -1;
362 }
363
364 /* Called when the last ref is deleted (refcnt == 0) */
365 int kfs_d_delete(struct dentry *dentry)
366 { // default, nothin
367         return -1;
368 }
369
370 /* Called when it's about to be slab-freed */
371 int kfs_d_release(struct dentry *dentry)
372 { // default, nothin
373         return -1;
374 }
375
376 /* Called when the dentry loses it's inode (becomes "negative") */
377 void kfs_d_iput(struct dentry *dentry, struct inode *inode)
378 { // default, call i_put to release the inode object
379 }
380
381
382 /* file_operations */
383
384 /* Updates the file pointer */
385 off_t kfs_llseek(struct file *file, off_t offset, int whence)
386 {
387         return -1;
388 }
389
390 /* Read cound bytes from the file into buf, starting at *offset, which is increased
391  * accordingly */
392 ssize_t kfs_read(struct file *file, char *buf, size_t count, off_t *offset)
393 {
394         return -1;
395 }
396
397 /* Writes count bytes from buf to the file, starting at *offset, which is
398  * increased accordingly */
399 ssize_t kfs_write(struct file *file, const char *buf, size_t count,
400                   off_t *offset)
401 {
402         return -1;
403 }
404
405 /* Fills in the next directory entry (dirent), starting with d_off */
406 int kfs_readdir(struct file *dir, struct dirent *dirent)
407 {
408         return -1;
409 }
410
411 /* Memory maps the file into the virtual memory area */
412 int kfs_mmap(struct file *file, struct vm_area_struct *vma)
413 {
414         return -1;
415 }
416
417 /* Opens the file specified by the inode, creating and filling in the file */
418 /* TODO: fill out the other // entries, sort vmnt refcnting */
419 int kfs_open(struct inode *inode, struct file *file)
420 {
421         /* This is mostly FS-agnostic, consider a helper */
422         file = kmem_cache_alloc(file_kcache, 0);
423         /* Add to the list of all files of this SB */
424         TAILQ_INSERT_TAIL(&inode->i_sb->s_files, file, f_list);
425         file->f_inode = inode;
426         atomic_inc(&inode->i_refcnt);
427         file->f_vfsmnt = inode->i_sb->s_mount;          /* saving a ref to the vmnt...*/
428         file->f_op = &kfs_f_op;
429         atomic_set(&file->f_refcnt, 1);                         /* ref passed out */
430         file->f_flags = inode->i_flags;                         /* just taking the inode vals */
431         file->f_mode = inode->i_mode;
432         file->f_pos = 0;
433         file->f_uid = inode->i_uid;
434         file->f_gid = inode->i_gid;
435         file->f_error = 0;
436 //      struct event_poll_tailq         f_ep_links;
437         spinlock_init(&file->f_ep_lock);
438         file->f_fs_info = 0;
439 //      struct address_space            *f_mapping;             /* page cache mapping */
440         return 0;
441 }
442
443 /* Called when a file descriptor is closed. */
444 int kfs_flush(struct file *file)
445 {
446         kmem_cache_free(file_kcache, file);
447         return -1;
448 }
449
450 /* Called when the file refcnt == 0 */
451 int kfs_release(struct inode *inode, struct file *file)
452 {
453         return -1;
454 }
455
456 /* Flushes the file's dirty contents to disc */
457 int kfs_fsync(struct file *file, struct dentry *dentry, int datasync)
458 {
459         return -1;
460 }
461
462 /* Traditionally, sleeps until there is file activity.  We probably won't
463  * support this, or we'll handle it differently. */
464 unsigned int kfs_poll(struct file *file, struct poll_table_struct *poll_table)
465 {
466         return -1;
467 }
468
469 /* Reads count bytes from a file, starting from (and modifiying) offset, and
470  * putting the bytes into buffers described by vector */
471 ssize_t kfs_readv(struct file *file, const struct iovec *vector,
472                   unsigned long count, off_t *offset)
473 {
474         return -1;
475 }
476
477 /* Writes count bytes to a file, starting from (and modifiying) offset, and
478  * taking the bytes from buffers described by vector */
479 ssize_t kfs_writev(struct file *file, const struct iovec *vector,
480                   unsigned long count, off_t *offset)
481 {
482         return -1;
483 }
484
485 /* Write the contents of file to the page.  Will sort the params later */
486 ssize_t kfs_sendpage(struct file *file, struct page *page, int offset,
487                      size_t size, off_t pos, int more)
488 {
489         return -1;
490 }
491
492 /* Checks random FS flags.  Used by NFS. */
493 int kfs_check_flags(int flags)
494 { // default, nothing
495         return -1;
496 }
497
498 /* Redeclaration and initialization of the FS ops structures */
499 struct super_operations kfs_s_op = {
500         kfs_alloc_inode,
501         kfs_destroy_inode,
502         kfs_read_inode,
503         kfs_dirty_inode,
504         kfs_write_inode,
505         kfs_put_inode,
506         kfs_drop_inode,
507         kfs_delete_inode,
508         kfs_put_super,
509         kfs_write_super,
510         kfs_sync_fs,
511         kfs_remount_fs,
512         kfs_umount_begin,
513 };
514
515 struct inode_operations kfs_i_op = {
516         kfs_create,
517         kfs_lookup,
518         kfs_link,
519         kfs_unlink,
520         kfs_symlink,
521         kfs_mkdir,
522         kfs_rmdir,
523         kfs_mknod,
524         kfs_rename,
525         kfs_readlink,
526         kfs_follow_link,
527         kfs_put_link,
528         kfs_truncate,
529         kfs_permission,
530 };
531
532 struct dentry_operations kfs_d_op = {
533         kfs_d_revalidate,
534         kfs_d_hash,
535         kfs_d_compare,
536         kfs_d_delete,
537         kfs_d_release,
538         kfs_d_iput,
539 };
540
541 struct file_operations kfs_f_op = {
542         kfs_llseek,
543         kfs_read,
544         kfs_write,
545         kfs_readdir,
546         kfs_mmap,
547         kfs_open,
548         kfs_flush,
549         kfs_release,
550         kfs_fsync,
551         kfs_poll,
552         kfs_readv,
553         kfs_writev,
554         kfs_sendpage,
555         kfs_check_flags,
556 };
557
558 /* KFS Specific Internal Functions */
559
560 /* For obj files compiled with the kernel */
561 #define DECL_PROG(x) \
562     extern uint8_t (COUNT(sizeof(size_t)) _binary_obj_tests_##x##_size)[],\
563         (COUNT(_binary_obj_user_apps_##x##_size)_binary_obj_tests_##x##_start)[];
564
565 #define KFS_PENTRY(x) {#x, _binary_obj_tests_##x##_start, (size_t) _binary_obj_tests_##x##_size},
566
567 /*
568  * Hardcode the files included in the KFS.  PROGs need to be in sync with the
569  * userapps in kern/src/Makefrag.  Files need to be in kern/kfs/
570  * Make sure to declare it, and add an entry.  Keep MAX_KFS_FILES big enough too
571  * Note that files with a . in their name will have an _ instead.
572  */
573 #ifdef __CONFIG_KFS__
574 DECL_PROG(tlstest);
575 DECL_PROG(fp_test);
576 DECL_PROG(mproctests);
577 DECL_PROG(hello);
578 DECL_PROG(mhello);
579 DECL_PROG(pthread_test);
580 DECL_PROG(pthread_barrier_test);
581 DECL_PROG(idle);
582 DECL_PROG(tsc_spitter);
583 DECL_PROG(msr_get_cores);
584 DECL_PROG(msr_get_singlecore);
585 DECL_PROG(msr_dumb_while);
586 DECL_PROG(msr_nice_while);
587 DECL_PROG(msr_single_while);
588 DECL_PROG(msr_cycling_vcores);
589 #endif
590
591 struct kfs_entry kfs[MAX_KFS_FILES] = {
592 #ifdef __CONFIG_KFS__
593         KFS_PENTRY(tlstest)
594         KFS_PENTRY(fp_test)
595         KFS_PENTRY(mproctests)
596         KFS_PENTRY(hello)
597         KFS_PENTRY(mhello)
598         KFS_PENTRY(pthread_test)
599         KFS_PENTRY(pthread_barrier_test)
600         KFS_PENTRY(idle)
601         KFS_PENTRY(tsc_spitter)
602         KFS_PENTRY(msr_get_cores)
603         KFS_PENTRY(msr_get_singlecore)
604         KFS_PENTRY(msr_dumb_while)
605         KFS_PENTRY(msr_nice_while)
606         KFS_PENTRY(msr_single_while)
607         KFS_PENTRY(msr_cycling_vcores)
608 #endif
609 };
610
611 ssize_t kfs_lookup_path(char* path)
612 {
613         for (int i = 0; i < MAX_KFS_FILES; i++)
614                 // need to think about how to copy-in something of unknown length
615                 if (!strncmp(kfs[i].name, path, strlen(path)))
616                         return i;
617         return -EINVAL;
618 }
619
620 /*
621  * Creates a process from the file pointed to by the KFS inode (index)
622  * This should take a real inode or something to point to the real location,
623  * and proc_create shouldn't assume everything is contiguous
624  */
625 struct proc *kfs_proc_create(int kfs_inode)
626 {
627         if (kfs_inode < 0 || kfs_inode >= MAX_KFS_FILES)
628                 panic("Invalid kfs_inode.  Check you error codes!");
629         return proc_create(kfs[kfs_inode].start, kfs[kfs_inode].size);
630 }
631
632 /* Dumps the contents of the KFS file to the console.  Not meant to be taken
633  * too seriously - just dumps each char. */
634 void kfs_cat(int kfs_inode)
635 {
636         if (kfs_inode < 0 || kfs_inode >= MAX_KFS_FILES)
637                 panic("Invalid kfs_inode.  Check you error codes!");
638         uint8_t *end = kfs[kfs_inode].start + kfs[kfs_inode].size;
639         for (uint8_t *ptr = kfs[kfs_inode].start; ptr < end; ptr++)
640                 cputchar(*ptr);
641 }
642
643 void print_cpio_entries(void *cpio_b)
644 {
645         struct cpio_newc_header *c_hdr = (struct cpio_newc_header*)cpio_b;
646
647         char buf[9] = {0};      /* temp space for strol conversions */
648         int size = 0;
649         int offset = 0;         /* offset in the cpio archive */
650
651         /* read all files and paths */
652         for (; ; c_hdr = (struct cpio_newc_header*)(cpio_b + offset)) {
653                 offset += sizeof(*c_hdr);
654                 if (strncmp(c_hdr->c_magic, "070701", 6)) {
655                         printk("Invalid magic number in CPIO header, aborting.\n");
656                         return;
657                 }
658                 printd("namesize: %.8s\n", c_hdr->c_namesize);
659                 printd("filesize: %.8s\n", c_hdr->c_filesize);
660                 memcpy(buf, c_hdr->c_namesize, 8);
661                 buf[8] = '\0';
662                 size = strtol(buf, 0, 16);
663                 printd("Namesize: %d\n", size);
664                 if (!strcmp((char*)c_hdr + sizeof(*c_hdr), "TRAILER!!!"))
665                         break;
666                 printk("File: %s: ", (char*)c_hdr + sizeof(*c_hdr));
667                 offset += size;
668                 /* header + name will be padded out to 4-byte alignment */
669                 offset = ROUNDUP(offset, 4);
670                 memcpy(buf, c_hdr->c_filesize, 8);
671                 buf[8] = '\0';
672                 size = strtol(buf, 0, 16);
673                 printk("%d Bytes\n", size);
674                 offset += size;
675                 offset = ROUNDUP(offset, 4);
676                 //printk("offset is %d bytes\n", offset);
677                 c_hdr = (struct cpio_newc_header*)(cpio_b + offset);
678         }
679 }