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; cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL); if (!cfi) return -ENOMEM; error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, &host_file); if (!host_file) error = -EIO; if (error) { kfree(cfi); 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; BUG_ON(coda_file->private_data != NULL); coda_file->private_data = cfi; return 0; }
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; }
/* * coda_open calls Venus which returns an open file descriptor the cache file * holding the data. We get the vnode while we are still in the context of * the venus process in coda_psdev.c. This vnode is then passed back to the * caller and opened. */ int coda_open(struct vop_open_args *ap) { /* * FreeBSD can pass the O_EXCL flag in mode, even though the check * has already happened. Venus defensively assumes that if open is * passed the EXCL, it must be a bug. We strip the flag here. */ /* true args */ struct vnode **vpp = &(ap->a_vp); struct cnode *cp = VTOC(*vpp); int flag = ap->a_mode & (~O_EXCL); struct ucred *cred = ap->a_cred; struct thread *td = ap->a_td; /* locals */ int error; struct vnode *vp; MARK_ENTRY(CODA_OPEN_STATS); /* * Check for open of control file. */ if (IS_CTL_VP(*vpp)) { /* XXX */ /* if (WRITEABLE(flag)) */ if (flag & (FWRITE | O_TRUNC | O_CREAT | O_EXCL)) { MARK_INT_FAIL(CODA_OPEN_STATS); return (EACCES); } MARK_INT_SAT(CODA_OPEN_STATS); return (0); } error = venus_open(vtomi((*vpp)), &cp->c_fid, flag, cred, td->td_proc, &vp); if (error) return (error); CODADEBUG(CODA_OPEN, myprintf(("open: vp %p result %d\n", vp, error)););