📄 presto.c
字号:
ENTRY; PRESTO_ALLOC(fset, struct presto_file_set *, sizeof(*fset)); error = -ENOMEM; if ( !fset ) { printk(KERN_ERR "No memory allocating fset for %s\n", fsetname); EXIT; return -ENOMEM; } CDEBUG(D_INODE, "fset at %p\n", fset); printk("presto: fsetroot: path %s, fileset name %s\n", path, fsetname); error = presto_walk(path, &fset->fset_nd); CDEBUG(D_INODE, "\n"); if (error) { EXIT; goto out_free; } dentry = fset->fset_nd.dentry; CDEBUG(D_INODE, "\n"); error = -ENXIO; if ( !presto_ispresto(dentry->d_inode) ) { EXIT; goto out_dput; } CDEBUG(D_INODE, "\n"); cache = presto_get_cache(dentry->d_inode); if (!cache) { printk(KERN_ERR "No cache found for %s\n", path); EXIT; goto out_dput; } CDEBUG(D_INODE, "\n"); error = -EINVAL; if ( !cache->cache_mtpt) { printk(KERN_ERR "Presto - no mountpoint: fsetroot fails!\n"); EXIT; goto out_dput; } CDEBUG(D_INODE, "\n"); if (!cache->cache_root_fileset) { printk(KERN_ERR "Presto - no file set: fsetroot fails!\n"); EXIT; goto out_dput; } error = -EEXIST; CDEBUG(D_INODE, "\n"); fset2 = presto_fset(dentry); if (fset2 && (fset2->fset_mtpt == dentry) ) { printk(KERN_ERR "Fsetroot already set (path %s)\n", path); EXIT; goto out_dput; } fset->fset_cache = cache; fset->fset_mtpt = dentry; fset->fset_name = fsetname; fset->fset_chunkbits = CHUNK_BITS; fset->fset_flags = flags; fset->fset_file_maxio = FSET_DEFAULT_MAX_FILEIO; dentry->d_fsdata = (void *) ( ((long)fset) + PRESTO_FSETROOT ); list_add(&fset->fset_list, &cache->cache_fset_list); error = presto_init_kml_file(fset); if ( error ) { EXIT; CDEBUG(D_JOURNAL, "Error init_kml %d\n", error); goto out_list_del; } error = presto_init_last_rcvd_file(fset); if ( error ) { int rc; EXIT; rc = presto_close_journal_file(fset); CDEBUG(D_JOURNAL, "Error init_lastrcvd %d, cleanup %d\n", error, rc); goto out_list_del; } error = presto_init_lml_file(fset); if ( error ) { int rc; EXIT; rc = presto_close_journal_file(fset); CDEBUG(D_JOURNAL, "Error init_lml %d, cleanup %d\n", error, rc); goto out_list_del; }#ifdef CONFIG_KREINT /* initialize kml reint buffer */ error = kml_init (fset); if ( error ) { int rc; EXIT; rc = presto_close_journal_file(fset); CDEBUG(D_JOURNAL, "Error init kml reint %d, cleanup %d\n", error, rc); goto out_list_del; }#endif if ( dentry->d_inode == dentry->d_inode->i_sb->s_root->d_inode) { cache->cache_flags |= CACHE_FSETROOT_SET; } CDEBUG(D_PIOCTL, "-------> fset at %p, dentry at %p, mtpt %p, fset %s, cache %p, d_fsdata %p\n", fset, dentry, fset->fset_mtpt, fset->fset_name, cache, dentry->d_fsdata); EXIT; return 0; out_list_del: list_del(&fset->fset_list); dentry->d_fsdata = 0; out_dput: path_release(&fset->fset_nd); out_free: PRESTO_FREE(fset, sizeof(*fset)); return error;}int presto_get_kmlsize(char *path, size_t *size){ struct nameidata nd; struct presto_file_set *fset; struct dentry *dentry; int error; ENTRY; error = presto_walk(path, &nd); if (error) { EXIT; return error; } dentry = nd.dentry; error = -ENXIO; if ( !presto_ispresto(dentry->d_inode) ) { EXIT; goto kml_out; } error = -EINVAL; if ( ! presto_dentry_is_fsetroot(dentry)) { EXIT; goto kml_out; } fset = presto_dentry2fset(dentry); if (!fset) { EXIT; goto kml_out; } error = 0; *size = fset->fset_kml.fd_offset; kml_out: path_release(&nd); return error;}int presto_clear_fsetroot(char *path){ struct nameidata nd; struct presto_file_set *fset; struct dentry *dentry; struct presto_cache *cache; int error; ENTRY; error = presto_walk(path, &nd); if (error) { EXIT; return error; } dentry = nd.dentry; error = -ENXIO; if ( !presto_ispresto(dentry->d_inode) ) { EXIT; goto put_out; } error = -EINVAL; if ( ! presto_dentry_is_fsetroot(dentry)) { EXIT; goto put_out; } fset = presto_dentry2fset(dentry); if (!fset) { EXIT; goto put_out; }#ifdef CONFIG_KREINT error = kml_cleanup (fset); if ( error ) { printk("InterMezzo: Closing kml for fset %s: %d\n", fset->fset_name, error); }#endif error = presto_close_journal_file(fset); if ( error ) { printk("InterMezzo: Closing journal for fset %s: %d\n", fset->fset_name, error); } cache = fset->fset_cache; cache->cache_flags &= ~CACHE_FSETROOT_SET; list_del(&fset->fset_list); dentry->d_fsdata = 0; path_release(&fset->fset_nd); fset->fset_mtpt = NULL; PRESTO_FREE(fset->fset_name, strlen(fset->fset_name) + 1); PRESTO_FREE(fset, sizeof(*fset)); EXIT;put_out: path_release(&nd); /* for our lookup */ return error;}int presto_clear_all_fsetroots(char *path){ struct nameidata nd; struct presto_file_set *fset; struct dentry *dentry; struct presto_cache *cache; int error; struct list_head *tmp,*tmpnext; ENTRY; error = presto_walk(path, &nd); if (error) { EXIT; return error; } dentry = nd.dentry; error = -ENXIO; if ( !presto_ispresto(dentry->d_inode) ) { EXIT; goto put_out; } error = -EINVAL; if ( ! presto_dentry_is_fsetroot(dentry)) { EXIT; goto put_out; } fset = presto_dentry2fset(dentry); if (!fset) { EXIT; goto put_out; } cache = fset->fset_cache; cache = fset->fset_cache; cache->cache_flags &= ~CACHE_FSETROOT_SET; tmp = &cache->cache_fset_list; tmpnext = tmp->next; while ( tmpnext != &cache->cache_fset_list) { tmp=tmpnext; tmpnext=tmp->next; fset = list_entry(tmp, struct presto_file_set, fset_list); error = presto_close_journal_file(fset); if ( error ) { printk("InterMezzo: Closing journal for fset %s: %d\n", fset->fset_name, error); } list_del(&fset->fset_list); fset->fset_mtpt->d_fsdata = 0; path_release(&fset->fset_nd); fset->fset_mtpt = NULL; PRESTO_FREE(fset->fset_name, strlen(fset->fset_name) +1); PRESTO_FREE(fset, sizeof(*fset)); } EXIT; put_out: path_release(&nd); /* for our lookup */ return error;}int presto_get_lastrecno(char *path, off_t *recno){ struct nameidata nd; struct presto_file_set *fset; struct dentry *dentry; int error; ENTRY; error = presto_walk(path, &nd); if (error) { EXIT; return error; } dentry = nd.dentry; error = -ENXIO; if ( !presto_ispresto(dentry->d_inode) ) { EXIT; goto kml_out; } error = -EINVAL; if ( ! presto_dentry_is_fsetroot(dentry)) { EXIT; goto kml_out; } fset = presto_dentry2fset(dentry); if (!fset) { EXIT; goto kml_out; } error = 0; *recno = fset->fset_kml.fd_recno; kml_out: path_release(&nd); return error;}/* if *cookie != 0, lento must wait for this cookie before releasing the permit, operations are in progress. */ int presto_permit_downcall( const char * path, int *cookie ){ int result; struct presto_file_set *fset; fset = presto_path2fileset(path); if (IS_ERR(fset)) { EXIT; return PTR_ERR(fset); } lock_kernel(); if (fset->fset_permit_count != 0) { /* is there are previous cookie? */ if (fset->fset_permit_cookie == 0) { CDEBUG(D_CACHE, "presto installing cookie 0x%x, %s\n", *cookie, path); fset->fset_permit_cookie = *cookie; } else { *cookie = fset->fset_permit_cookie; CDEBUG(D_CACHE, "presto has cookie 0x%x, %s\n", *cookie, path); } result = presto_mark_fset(path, 0, FSET_PERMIT_WAITING, NULL); } else { *cookie = 0; CDEBUG(D_CACHE, "presto releasing permit %s\n", path); result = presto_mark_fset(path, ~FSET_HASPERMIT, 0, NULL); } unlock_kernel(); return result;}inline int presto_is_read_only(struct presto_file_set * fset){ int minor, mask; struct presto_cache *cache = fset->fset_cache; minor= cache->cache_psdev->uc_minor; mask= (ISLENTO(minor)? FSET_LENTO_RO : FSET_CLIENT_RO); if ( fset->fset_flags & mask ) return 1; mask= (ISLENTO(minor)? CACHE_LENTO_RO : CACHE_CLIENT_RO); return ((cache->cache_flags & mask)? 1 : 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -