00001
00012 #include <linux/module.h>
00013 #include <linux/fs.h>
00014 #include <linux/pagemap.h>
00015 #include <linux/highmem.h>
00016 #include <linux/init.h>
00017 #include <linux/string.h>
00018 #include <linux/smp_lock.h>
00019 #include <linux/backing-dev.h>
00020 #include <linux/slab.h>
00021 #include <linux/statfs.h>
00022 #include <asm/uaccess.h>
00023
00024 #include "mountdata.h"
00025 #include "procfs.h"
00026 #include "storage.h"
00027 #include "file.h"
00028
00029
00030
00031 #define MUMUFS_MAGIC 0x710110
00032
00033
00034 MODULE_LICENSE( "GPL" );
00035 MODULE_AUTHOR( "Sergey Satskiy" );
00036 MODULE_DESCRIPTION( "MuMu filesystem supports multiple writers and multiple readers" );
00037
00038
00039
00043 struct kmem_cache * mumufs_storage_cache;
00044
00045
00046 static struct super_operations mumufs_ops;
00047 static struct address_space_operations mumufs_aops;
00048 static struct inode_operations mumufs_file_inode_operations;
00049 static struct inode_operations mumufs_dir_inode_operations;
00050 static struct file_operations mumufs_file_operations;
00051 static struct backing_dev_info mumufs_backing_dev_info;
00052
00053
00057 static struct backing_dev_info mumufs_backing_dev_info =
00058 {
00059 .ra_pages = 0,
00060 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
00061
00062
00063
00064
00065 };
00066
00067
00068
00076 static struct inode * mumufs_get_inode( struct super_block * sb,
00077 int mode,
00078 dev_t dev )
00079 {
00080 if ( S_ISREG( mode ) || S_ISDIR( mode ) || S_ISLNK( mode ) )
00081 {
00082 struct inode * inode = NULL;
00083
00084
00085 if ( S_ISREG( mode ) && (mode & S_IXUGO) ) return NULL;
00086
00087 inode = new_inode( sb );
00088 if ( inode != NULL )
00089 {
00090 inode->i_mode = mode;
00091 inode->i_uid = current_fsuid();
00092 inode->i_gid = current_fsgid();
00093 inode->i_blocks = 0;
00094 inode->i_mapping->a_ops = &mumufs_aops;
00095 inode->i_mapping->backing_dev_info = &mumufs_backing_dev_info;
00096 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
00097 inode->i_private = NULL;
00098
00099 switch ( mode & S_IFMT )
00100 {
00101 case S_IFREG:
00102
00103 {
00104 int records = atomic_read( & ((struct mumu_mount_data *)(sb->s_fs_info))->number_of_entries );
00105 if ( records >= ((struct mumu_mount_data *)(sb->s_fs_info))->max_entries )
00106 {
00107 iput( inode );
00108 return NULL;
00109 }
00110 }
00111
00112 inode->i_op = & mumufs_file_inode_operations;
00113 inode->i_fop = & mumufs_file_operations;
00114
00115
00116 inode->i_private = mumufs_allocate_storage();
00117 if ( inode->i_private == NULL )
00118 {
00119 iput( inode );
00120 return NULL;
00121 }
00122
00123
00124 atomic_inc( & ((struct mumu_mount_data *)(sb->s_fs_info))->number_of_entries );
00125 break;
00126 case S_IFDIR:
00127 inode->i_op = & mumufs_dir_inode_operations;
00128 inode->i_fop = & simple_dir_operations;
00129
00130 inode->i_nlink++;
00131 break;
00132 case S_IFLNK:
00133 inode->i_op = & page_symlink_inode_operations;
00134 break;
00135 default:
00136
00137 break;
00138 }
00139 }
00140 return inode;
00141 }
00142
00143 return NULL;
00144 }
00145
00146
00154 static int mumufs_inode_unlink( struct inode * dir,
00155 struct dentry * dentry )
00156 {
00157 if ( (dentry->d_inode->i_private != NULL) &&
00158 ((dentry->d_inode->i_mode & S_IFMT) == S_IFREG) )
00159 {
00160
00161
00162 mumufs_free_storage( (struct mumufs_storage *)( dentry->d_inode->i_private ) );
00163 dentry->d_inode->i_private = NULL;
00164
00165
00166 atomic_dec( & ((struct mumu_mount_data *)(dir->i_sb->s_fs_info))->number_of_entries );
00167 }
00168
00169
00170
00171
00172 return simple_unlink( dir, dentry );
00173 }
00174
00175
00176
00177
00186 static int mumufs_mknod( struct inode * dir,
00187 struct dentry * dentry,
00188 int mode,
00189 dev_t dev )
00190 {
00191 struct inode * inode = mumufs_get_inode( dir->i_sb, mode, dev );
00192
00193 if ( inode != NULL )
00194 {
00195 if ( dir->i_mode & S_ISGID )
00196 {
00197 inode->i_gid = dir->i_gid;
00198 if ( S_ISDIR( mode ) )
00199 {
00200 inode->i_mode |= S_ISGID;
00201 }
00202 }
00203 d_instantiate( dentry, inode );
00204 dget( dentry );
00205 return 0;
00206 }
00207 return -ENOSPC;
00208 }
00209
00210
00211
00212
00220 static int mumufs_mkdir( struct inode * dir,
00221 struct dentry * dentry,
00222 int mode )
00223 {
00224 int retval = mumufs_mknod( dir, dentry, mode | S_IFDIR, 0 );
00225
00226 if ( !retval )
00227 {
00228 dir->i_nlink++;
00229 }
00230 return retval;
00231 }
00232
00233
00234
00235
00243 static int mumufs_create( struct inode * dir,
00244 struct dentry * dentry,
00245 int mode,
00246 struct nameidata * nd )
00247 {
00248 return mumufs_mknod( dir, dentry, mode | S_IFREG, 0 );
00249 }
00250
00251
00252
00253
00261 static int mumufs_symlink( struct inode * dir,
00262 struct dentry * dentry,
00263 const char * symname )
00264 {
00265 struct inode * inode = NULL;
00266 int error = -ENOSPC;
00267
00268 inode = mumufs_get_inode( dir->i_sb, S_IFLNK | S_IRWXUGO, 0 );
00269 if ( inode != NULL )
00270 {
00271 error = page_symlink( inode, symname, strlen( symname ) + 1 );
00272 if ( !error )
00273 {
00274 if ( dir->i_mode & S_ISGID )
00275 {
00276 inode->i_gid = dir->i_gid;
00277 }
00278 d_instantiate( dentry, inode );
00279 dget( dentry );
00280 }
00281 else
00282 {
00283 iput( inode );
00284 }
00285 }
00286
00287 return error;
00288 }
00289
00290
00297 static int mumufs_inode_setattr( struct dentry * dentry,
00298 struct iattr * iattr)
00299 {
00300 struct inode * inode = dentry->d_inode;
00301 int ret;
00302
00303 ret = inode_change_ok( inode, iattr );
00304 if ( ret != 0 )
00305 {
00306 return ret;
00307 }
00308
00309
00310
00311
00312 if ( iattr->ia_valid & ATTR_MODE )
00313 {
00314 if ( iattr->ia_mode & S_IXUGO ) return -EINVAL;
00315 }
00316
00317 return inode_setattr( inode, iattr );
00318 }
00319
00320
00328 static loff_t mumufs_no_llseek( struct file * file,
00329 loff_t offset,
00330 int origin )
00331 {
00332
00333
00334
00335 return -EINVAL;
00336 }
00337
00338
00339
00340 static struct address_space_operations mumufs_aops =
00341 {
00342 .readpage = simple_readpage,
00343 .write_begin = simple_write_begin,
00344 .write_end = simple_write_end,
00345 };
00346
00347
00348
00349 static struct file_operations mumufs_file_operations =
00350 {
00351 .open = mumufs_file_open,
00352 .read = mumufs_file_read,
00353 .write = mumufs_file_write,
00354 .release = mumufs_file_release,
00355 .llseek = mumufs_no_llseek,
00356
00357 .poll = mumufs_file_poll,
00358 };
00359
00360
00361
00362 static struct inode_operations mumufs_file_inode_operations =
00363 {
00364 .getattr = simple_getattr,
00365 .setattr = mumufs_inode_setattr,
00366 };
00367
00368
00369
00370 static struct inode_operations mumufs_dir_inode_operations =
00371 {
00372 .create = mumufs_create,
00373 .lookup = simple_lookup,
00374 .link = simple_link,
00375 .unlink = mumufs_inode_unlink,
00376 .symlink = mumufs_symlink,
00377 .mkdir = mumufs_mkdir,
00378 .rmdir = simple_rmdir,
00379 .mknod = mumufs_mknod,
00380 .rename = simple_rename,
00381 };
00382
00383
00388 static void mumufs_put_super( struct super_block * sb )
00389 {
00390 mumufs_remove_mount_info( sb );
00391 mumufs_umount_cleanup( sb );
00392 kfree( sb->s_fs_info );
00393
00394
00395
00396
00397 }
00398
00399
00414 static int mumufs_statfs( struct dentry * dentry, struct kstatfs * buf )
00415 {
00416 struct super_block * sb = dentry->d_sb;
00417 struct mumu_mount_data * d = (struct mumu_mount_data *)( sb->s_fs_info );
00418
00419 buf->f_type = MUMUFS_MAGIC;
00420 buf->f_bsize = 1;
00421 buf->f_blocks = d->max_entries;
00422 buf->f_bfree = d->max_entries - d->number_of_entries.counter;
00423 buf->f_bavail = buf->f_bfree;
00424 buf->f_files = buf->f_blocks;
00425 buf->f_ffree = buf->f_bfree;
00426 buf->f_namelen = NAME_MAX;
00427 buf->f_frsize = 1;
00428
00429 return 0;
00430 }
00431
00432 static struct super_operations mumufs_ops =
00433 {
00434 .statfs = mumufs_statfs,
00435 .drop_inode = generic_delete_inode,
00436 .put_super = mumufs_put_super,
00437 .show_options = mumufs_show_options,
00438 };
00439
00440
00441
00449 static int mumufs_fill_super( struct super_block * sb,
00450 void * data,
00451 int silent )
00452 {
00453 struct inode * inode;
00454 struct dentry * root;
00455 struct mumu_mount_data * mount_data;
00456
00457
00458 mount_data = kmalloc( sizeof( struct mumu_mount_data ), GFP_KERNEL );
00459 if ( mount_data == NULL )
00460 {
00461 return -ENOMEM;
00462 }
00463
00464 memset( mount_data, 0, sizeof( struct mumu_mount_data ) );
00465 if ( mumufs_init_mount_data( mount_data ) != 0 )
00466 {
00467 kfree( mount_data );
00468 return -ENOMEM;
00469 }
00470
00471 if ( !mumufs_parse_opt( (char *)data, mount_data ) )
00472 {
00473 kfree( mount_data );
00474 return -EINVAL;
00475 }
00476
00477 sb->s_maxbytes = MAX_LFS_FILESIZE;
00478 sb->s_blocksize = 1;
00479 sb->s_magic = MUMUFS_MAGIC;
00480 sb->s_op = &mumufs_ops;
00481 sb->s_time_gran = 1;
00482 sb->s_fs_info = mount_data;
00483
00484 inode = mumufs_get_inode( sb, S_IFDIR | 0755, 0 );
00485 if ( !inode )
00486 {
00487 kfree( mount_data );
00488 return -ENOMEM;
00489 }
00490
00491 root = d_alloc_root( inode );
00492 if ( !root )
00493 {
00494 kfree( mount_data );
00495 iput( inode );
00496 return -ENOMEM;
00497 }
00498 sb->s_root = root;
00499
00500
00501 {
00502 int ret = mumufs_create_mount_info( sb );
00503 if ( ret != 0 )
00504 {
00505 kfree( mount_data );
00506 iput( inode );
00507 dput( root );
00508 return ret;
00509 }
00510 }
00511
00512 return 0;
00513 }
00514
00515
00516
00526 int mumufs_get_sb( struct file_system_type * fs_type,
00527 int flags,
00528 const char * dev_name,
00529 void * data,
00530 struct vfsmount * mnt )
00531 {
00532 int ret;
00533
00534 ret = get_sb_nodev( fs_type, flags, data, mumufs_fill_super, mnt );
00535 if ( ret == 0 )
00536 {
00537 struct super_block * sb = mnt->mnt_sb;
00538
00539
00540
00541 ((struct mumu_mount_data *)(sb->s_fs_info))->mount = mnt;
00542 }
00543 return ret;
00544 }
00545
00546
00551 void mumufs_kill_super( struct super_block * sb )
00552 {
00553 struct inode * inode;
00554 struct inode * next_i;
00555
00556
00557 list_for_each_entry_safe(inode, next_i, & sb->s_inodes, i_sb_list)
00558 {
00559 if ( inode->i_mode && S_IFREG )
00560 {
00561 if ( inode->i_private != NULL )
00562 {
00563 mumufs_free_storage( (struct mumufs_storage *)( inode->i_private ) );
00564 }
00565 }
00566 }
00567
00568 return kill_litter_super( sb );
00569 }
00570
00571
00572 static struct file_system_type mumufs_fs_type =
00573 {
00574 .owner = THIS_MODULE,
00575 .name = "mumufs",
00576 .get_sb = mumufs_get_sb,
00577 .kill_sb = mumufs_kill_super,
00578 };
00579
00580
00581
00586 static int __init init_mumufs_fs( void )
00587 {
00588 int ret;
00589
00590 mumufs_storage_cache = kmem_cache_create( "mumu_storage", sizeof( struct mumufs_storage ),
00591 0, SLAB_HWCACHE_ALIGN, NULL );
00592 if ( mumufs_storage_cache == NULL )
00593 {
00594 return -EFAULT;
00595 }
00596
00597 if ( mumufs_initialise_proc_entries() != 0 )
00598 {
00599 kmem_cache_destroy( mumufs_storage_cache );
00600 return -EFAULT;
00601 }
00602
00603 ret = register_filesystem( &mumufs_fs_type );
00604 if ( ret != 0 )
00605 {
00606 kmem_cache_destroy( mumufs_storage_cache );
00607 mumufs_remove_proc_entries();
00608 }
00609
00610 return ret;
00611 }
00612
00613
00621 static void __exit exit_mumufs_fs( void )
00622 {
00623 mumufs_remove_proc_entries();
00624 unregister_filesystem( &mumufs_fs_type );
00625 kmem_cache_destroy( mumufs_storage_cache );
00626 return;
00627 }
00628
00629
00630 module_init( init_mumufs_fs )
00631 module_exit( exit_mumufs_fs )
00632
00633