X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdfs%2Fsuper.c;h=498e2f44c520ef5ba338700154a96cb95bc03ee0;hb=5ffc9e67fce81ae1b946244565b74f98e2f9c786;hp=cf60d54d74dbc1fae5aede5875dd50f0fe215ea8;hpb=fc27fd73f3a22f9b8d819948f143c2537179b1c8;p=fs%2Flustre-release.git diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index cf60d54..498e2f4 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -2,6 +2,9 @@ * OBDFS Super operations * * Copryright (C) 1996 Peter J. Braam + * Copryright (C) 1999 Stelias Computing Inc. + * Copryright (C) 1999 Seagate Technology Inc. + * */ #define EXPORT_SYMTAB @@ -25,12 +28,12 @@ #include #include -#include <../obd/linux/sim_obd.h> -#include +#include +#include +#include /* VFS super_block ops */ static struct super_block *obdfs_read_super(struct super_block *, void *, int); -static void obdfs_read_inode(struct inode *); static int obdfs_notify_change(struct dentry *dentry, struct iattr *attr); static void obdfs_write_inode(struct inode *); static void obdfs_delete_inode(struct inode *); @@ -52,44 +55,185 @@ struct super_operations obdfs_super_operations = NULL /* remount_fs */ }; -struct obdfs_sb_info obdfs_super_info; -int obd_minor = 0; -int obd_root_ino = 2; +static char *obdfs_read_opt(const char *opt, char *data) +{ + char *value; + char *retval; + + CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); + if ( strncmp(opt, data, strlen(opt)) ) + return NULL; + + if ( (value = strchr(data, '=')) == NULL ) + return NULL; + + value++; + OBD_ALLOC(retval, char *, strlen(value) + 1); + if ( !retval ) { + printk("OBDFS: Out of memory!\n"); + return NULL; + } + + memcpy(retval, value, strlen(value)+1); + CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval); + return retval; +} + +void obdfs_options(char *options, char **dev, char **vers) +{ + char *this_char; + + if (!options) + return; + + for (this_char = strtok (options, ","); + this_char != NULL; + this_char = strtok (NULL, ",")) { + CDEBUG(D_SUPER, "this_char %s\n", this_char); + if ( (!*dev && (*dev = obdfs_read_opt("device", this_char)))|| + (!*vers && (*vers = obdfs_read_opt("version", this_char))) ) + continue; + + } +} + +static int obdfs_getdev(char *devpath, int *dev) +{ + struct dentry *dentry; + kdev_t devno; + + dentry = lookup_dentry(devpath, NULL, 0); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + + if (!S_ISCHR(dentry->d_inode->i_mode)) + return -ENODEV; + + devno = dentry->d_inode->i_rdev; + if ( MAJOR(devno) != OBD_PSDEV_MAJOR ) + return -ENODEV; + + if ( MINOR(devno) >= MAX_OBD_DEVICES ) + return -ENODEV; + + *dev = devno; + return 0; +} static struct super_block * obdfs_read_super(struct super_block *sb, void *data, int silent) { struct inode *root = 0; - struct obdfs_sb_info *sbi = NULL; + struct obdfs_sb_info *sbi = (struct obdfs_sb_info *)(&sb->u.generic_sbp); + struct obd_device *obddev; int error = 0; + char *device = NULL; + char *version = NULL; + int devno; + int err; + unsigned long blocksize; + unsigned long blocksize_bits; + unsigned long root_ino; + int scratch; + ENTRY; MOD_INC_USE_COUNT; + + memset(sbi, 0, sizeof(*sbi)); + + obdfs_options(data, &device, &version); + if ( !device ) { + printk("No device\n"); + MOD_DEC_USE_COUNT; + EXIT; + return NULL; + } - sbi = &obdfs_super_info; + if ( (err = obdfs_getdev(device, &devno)) ) { + printk("Cannot get devno of %s, error %d\n", device, err); + MOD_DEC_USE_COUNT; + EXIT; + return NULL; + } - if ( sbi->osi_super ) { - printk("Already mounted\n"); + if ( MAJOR(devno) != OBD_PSDEV_MAJOR ) { + printk("Wrong major number!\n"); MOD_DEC_USE_COUNT; + EXIT; return NULL; } + + if ( MINOR(devno) >= MAX_OBD_DEVICES ) { + printk("Minor of %s too high (%d)\n", device, MINOR(devno)); + MOD_DEC_USE_COUNT; + EXIT; + return NULL; + } + + obddev = &obd_dev[MINOR(devno)]; + + if ( ! (obddev->obd_flags & OBD_ATTACHED) || + ! (obddev->obd_flags & OBD_SET_UP) ){ + printk("Device %s not attached or not set up (%d)\n", + device, MINOR(devno)); + MOD_DEC_USE_COUNT; + EXIT; + return NULL; + } - error = obd_connect(obd_minor, &sbi->osi_conn_info); + sbi->osi_obd = obddev; + sbi->osi_ops = sbi->osi_obd->obd_type->typ_ops; + + sbi->osi_conn.oc_dev = obddev; + error = sbi->osi_ops->o_connect(&sbi->osi_conn); if ( error ) { - printk("OBDFS: cannot connect to 0x%x.\n", obd_minor); + printk("OBDFS: cannot connect to %s\n", device); goto error; } + + INIT_LIST_HEAD(&sbi->osi_list); + sbi->osi_super = sb; + error = sbi->osi_ops->o_get_info(&sbi->osi_conn, + strlen("blocksize"), + "blocksize", + &scratch, (void *)&blocksize); + if ( error ) { + printk("Getinfo call to drive failed (blocksize)\n"); + goto error; + } + + error = sbi->osi_ops->o_get_info(&sbi->osi_conn, + strlen("blocksize_bits"), + "blocksize_bits", + &scratch, (void *)&blocksize_bits); + if ( error ) { + printk("Getinfo call to drive failed (blocksize_bits)\n"); + goto error; + } + + error = sbi->osi_ops->o_get_info(&sbi->osi_conn, + strlen("root_ino"), + "root_ino", + &scratch, (void *)&root_ino); + if ( error ) { + printk("Getinfo call to drive failed (root_ino)\n"); + goto error; + } + + + lock_super(sb); - sb->u.generic_sbp = sbi; - sb->s_blocksize = sbi->osi_conn_info.conn_blocksize; - sb->s_blocksize_bits = sbi->osi_conn_info.conn_blocksize_bits; + + sb->s_blocksize = blocksize; + sb->s_blocksize_bits = (unsigned char)blocksize_bits; sb->s_magic = OBDFS_SUPER_MAGIC; sb->s_op = &obdfs_super_operations; /* make root inode */ - root = iget(sb, sbi->osi_conn_info.conn_ino); + root = iget(sb, root_ino); if (!root || is_bad_inode(root)) { printk("OBDFS: bad iget for root\n"); sb->s_dev = 0; @@ -97,9 +241,12 @@ static struct super_block * obdfs_read_super(struct super_block *sb, unlock_super(sb); goto error; } + - printk("obdfs_read_super: rootinode is %ld dev %d\n", - root->i_ino, root->i_dev); + printk("obdfs_read_super: sbdev %d, rootino: %ld, dev %s, " + "minor: %d, blocksize: %ld, blocksize bits %ld\n", + sb->s_dev, root->i_ino, device, MINOR(devno), + blocksize, blocksize_bits); sb->s_root = d_alloc_root(root); unlock_super(sb); EXIT; @@ -128,78 +275,62 @@ static void obdfs_put_super(struct super_block *sb) sb->s_dev = 0; /* XXX flush stuff */ - sbi = sb->u.generic_sbp; - sb->u.generic_sbp = NULL; - obd_disconnect(sbi->osi_conn_info.conn_id); - sbi->osi_super = NULL; + sbi = (struct obdfs_sb_info *) &sb->u.generic_sbp; + OPS(sb,disconnect)(ID(sb)); + + memset(sbi, 0, sizeof(* sbi)); printk("OBDFS: Bye bye.\n"); - memset(sbi, 0, sizeof(* sbi)); MOD_DEC_USE_COUNT; EXIT; } /* all filling in of inodes postponed until lookup */ -static void obdfs_read_inode(struct inode *inode) +void obdfs_read_inode(struct inode *inode) { - struct iattr attr; int error; - struct obdfs_sb_info *sbi = inode->i_sb->u.generic_sbp; ENTRY; - error = obd_getattr(sbi->osi_conn_info.conn_id, inode->i_ino, &attr); + error = IOPS(inode, getattr)(IID(inode), inode); if (error) { - printk("obdfs_read_inode: ibd_getattr fails (%d)\n", error); + printk("obdfs_read_inode: obd_getattr fails (%d)\n", error); return; } - - inode_setattr(inode, &attr); - inode->i_op = NULL; + CDEBUG(D_INODE, "ino %ld, mode: %o\n", inode->i_ino, inode->i_mode); + IDEBUG(inode); + if (S_ISREG(inode->i_mode)) + inode->i_op = &obdfs_file_inode_operations; + else if (S_ISDIR(inode->i_mode)) + inode->i_op = &obdfs_dir_inode_operations; + else if (S_ISLNK(inode->i_mode)) + inode->i_op = &obdfs_symlink_inode_operations; + else + /* XXX what do we pass here??? */ + init_special_inode(inode, inode->i_mode, 0 /* XXX XXX */ ); return; } -static void inode_to_iattr(struct inode *inode, struct iattr *tmp) -{ - tmp->ia_mode = inode->i_mode; - tmp->ia_uid = inode->i_uid; - tmp->ia_gid = inode->i_gid; - tmp->ia_size = inode->i_size; - tmp->ia_atime = inode->i_atime; - tmp->ia_mtime = inode->i_mtime; - tmp->ia_ctime = inode->i_ctime; - tmp->ia_attr_flags = inode->i_flags; - - tmp->ia_valid = ~0; -} - static void obdfs_write_inode(struct inode *inode) { - struct obdfs_sb_info *sbi; - struct iattr attr; int error; - ENTRY; - inode_to_iattr(inode, &attr); - sbi = inode->i_sb->u.generic_sbp; - error = obd_setattr(sbi->osi_conn_info.conn_id, inode->i_ino, &attr); + error = IOPS(inode, setattr)(IID(inode), inode); if (error) { - printk("obdfs_write_inode: ibd_setattr fails (%d)\n", error); + printk("obdfs_write_inode: obd_setattr fails (%d)\n", error); return; } - + return; } static void obdfs_delete_inode(struct inode *inode) { - struct obdfs_sb_info *sbi; int error; ENTRY; - sbi = inode->i_sb->u.generic_sbp; - error = obd_destroy(sbi->osi_conn_info.conn_id , inode->i_ino); + error = IOPS(inode, destroy)(IID(inode), inode); if (error) { printk("obdfs_delete_node: ibd_destroy fails (%d)\n", error); return; @@ -211,19 +342,21 @@ static void obdfs_delete_inode(struct inode *inode) static int obdfs_notify_change(struct dentry *de, struct iattr *iattr) { struct inode *inode = de->d_inode; - struct obdfs_sb_info * sbi; + struct iattr saved_copy; int error; ENTRY; + inode_to_iattr(inode, &saved_copy); - sbi = inode->i_sb->u.generic_sbp; - error = obd_setattr(sbi->osi_conn_info.conn_id, inode->i_ino, iattr); + inode_setattr(inode, iattr); + error = IOPS(inode, setattr)(IID(inode), inode); if ( error ) { + inode_setattr(inode, &saved_copy); printk("obdfs_notify_change: obd_setattr fails (%d)\n", error); return error; - } else { - inode_setattr(inode, iattr); } + + CDEBUG(D_INODE, "inode blocks now %ld\n", inode->i_blocks); EXIT; return error; } @@ -233,13 +366,11 @@ static int obdfs_statfs(struct super_block *sb, struct statfs *buf, int bufsize) { struct statfs tmp; - struct obdfs_sb_info * sbi; int error; ENTRY; - sbi = sb->u.generic_sbp; - error = obd_statfs(sbi->osi_conn_info.conn_id, &tmp); + error = OPS(sb,statfs)(ID(sb), &tmp); if ( error ) { printk("obdfs_notify_change: obd_statfs fails (%d)\n", error); return error; @@ -257,9 +388,16 @@ struct file_system_type obdfs_fs_type = { int init_obdfs(void) { + int err; + printk(KERN_INFO "OBDFS v0.1, braam@stelias.com\n"); obdfs_sysctl_init(); + + err = obdfs_init_wreqcache(); + if (err) + return err; + return register_filesystem(&obdfs_fs_type); } @@ -277,11 +415,5 @@ void cleanup_module(void) obdfs_sysctl_clean(); unregister_filesystem(&obdfs_fs_type); } -void obdfs_psdev_dec_use_count(void) -{ - MOD_DEC_USE_COUNT; -} - -EXPORT_SYMBOL(obdfs_psdev_dec_use_count); #endif