00001
00010
00011
00012
00013
00014
00015
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
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
00044
00045
00046
00047
00048 static struct super_operations tarfs_ops = {
00049 read_inode: tarfs_read_inode,
00050 statfs: tarfs_statfs,
00051 };
00052
00053
00054 static struct inode_operations tarfs_inode_ops = {
00055 lookup: tarfs_lookup,
00056
00057 };
00058
00059
00060 static struct file_operations tarfs_dir_ops = {
00061 read: generic_read_dir,
00062 readdir: tarfs_readdir,
00063 };
00064
00065
00066 static struct address_space_operations tarfs_aops = {
00067 readpage: tarfs_readpage,
00068 };
00069
00070
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
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
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 static int tarfs_readdir(struct file* filp, void* dirent, filldir_t filldir)
00130 {
00131 int retval;
00132 PRINTD("*** tarfs_readdir");
00133
00134
00135
00136 retval = tar_readdir(filp, dirent, filldir);
00137
00138 if (retval == 0 || retval == TARFS_EVAL) {
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
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
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();
00265 buf = (char*) kmap(page);
00266 if (!buf) {
00267 goto err_out;
00268 }
00269
00270
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