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; }
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; }