00001
00014 #ifndef __KERNEL__
00015 # define __KERNEL__
00016 #endif
00017
00018
00019 #include <linux/init.h>
00020 #include <linux/kernel.h>
00021 #include <linux/module.h>
00022 #include <linux/version.h>
00023 #include <linux/fs.h>
00024 #include <linux/sched.h>
00025 #include <linux/statfs.h>
00026 #include <linux/mm.h>
00027 #include <asm/uaccess.h>
00028 #include <asm/errno.h>
00029 #include <linux/buffer_head.h>
00030 #include <linux/pagemap.h>
00031 #include <linux/proc_fs.h>
00032 #include <asm/atomic.h>
00033 #include <linux/string.h>
00034 #include <linux/smp_lock.h>
00035
00036
00037 #include "fsc_device.h"
00038 #include "rkfs.h"
00039 #include "parser.h"
00040
00041
00043 static struct inode *rkfs_root_inode;
00044
00045
00047 struct super_operations rkfs_sops = {
00048 read_inode: rkfs_super_read_inode,
00049 statfs: simple_statfs,
00050 write_inode: rkfs_super_write_inode,
00051 delete_inode: rkfs_super_delete_inode
00052 };
00053
00054
00056 struct inode_operations rkfs_iops = {
00057 lookup: rkfs_inode_lookup,
00058 mkdir: rkfs_mkdir,
00059 rmdir: rkfs_rmdir,
00060 create : rkfs_inode_create,
00061 unlink: rkfs_inode_unlink,
00062 truncate: rkfs_inode_truncate,
00063 rename: rkfs_inode_rename
00064 };
00065
00066
00078 static int rkfs_fill_super(struct super_block *sb, void *data, int silent) {
00079 char query_string[MAX_QUERY_LENGTH + 1];
00080 char file_dircount[MAX_SIZE_LENGTH + 1];
00081 char file_filecount[MAX_SIZE_LENGTH + 1];
00082 char *data_pos;
00083
00084 FSPDEBUG("rkfs_fill_super\n");
00085
00086
00087
00088 if (query("MYSQL1.1 TS", strlen("MYSQL1.1 TS")) != RKFS_DEF_QUERY_OK) {
00089 return -EFAULT;
00090 }
00091 else {
00092 if (ret_command.command_nr == CMD_ER_NR) {
00093 FSPDEBUG("filesystem mount error, db connection failed\n");
00094 return -EFAULT;
00095 }
00096
00097 }
00098
00099 sb->s_blocksize = RKFS_BLOCKSIZE;
00100 sb->s_blocksize_bits = RKFS_BLOCKSIZE_BITS;
00101 sb->s_magic = RKFS_MAGIC;
00102
00103
00104 sb->s_op = &rkfs_sops;
00105
00106
00107 sb->s_type = &rkfs;
00108
00109
00110 rkfs_root_inode = iget(sb, RKFS_ROOT_INODE);
00111
00112
00113 rkfs_root_inode->i_op = &rkfs_iops;
00114
00115 rkfs_root_inode->i_mode = S_IFDIR|S_IRWXU;
00116 rkfs_root_inode->i_fop = &rkfs_dops;
00117
00118
00119 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 RI %d", RKFS_ROOT_INODE);
00120 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00121 return -EFAULT;
00122 }
00123 else {
00124 if (ret_command.command_nr == CMD_ER_NR) {
00125 return -EFAULT;
00126 }
00127 }
00128
00129 data_pos = ret_command.data;
00130
00131 rkfs_next_data_item(&data_pos, file_dircount);
00132
00133
00134 rkfs_next_data_item(&data_pos, file_filecount);
00135
00136 FSPDEBUG("dircount = '%s', filecount = '%s'\n", file_dircount, file_filecount);
00137 rkfs_root_inode->i_size = rkfs_atoi(file_dircount) + rkfs_atoi(file_filecount);
00138
00139
00140 rkfs_root_inode->i_nlink = rkfs_atoi(file_dircount) + 2;
00141
00142 if (!(sb->s_root = d_alloc_root(rkfs_root_inode))) {
00143 iput(rkfs_root_inode);
00144 FSPDEBUG("filesystem mount error, not enough memory\n");
00145 return -ENOMEM;
00146 }
00147
00148 return 0;
00149 }
00150
00151
00165 int rkfs_get_sb (struct file_system_type *fs_type, int flags, const char *devname, void *data,
00166 struct vfsmount *mnt) {
00167 int result;
00168 FSPDEBUG("rkfs_get_sb\n");
00169
00170 result = get_sb_single(
00171 fs_type,
00172 flags,
00173 data,
00174 &rkfs_fill_super, mnt);
00175 if (result == 0) {
00176 FSPDEBUG("rkfs_get_sb succesfull\n");
00177 }
00178 else {
00179 FSPDEBUG("rkfs_get_sb: get_sb_single failed, return=%d\n", result);
00180 }
00181
00182 return result;
00183 }
00184
00185
00194 void rkfs_kill_sb(struct super_block *super) {
00195 FSPDEBUG("rkfs_kill_sb\n\n\n\n");
00196 kill_anon_super(super);
00197 }
00198
00199
00208 void rkfs_super_read_inode(struct inode *inode) {
00209 char query_string[MAX_QUERY_LENGTH + 1];
00210 char file_size[MAX_SIZE_LENGTH + 1];
00211 char file_dircount[MAX_SIZE_LENGTH + 1];
00212 char file_filecount[MAX_SIZE_LENGTH + 1];
00213 char *data_pos = NULL;
00214
00215 FSPDEBUG("rkfs_super_read_inode (%lu)\n", inode->i_ino);
00216
00217 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 RI %lu", inode->i_ino);
00218 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00219 make_bad_inode(inode);
00220 return;
00221 }
00222 else {
00223 if (ret_command.command_nr == CMD_ER_NR) {
00224 make_bad_inode(inode);
00225
00226 return;
00227 }
00228 }
00229
00230 FSPRETCMD();
00231 data_pos = ret_command.data;
00232
00233
00234 if (strcmp(ret_command.param, "IS_FILE") == 0) {
00235 rkfs_next_data_item(&data_pos, file_size);
00236 inode->i_size = rkfs_atoi(file_size);
00237
00238
00239 inode->i_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
00240 inode->i_fop = &rkfs_fops;
00241
00242
00243 inode->i_op = &rkfs_iops;
00244 FSPDEBUG("end of rkfs_super_read_inode from file branch\n");
00245 }
00246 else {
00247
00248
00249 rkfs_next_data_item(&data_pos, file_dircount);
00250
00251
00252 rkfs_next_data_item(&data_pos, file_filecount);
00253 FSPDEBUG("dircount = '%s', filecount = '%s'\n", file_dircount, file_filecount);
00254 inode->i_size = rkfs_atoi(file_dircount) + rkfs_atoi(file_filecount);
00255
00256
00257 inode->i_nlink = rkfs_atoi(file_dircount) + 2;
00258
00259
00260
00261 inode->i_mode = S_IFDIR|S_IXUSR|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
00262 inode->i_fop = &rkfs_dops;
00263
00264
00265 inode->i_op = &rkfs_iops;
00266 FSPDEBUG("end of rkfs_super_read_inode from dir branch\n");
00267 }
00268 }
00269
00270
00281 int rkfs_super_write_inode(struct inode *inode, int wait) {
00282 FSPDEBUG("rkfs_super_write_inode (i_ino = %d) = %d\n",
00283 (int)inode->i_ino,(int)i_size_read(inode));
00284 return 0;
00285 }
00286
00287
00298 int rkfs_inode_unlink (struct inode *dir, struct dentry *dentry) {
00299 struct inode * inode = dentry->d_inode;
00300 char query_string[MAX_QUERY_LENGTH + 1];
00301 FSPDEBUG("rkfs_unlink_inode (i_ino = %lu)\n", (unsigned long int)inode->i_ino);
00302
00303 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 RF %lu", (long unsigned int)inode->i_ino);
00304
00305
00306 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00307 return -EFAULT;
00308 }
00309 else {
00310 if (ret_command.command_nr == CMD_ER_NR) {
00311 return -EACCES;
00312 }
00313 }
00314
00315 inode->i_size = 0;
00316
00317 dir->i_size--;
00318
00319 return 0;
00320 }
00321
00322
00332 void rkfs_super_delete_inode(struct inode *inode) {
00333 FSPDEBUG("rkfs_delete_inode (i_ino = %lu)\n", (long unsigned int)inode->i_ino);
00334 return generic_delete_inode(inode);
00335 }
00336
00337
00350 struct dentry *rkfs_inode_lookup(struct inode *parent_inode, struct dentry *dentry,
00351 struct nameidata *nameidata) {
00352 struct inode *file_inode;
00353 char query_string[MAX_QUERY_LENGTH + 1];
00354 char file_id[MAX_ID_LENGTH + 1];
00355 char* data_pos;
00356
00357 FSPDEBUG("rkfs_inode_lookup\n");
00358 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 LU %lu %s", parent_inode->i_ino, dentry->d_name.name);
00359
00360
00361 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00362 return NULL;
00363 }
00364 else {
00365 if (ret_command.command_nr == CMD_ER_NR) {
00366
00367 return NULL;
00368 }
00369 }
00370
00371 data_pos = ret_command.data;
00372
00373
00374 rkfs_next_data_item(&data_pos, file_id);
00375
00376 file_inode = iget(parent_inode->i_sb, rkfs_atoi(file_id));
00377
00378 if (!file_inode) {
00379 return ERR_PTR(-EACCES);
00380 }
00381
00382 d_add(dentry, file_inode);
00383 return NULL;
00384 }
00385
00386
00387
00400 int rkfs_inode_create(struct inode *dir, struct dentry *dirdentry, int mode,
00401 struct nameidata *nd) {
00402 struct inode * inode;
00403 struct super_block *sb = dir->i_sb;
00404 char query_string[MAX_QUERY_LENGTH + 1];
00405 struct qstr qname;
00406 struct dentry *dentry;
00407
00408 FSPDEBUG("rkfs_inode_create\n");
00409
00410
00411 inode = new_inode(sb);
00412 if (IS_ERR(inode)) {
00413 return PTR_ERR(inode);
00414 }
00415
00416 qname.name = dirdentry->d_name.name;
00417 qname.len = strlen (dirdentry->d_name.name);
00418 qname.hash = full_name_hash(qname.name, qname.len);
00419
00420
00421 dentry = d_alloc(dirdentry, &qname);
00422 if (! dentry) {
00423 return 0;
00424 }
00425
00426 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 CF %lu %s", dir->i_ino, dirdentry->d_name.name);
00427
00428
00429 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00430 dput(dentry);
00431 return 0;
00432 }
00433 else {
00434 if (ret_command.command_nr == CMD_ER_NR) {
00435 dput(dentry);
00436 return 0;
00437 }
00438 }
00439
00440 inode->i_ino = rkfs_atoi(ret_command.param);
00441
00442
00443 inode->i_size = 0;
00444
00445
00446 inode->i_mode = S_IFREG | mode ;
00447
00448
00449 inode->i_fop = &rkfs_fops;
00450
00451
00452 inode->i_op = &rkfs_iops;
00453 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
00454 inode_inc_link_count(inode);
00455
00456 d_add(dirdentry, inode);
00457
00458
00459 dir->i_size++;
00460
00461
00462 return 0;
00463 }
00464
00465
00467 struct write_buffer {
00469 char data_buf[RKFS_BLOCKSIZE];
00471 char query_buf[RKFS_BLOCKSIZE + MAX_QUERY_LENGTH + 1];
00473 char query_len;
00474 } truncate_buffer;
00475
00476
00486 void rkfs_inode_truncate (struct inode * inode) {
00487 char query_string[MAX_QUERY_LENGTH + 1];
00488 long new_file_size = inode->i_size;
00489
00490 FSPDEBUG("rkfs_inode_truncate\n");
00491
00492
00493
00494 if (new_file_size == 0) {
00495 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 CR %lu", inode->i_ino);
00496 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00497 return;
00498 }
00499 else {
00500 if (ret_command.command_nr == CMD_ER_NR) {
00501
00502
00503 return;
00504 }
00505 }
00506 return;
00507 }
00508
00509 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 TR %lu %lu", inode->i_ino, new_file_size);
00510
00511 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00512 return;
00513 }
00514 else {
00515 if (ret_command.command_nr == CMD_ER_NR) {
00516
00517
00518 return;
00519 }
00520 }
00521
00522 }
00523
00524
00537 int rkfs_inode_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,
00538 struct dentry *new_dentry) {
00539 char query_string[MAX_QUERY_LENGTH + 1];
00540 char file_id[MAX_SIZE_LENGTH + 1];
00541 char* data_pos;
00542 long file_id_long;
00543 int is_file = 0;
00544
00545 FSPDEBUG("rkfs_inode_rename\n");
00546 FSPDEBUG("rkfs_inode_rename (old_dir->i_ino='%lu', old_dentry->d_name='%s', new_dir->i_ino='%lu', new_dentry->d_name='%s')\n", (long)old_dir->i_ino, old_dentry->d_name.name, (long)new_dir->i_ino, new_dentry->d_name.name);
00547
00548 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 LU %lu %s", old_dir->i_ino, old_dentry->d_name.name);
00549
00550
00551 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00552 return -ENOENT;
00553 }
00554 else {
00555 if (ret_command.command_nr == CMD_ER_NR) {
00556
00557
00558 return -ENOENT;
00559 }
00560
00561 }
00562
00563 data_pos = ret_command.data;
00564
00565
00566 rkfs_next_data_item(&data_pos, file_id);
00567 file_id_long = rkfs_atoi(file_id);
00568
00569 if (strcmp(ret_command.param, "IS_FILE") == 0) {
00570 is_file = 1;
00571 }
00572
00573 if (old_dir->i_ino != new_dir->i_ino) {
00574 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 MV %s %lu", file_id, new_dir->i_ino);
00575 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00576 return -ENOENT;
00577 }
00578 else {
00579 if (ret_command.command_nr == CMD_ER_NR) {
00580
00581
00582 return -ENOENT;
00583 }
00584 }
00585
00586 old_dir->i_size--;
00587 new_dir->i_size++;
00588
00589 if (!is_file) {
00590 old_dir->i_nlink--;
00591 new_dir->i_nlink--;
00592 }
00593
00594 }
00595
00596 if (strcmp(old_dentry->d_name.name, new_dentry->d_name.name) != 0) {
00597 if (is_file) {
00598 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 DN %s %s", file_id, new_dentry->d_name.name);
00599
00600 } else {
00601 snprintf(query_string, MAX_QUERY_LENGTH + 1, "MYSQL1.1 DD %s %s", file_id, new_dentry->d_name.name);
00602 }
00603
00604 if (query(query_string, strlen(query_string)) != RKFS_DEF_QUERY_OK) {
00605 return -ENOENT;
00606 }
00607 else {
00608 if (ret_command.command_nr == CMD_ER_NR) {
00609
00610
00611 return -ENOENT;
00612 }
00613
00614 }
00615
00616 }
00617
00618 return 0;
00619 }
00620
00621