Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

tarfs_module.c

Go to the documentation of this file.
00001 
00010 /* ************************************************************************* *
00011  *                                                                           *
00012  *   This program is free software; you can redistribute it and/or modify    *
00013  *   it under the terms of the GNU General Public License as published by    *
00014  *   the Free Software Foundation; either version 2 of the License, or       *
00015  *   (at your option) any later version.                                     *
00016  *                                                                           *
00017  * ************************************************************************* */
00018 
00019 
00020 #include <linux/module.h>
00021 #include <linux/fs.h>
00022 #include <linux/types.h>
00023 #include <linux/errno.h>
00024 #include <linux/init.h>
00025 #include <linux/locks.h>
00026 #include <linux/smp_lock.h>
00027 #include "tarfs_tar.h"
00028 #include "tarfs_common.h"
00029 
00030 
00031 MODULE_DESCRIPTION("TAR FS");
00032 MODULE_AUTHOR("Petr Cermak; Jaroslav Drazan");
00033 MODULE_LICENSE("GPL");
00034 
00035 
00036 // *** forward declarations
00037 static struct super_block* tarfs_read_super(struct super_block *s, void *data, int silent);
00038 static void tarfs_read_inode(struct inode *i);
00039 static int tarfs_statfs(struct super_block *sb, struct statfs *buf);
00040 static struct dentry* tarfs_lookup(struct inode* dir, struct dentry* dentry);
00041 static int tarfs_readdir(struct file* filp, void* dirent, filldir_t filldir);
00042 static int tarfs_readpage(struct file* file, struct page* page);
00043 //static int tarfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname);
00044 
00045 // *** structures
00046 
00047 // operations on superblock
00048 static struct super_operations tarfs_ops = {
00049     read_inode: tarfs_read_inode,
00050     statfs:     tarfs_statfs,
00051 };
00052 
00053 // operations on inode
00054 static struct inode_operations tarfs_inode_ops = {
00055     lookup:     tarfs_lookup,
00056 //    symlink:    tarfs_symlink,
00057 };
00058 
00059 // operations on directories
00060 static struct file_operations tarfs_dir_ops = {
00061     read:       generic_read_dir,
00062     readdir:    tarfs_readdir,
00063 };
00064 
00065 // memory operations
00066 static struct address_space_operations tarfs_aops = {
00067     readpage:   tarfs_readpage,
00068 };
00069 
00070 // declaration of structure for our filesystem registration
00071 static DECLARE_FSTYPE_DEV(tarfs_type, FSNAME, tarfs_read_super);
00072 
00073 
00084 static struct super_block* tarfs_read_super(struct super_block *s, void *data, int silent)
00085 {
00086   int ino;
00087   kdev_t dev = s->s_dev;
00088 
00089   PRINTD("*** tarfs_read_super");
00090 
00091   set_blocksize(dev, TARFS_BLKSIZE);
00092   s->s_blocksize = TARFS_BLKSIZE;
00093   s->s_blocksize_bits = TARFS_BLKSIZE_BITS;
00094   s->u.generic_sbp = (void *) 0;
00095   s->s_maxbytes = 0xFFFFFFFF;
00096 
00097   // Zkontroluje se prvni blok - zda se jedna o tar
00098   if (!tar_quick_validation(s)) {
00099     goto EOut1;
00100   }
00101 
00102   s->s_magic = TARFS_MAGIC;
00103   s->s_flags |= MS_RDONLY;
00104   s->s_op = &tarfs_ops;
00105 
00106   if ((ino = tar_get_root_ino(s)) == TARFS_EVAL) {
00107     goto EOut1;
00108   }
00109   s->s_root = d_alloc_root(iget(s, ino));
00110 
00111   return s;
00112 
00113 EOut1:
00114   return 0;
00115 }
00116 
00117 /*
00118  * @brief Reads directory content
00119  *
00120  * Reads directory entries, until stopped by returning <0 from filldir function,
00121  * after that, it stores last entry id read into filp->f_pos. When called again,
00122  * it continues from the last f_pos stored.
00123  *
00124  * @param filp A file structure representing directory being read
00125  * @param dirent Falls through this function to the filldir call
00126  * @param filldir Pointer to a function called to add new dir entry
00127  * @return 0 - there are more entries to be read, -ENOENT no more entries to be read
00128  */
00129 static int tarfs_readdir(struct file* filp, void* dirent, filldir_t filldir)
00130 {
00131   int retval;
00132   PRINTD("*** tarfs_readdir");
00133 
00134   //printk("<1> inode: %d, filpos: %d\n", filp->f_dentry->d_inode->i_ino, filp->f_pos);
00135 
00136   retval = tar_readdir(filp, dirent, filldir);
00137 
00138   if (retval == 0 || retval == TARFS_EVAL) {   // pokud chyba tak taky skoncim
00139     return -ENOENT;
00140   } else {
00141     return 0;
00142   }
00143 }
00144 
00145 
00156 static struct dentry* tarfs_lookup(struct inode* dir, struct dentry* dentry)
00157 {
00158   struct inode* inode;
00159   unsigned long retval;
00160 
00161   PRINTD("*** tarfs_lookup");
00162   // tady kontrola + urceni cisla inodu
00163 
00164   retval = tar_lookup(dir->i_sb, dir->i_ino, dentry->d_name.name, dentry->d_name.len);
00165 
00166   inode = 0;
00167   
00168   if (retval != TARFS_EVAL) {
00169     inode = iget(dir->i_sb, retval);
00170     if (!inode) {
00171       return ERR_PTR(-EACCES);
00172     }
00173   }
00174 
00175   d_add(dentry, inode);
00176 
00177   return 0;
00178 }
00179 
00187 void tarfs_get_new_root_inode(struct inode* i)
00188 {
00189   PRINTD("*** tarfs_get_new_root_inode");
00190   i->i_nlink = 1;
00191   i->i_size = 0;
00192   i->i_atime = i->i_ctime = i->i_mtime = 0;
00193   i->i_uid = i->i_gid = 0;
00194   i->i_op = &tarfs_inode_ops;
00195   i->i_fop = &tarfs_dir_ops;
00196   i->i_mode = S_IFDIR + 0555;
00197 }
00198 
00204 static void tarfs_read_inode(struct inode *i)
00205 {
00206   int rdev = 0;
00207 
00208   PRINTD("*** tarfs_read_inode");
00209 
00210   // Pokud je to nula, root adresar nebyl pritomen v taru a musime si ho vymyslet
00211   if (i->i_ino == TARFS_ROOT_INO) {
00212     tarfs_get_new_root_inode(i);
00213     return;
00214   }
00215 
00216   switch (tar_fill_inode(i->i_sb, i, &rdev)) {
00217 
00218     case S_IFREG:
00219       i->i_fop = &generic_ro_fops;
00220       i->i_data.a_ops = &tarfs_aops;
00221       break;
00222 
00223     case S_IFDIR:
00224       i->i_op = &tarfs_inode_ops;
00225       i->i_fop = &tarfs_dir_ops;
00226       break;
00227 
00228     case S_IFLNK:
00229       i->i_op = &page_symlink_inode_operations;
00230       i->i_data.a_ops = &tarfs_aops;
00231       break;
00232 
00233     case S_IFCHR:
00234     case S_IFIFO:
00235     case S_IFBLK:
00236       init_special_inode(i, i->i_mode, rdev);
00237       break;
00238 
00239     default:
00240       break;
00241   }
00242 
00243   return;
00244 }
00245 
00255 static int tarfs_readpage(struct file* file, struct page* page)
00256 {
00257   struct inode* i = page->mapping->host;
00258   unsigned long offset;
00259   char* buf;
00260   int result = -EIO;
00261 
00262   PRINTD("*** tarfs_readpage");
00263   page_cache_get(page);
00264   lock_kernel();      // tohle je pro SMP.. je to tu potreba? bylo to v romfs
00265   buf = (char*) kmap(page);   // namapuje stranku do adr. space kernelu
00266   if (!buf) {
00267       goto err_out;
00268   }
00269 
00270   // ofset v bloku - od kolikateho b. mame cist, cte se do konce stranky
00271   offset = page->index << PAGE_CACHE_SHIFT;
00272 
00273   if (tar_read_page(i->i_sb, i, offset, buf) != TARFS_EVAL) {
00274     result = 0;
00275     SetPageUptodate(page);
00276   } else {
00277     memset(buf, 0, PAGE_SIZE);
00278     SetPageError(page);
00279   }
00280 
00281   flush_dcache_page(page);
00282   UnlockPage(page);
00283   kunmap(page);
00284 
00285 err_out:
00286   page_cache_release(page);
00287   unlock_kernel();
00288   return result;
00289 }
00290 
00298 static int tarfs_statfs(struct super_block *s, struct statfs *stats)
00299 {
00300   PRINTD("*** tarfs_statfs");
00301   stats->f_type = TARFS_MAGIC;
00302   stats->f_bsize = TARFS_BLKSIZE;
00303   stats->f_bfree = 0;
00304   stats->f_blocks = tar_length(s);
00305   stats->f_namelen = 128;
00306   return 0;
00307 }
00308 
00309 //-------------------------------------------------
00310 
00316 static int __init init_module()
00317 {
00318   return register_filesystem(&tarfs_type);
00319 }
00320 
00324 static void __exit cleanup_module()
00325 {
00326   unregister_filesystem(&tarfs_type);
00327 }
00328 

Generated on Fri May 23 02:10:44 2003 for TarFS by doxygen1.3