patch-2.4.0-test9 linux/fs/coda/inode.c
Next file: linux/fs/coda/pioctl.c
Previous file: linux/fs/coda/file.c
Back to the patch index
Back to the overall index
- Lines: 219
- Date:
Thu Sep 21 09:59:46 2000
- Orig file:
v2.4.0-test8/linux/fs/coda/inode.c
- Orig date:
Wed Jun 21 10:10:02 2000
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/inode.c linux/fs/coda/inode.c
@@ -18,6 +18,7 @@
#include <linux/locks.h>
#include <linux/unistd.h>
#include <linux/smp_lock.h>
+#include <linux/file.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -48,6 +49,47 @@
statfs: coda_statfs,
};
+static int get_device_index(struct coda_mount_data *data)
+{
+ struct file *file;
+ struct inode *inode;
+ int idx;
+
+ if(data == NULL) {
+ printk("coda_read_super: Bad mount data\n");
+ return -1;
+ }
+
+ if(data->version != CODA_MOUNT_VERSION) {
+ printk("coda_read_super: Bad mount version\n");
+ return -1;
+ }
+
+ file = fget(data->fd);
+ inode = NULL;
+ if(file)
+ inode = file->f_dentry->d_inode;
+
+ if(!inode || !S_ISCHR(inode->i_mode) ||
+ MAJOR(inode->i_rdev) != CODA_PSDEV_MAJOR) {
+ if(file)
+ fput(file);
+
+ printk("coda_read_super: Bad file\n");
+ return -1;
+ }
+
+ idx = MINOR(inode->i_rdev);
+ fput(file);
+
+ if(idx < 0 || idx >= MAX_CODADEVS) {
+ printk("coda_read_super: Bad minor number\n");
+ return -1;
+ }
+
+ return idx;
+}
+
static struct super_block * coda_read_super(struct super_block *sb,
void *data, int silent)
{
@@ -57,23 +99,41 @@
ViceFid fid;
kdev_t dev = sb->s_dev;
int error;
-
+ int idx;
ENTRY;
- vc = &coda_upc_comm;
- sbi = &coda_super_info;
+ idx = get_device_index((struct coda_mount_data *) data);
+
+ /* Ignore errors in data, for backward compatibility */
+ if(idx == -1)
+ idx = 0;
+
+ printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
+
+ vc = &coda_comms[idx];
+ if (!vc->vc_inuse) {
+ printk("coda_read_super: No pseudo device\n");
+ EXIT;
+ return NULL;
+ }
+
+ if ( vc->vc_sb ) {
+ printk("coda_read_super: Device already mounted\n");
+ EXIT;
+ return NULL;
+ }
- if ( sbi->sbi_sb ) {
- printk("Already mounted\n");
+ sbi = kmalloc(sizeof(struct coda_sb_info), GFP_KERNEL);
+ if(!sbi) {
EXIT;
return NULL;
}
+ vc->vc_sb = sb;
+
sbi->sbi_sb = sb;
- sbi->sbi_psdev = psdev;
sbi->sbi_vcomm = vc;
- INIT_LIST_HEAD(&(sbi->sbi_cchead));
- INIT_LIST_HEAD(&(sbi->sbi_volroothead));
+ INIT_LIST_HEAD(&sbi->sbi_cihead);
sb->u.generic_sbp = sbi;
sb->s_blocksize = 1024; /* XXXXX what do we put here?? */
@@ -100,7 +160,6 @@
printk("coda_read_super: rootinode is %ld dev %d\n",
root->i_ino, root->i_dev);
- sbi->sbi_root = root;
sb->s_root = d_alloc_root(root);
EXIT;
return sb;
@@ -108,9 +167,9 @@
error:
EXIT;
if (sbi) {
- sbi->sbi_vcomm = NULL;
- sbi->sbi_root = NULL;
- sbi->sbi_sb = NULL;
+ kfree(sbi);
+ if(vc)
+ vc->vc_sb = NULL;
}
if (root) {
iput(root);
@@ -120,15 +179,16 @@
static void coda_put_super(struct super_block *sb)
{
- struct coda_sb_info *sb_info;
+ struct coda_sb_info *sbi;
ENTRY;
- coda_cache_clear_all(sb);
- sb_info = coda_sbp(sb);
- coda_super_info.sbi_sb = NULL;
+ sbi = coda_sbp(sb);
+ sbi->sbi_vcomm->vc_sb = NULL;
+ list_del_init(&sbi->sbi_cihead);
+
printk("Coda: Bye bye.\n");
- memset(sb_info, 0, sizeof(* sb_info));
+ kfree(sbi);
EXIT;
}
@@ -136,11 +196,21 @@
/* all filling in of inodes postponed until lookup */
static void coda_read_inode(struct inode *inode)
{
+ struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
struct coda_inode_info *cii;
ENTRY;
+
+ if (!sbi) BUG();
+
cii = ITOC(inode);
- cii->c_magic = 0;
- return;
+ if (cii->c_magic == CODA_CNODE_MAGIC) {
+ printk("coda_read_inode: initialized inode");
+ return;
+ }
+
+ memset(cii, 0, sizeof(struct coda_inode_info));
+ list_add(&cii->c_cilist, &sbi->sbi_cihead);
+ cii->c_magic = CODA_CNODE_MAGIC;
}
static void coda_clear_inode(struct inode *inode)
@@ -152,15 +222,13 @@
CDEBUG(D_SUPER, " inode->ino: %ld, count: %d\n",
inode->i_ino, atomic_read(&inode->i_count));
- if ( inode->i_ino == CTL_INO || cii->c_magic != CODA_CNODE_MAGIC )
- goto out;
+ if ( cii->c_magic != CODA_CNODE_MAGIC )
+ return;
- lock_kernel();
+ list_del_init(&cii->c_cilist);
- if ( !list_empty(&cii->c_volrootlist) ) {
- list_del(&cii->c_volrootlist);
- INIT_LIST_HEAD(&cii->c_volrootlist);
- }
+ if ( inode->i_ino == CTL_INO )
+ goto out;
if ( inode->i_mapping != &inode->i_data ) {
open_inode = (struct inode *)inode->i_mapping->host;
@@ -170,12 +238,11 @@
iput(open_inode);
}
- coda_cache_clear_inode(inode);
- unlock_kernel();
-
CDEBUG(D_DOWNCALL, "clearing inode: %ld, %x\n", inode->i_ino, cii->c_flags);
+ coda_cache_clear_inode(inode);
out:
inode->u.coda_i.c_magic = 0;
+ memset(&inode->u.coda_i.c_fid, 0, sizeof(struct ViceFid));
EXIT;
}
@@ -237,9 +304,4 @@
/* init_coda: used by filesystems.c to register coda */
DECLARE_FSTYPE( coda_fs_type, "coda", coda_read_super, 0);
-
-int init_coda_fs(void)
-{
- return register_filesystem(&coda_fs_type);
-}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)