int coda_open(struct inode *coda_inode, struct file *coda_file)
{
	struct file *host_file = NULL;
	int error;
	unsigned short flags = coda_file->f_flags & (~O_EXCL);
	unsigned short coda_flags = coda_flags_to_cflags(flags);
	struct coda_file_info *cfi;
	struct inode *host_inode;

	coda_vfs_stat.open++;

	cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL);
	if (!cfi) {
		unlock_kernel();
		return -ENOMEM;
	}

	lock_kernel();

	error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
			   &host_file); 
	if (error || !host_file) {
		kfree(cfi);
		unlock_kernel();
		return error;
	}

	host_file->f_flags |= coda_file->f_flags & (O_APPEND | O_SYNC);

	cfi->cfi_magic = CODA_MAGIC;
	cfi->cfi_mapcount = 0;
	cfi->cfi_container = host_file;
	coda_load_creds(&cfi->cfi_cred);

	host_inode = host_file->f_dentry->d_inode;
	if (coda_inode->i_mapping == &coda_inode->i_data)
		coda_inode->i_mapping = host_inode->i_mapping;

	else if (coda_inode->i_mapping != host_inode->i_mapping) {
		/* This is not a good thing, it doesn't happen with 'venus'
		 * Coda's own userspace daemon, but others might not provide
		 * the same guarantees. Still looking for the real fix. */
		printk("coda_open: changed mapping\n");
		coda_inode->i_mapping = host_inode->i_mapping;
	}

	if (coda_file->private_data != NULL) BUG();
	coda_file->private_data = cfi;

	unlock_kernel();
	return 0;
}
예제 #2
0
파일: file.c 프로젝트: nhanh0/hah
int coda_open(struct inode *i, struct file *f)
{
	struct file *fh = NULL;
	int error = 0;
	unsigned short flags = f->f_flags & (~O_EXCL);
	unsigned short coda_flags = coda_flags_to_cflags(flags);
	struct coda_cred *cred;
	struct coda_inode_info *cii;

	lock_kernel();
	coda_vfs_stat.open++;

	CDEBUG(D_SPECIAL, "OPEN inode number: %ld, count %d, flags %o.\n", 
	       f->f_dentry->d_inode->i_ino, atomic_read(&f->f_dentry->d_count), flags);

	error = venus_open(i->i_sb, coda_i2f(i), coda_flags, &fh); 
	if (error || !fh) {
	        CDEBUG(D_FILE, "coda_open: venus_open result %d\n", error);
		unlock_kernel();
		return error;
	}

	/* coda_upcall returns filehandle of container file object */
	cii = ITOC(i);
	if (cii->c_container)
		fput(cii->c_container);

	cii->c_contcount++;
	cii->c_container = fh;
	i->i_mapping = &cii->c_container->f_dentry->d_inode->i_data;

	cred = kmalloc(sizeof(struct coda_cred), GFP_KERNEL);

	/* If the allocation failed, we'll just muddle on. This actually works
	 * fine for normal cases. (i.e. when open credentials are the same as
	 * close credentials) */
	if (cred) {
		coda_load_creds(cred);
		f->private_data = cred;
	}

	CDEBUG(D_FILE, "result %d, coda i->i_count is %d, cii->contcount is %d for ino %ld\n", 
	       error, atomic_read(&i->i_count), cii->c_contcount, i->i_ino);
	CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %p\n", 
	       fh->f_dentry->d_inode->i_ino,
	       atomic_read(&fh->f_dentry->d_inode->i_count),
               fh->f_dentry->d_inode->i_op);
	unlock_kernel();
	return 0;
}