int coda_release(struct inode *coda_inode, struct file *coda_file) { unsigned short flags = (coda_file->f_flags) & (~O_EXCL); unsigned short coda_flags = coda_flags_to_cflags(flags); struct coda_file_info *cfi; struct coda_inode_info *cii; struct inode *host_inode; int err; cfi = CODA_FTOC(coda_file); BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, coda_file->f_cred->fsuid); host_inode = cfi->cfi_container->f_path.dentry->d_inode; cii = ITOC(coda_inode); /* did we mmap this file? */ spin_lock(&cii->c_lock); if (coda_inode->i_mapping == &host_inode->i_data) { cii->c_mapcount -= cfi->cfi_mapcount; if (!cii->c_mapcount) coda_inode->i_mapping = &coda_inode->i_data; } spin_unlock(&cii->c_lock); fput(cfi->cfi_container); kfree(coda_file->private_data); coda_file->private_data = NULL; /* VFS fput ignores the return value from file_operations->release, so * there is no use returning an error here */ return 0; }
int coda_release(struct inode *coda_inode, struct file *coda_file) { unsigned short flags = (coda_file->f_flags) & (~O_EXCL); unsigned short coda_flags = coda_flags_to_cflags(flags); struct coda_file_info *cfi; struct coda_inode_info *cii; struct inode *host_inode; int err = 0; lock_kernel(); coda_vfs_stat.release++; if (!use_coda_close) { err = venus_release(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags); if (err == -EOPNOTSUPP) { use_coda_close = 1; err = 0; } } cfi = CODA_FTOC(coda_file); if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG(); if (use_coda_close) err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, &cfi->cfi_cred); host_inode = cfi->cfi_container->f_dentry->d_inode; cii = ITOC(coda_inode); /* did we mmap this file? */ if (coda_inode->i_mapping == &host_inode->i_data) { cii->c_mapcount -= cfi->cfi_mapcount; if (!cii->c_mapcount) coda_inode->i_mapping = &coda_inode->i_data; } fput(cfi->cfi_container); kfree(coda_file->private_data); coda_file->private_data = NULL; unlock_kernel(); return err; }
int coda_release(struct inode *i, struct file *f) { unsigned short flags = (f->f_flags) & (~O_EXCL); unsigned short cflags = coda_flags_to_cflags(flags); struct coda_inode_info *cii; struct file *cfile; int err = 0; lock_kernel(); coda_vfs_stat.release++; if (!use_coda_close) { err = venus_release(i->i_sb, coda_i2f(i), cflags); if (err == -EOPNOTSUPP) { use_coda_close = 1; err = 0; } } if (use_coda_close) err = venus_close(i->i_sb, coda_i2f(i), cflags, (struct coda_cred *)f->private_data); cii = ITOC(i); cfile = cii->c_container; if (!cfile) BUG(); if (--cii->c_contcount) { unlock_kernel(); return err; } i->i_mapping = &i->i_data; fput(cfile); cii->c_container = NULL; if (f->private_data) { kfree(f->private_data); f->private_data = NULL; } unlock_kernel(); return err; }