⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 presto.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
        }                fset = presto_fset(dentry);        error=-EINVAL;        if (fset==NULL) {                printk("No fileset!\n");                EXIT;                goto out_cancel_lml;        }                /* this only requires a transaction below which is automatic */        handle = presto_trans_start(fset, dentry->d_inode, PRESTO_OP_RELEASE);         if ( !handle ) {                error = -ENOMEM;                 EXIT;                 goto out_cancel_lml;         }                 if (info->flags & LENTO_FL_CANCEL_LML) {                error = presto_clear_lml_close(fset, lml_offset);                if ( error ) {                        presto_trans_commit(fset, handle);                        EXIT;                         goto out_cancel_lml;                }        }        if (info->flags & LENTO_FL_WRITE_KML) {                struct file file;                file.private_data = NULL;                file.f_dentry = dentry;                 presto_getversion(&new_ver, dentry->d_inode);                error = presto_journal_close(&rec, fset, &file, dentry,                                              &new_ver);                if ( error ) {                        EXIT;                         presto_trans_commit(fset, handle);                        goto out_cancel_lml;                }        }        if (info->flags & LENTO_FL_WRITE_EXPECT) {                error = presto_write_last_rcvd(&rec, fset, info);                 if ( error ) {                        EXIT;                         presto_trans_commit(fset, handle);                        goto out_cancel_lml;                }        }        presto_trans_commit(fset, handle);        if (info->flags & LENTO_FL_CANCEL_LML) {            presto_truncate_lml(fset);         }                 out_cancel_lml:        EXIT;        path_release(&nd);         return error;}       /* given a path, operate on the flags in its dentry.  Used by downcalls */int presto_mark_dentry(const char *name, int and_flag, int or_flag,                        int *res){        struct nameidata nd;        struct dentry *dentry;        int error;        CDEBUG(D_INODE, "name: %s, and flag %x, or flag %x\n",               name, and_flag, or_flag);        error = presto_walk(name, &nd);        if (error)                return error;        dentry = nd.dentry;        CDEBUG(D_INODE, "dentry at %p, d_fsdata %p\n", dentry, dentry->d_fsdata);        error = -ENXIO;        if ( !presto_ispresto(dentry->d_inode) )                goto out;        error = 0;        if ( presto_dentry_is_fsetroot(dentry) ) {                struct presto_file_set *fset = presto_dentry2fset(dentry);                CDEBUG(D_INODE, "Setting fset fset_data: fset %p\n", fset);                if ( fset ) {                        fset->fset_data &= and_flag;                        fset->fset_data |= or_flag;                        if (res) {                                *res = fset->fset_data;                        }                }                CDEBUG(D_INODE, "fset %p, flags %x data %x\n",                        fset, fset->fset_flags, fset->fset_data);        } else {                ((int)(long)dentry->d_fsdata) &= and_flag;                ((int)(long)dentry->d_fsdata) |= or_flag;                if (res)                         *res = (int)(long)dentry->d_fsdata;        }        /* indicate if we were the only users while changing the flag */        if ( atomic_read(&dentry->d_count) > 1 )                error = -EBUSY;out:        path_release(&nd);        return error;}/* given a path, operate on the flags in its cache.  Used by mark_ioctl */int presto_mark_cache(const char *name, int and_flag, int or_flag,                       int *res){        struct nameidata nd;        struct dentry *dentry;        struct presto_cache *cache;        int error;        CDEBUG(D_INODE,               "presto_mark_cache :: name: %s, and flag %x, or flag %x\n",               name, and_flag, or_flag);        error = presto_walk(name, &nd);        if (error)                return error;        dentry = nd.dentry;        error = -ENXIO;        if ( !presto_ispresto(dentry->d_inode) )                goto out;        error = -EBADF;        cache = presto_get_cache(dentry->d_inode);        if ( !cache ) {                printk("PRESTO: BAD: cannot find cache in presto_mark_cache\n");                make_bad_inode(dentry->d_inode);                goto out;        }        error = 0;        ((int)cache->cache_flags) &= and_flag;        ((int)cache->cache_flags) |= or_flag;        if (res) {                *res = (int)cache->cache_flags;        }out:        path_release(&nd);        return error;}int presto_mark_fset_dentry(struct dentry *dentry, int and_flag, int or_flag,                      int * res){        int error;        struct presto_file_set *fset;        error = -ENXIO;        if ( !presto_ispresto(dentry->d_inode) )                return error;        error = -EBADF;        fset = presto_fset(dentry);        if ( !fset ) {                printk("PRESTO: BAD: cannot find cache in presto_mark_cache\n");                make_bad_inode(dentry->d_inode);                return error;        }        error = 0;        ((int)fset->fset_flags) &= and_flag;        ((int)fset->fset_flags) |= or_flag;        if (res) {                 *res = (int)fset->fset_flags;        }        return error;}/* given a path, operate on the flags in its cache.  Used by mark_ioctl */inline int presto_mark_fset(const char *name, int and_flag, int or_flag,                      int * res){        struct nameidata nd;        struct dentry *dentry;        int error;        ENTRY;        error = presto_walk(name, &nd);        if (error)                return error;        dentry = nd.dentry;        error = presto_mark_fset_dentry(dentry, and_flag, or_flag, res);        path_release(&nd);        return error;}/* talk to Lento about the permit */static int presto_permit_upcall(struct dentry *dentry){        int rc;        char *path, *buffer;        int pathlen;        int minor;        int fsetnamelen;        struct presto_file_set *fset = NULL;        if ( (minor = presto_i2m(dentry->d_inode)) < 0)                return -EINVAL;        fset = presto_fset(dentry);        if (!fset) {                EXIT;                return -ENOTCONN;        }                if ( !presto_lento_up(minor) ) {                if ( fset->fset_flags & FSET_STEAL_PERMIT ) {                        return 0;                } else {                        return -ENOTCONN;                }        }        PRESTO_ALLOC(buffer, char *, PAGE_SIZE);        if ( !buffer ) {                printk("PRESTO: out of memory!\n");                return -ENOMEM;        }        path = presto_path(dentry, fset->fset_mtpt, buffer, PAGE_SIZE);        pathlen = MYPATHLEN(buffer, path);        fsetnamelen = strlen(fset->fset_name);         rc = lento_permit(minor, pathlen, fsetnamelen, path, fset->fset_name);        PRESTO_FREE(buffer, PAGE_SIZE);        return rc;}/* get a write permit for the fileset of this inode *  - if this returns a negative value there was an error *  - if 0 is returned the permit was already in the kernel -- or -- *    Lento gave us the permit without reintegration *  - lento returns the number of records it reintegrated  */int presto_get_permit(struct inode * inode){        struct dentry *de;        struct presto_file_set *fset;        int minor = presto_i2m(inode);        int rc;        ENTRY;        if (minor < 0) {                EXIT;                return -1;        }        if ( ISLENTO(minor) ) {                EXIT;                return -EINVAL;        }        if (list_empty(&inode->i_dentry)) {                printk("No alias for inode %d\n", (int) inode->i_ino);                EXIT;                return -EINVAL;        }        de = list_entry(inode->i_dentry.next, struct dentry, d_alias);        fset = presto_fset(de);        if ( !fset ) {                printk("Presto: no fileset in presto_get_permit!\n");                EXIT;                return -EINVAL;        }        if (fset->fset_flags & FSET_HASPERMIT) {                lock_kernel();                fset->fset_permit_count++;                CDEBUG(D_INODE, "permit count now %d, inode %lx\n",                        fset->fset_permit_count, inode->i_ino);                unlock_kernel();                EXIT;                return 0;        } else {		/* Allow reintegration to proceed without locks -SHP */                rc = presto_permit_upcall(fset->fset_mtpt);                lock_kernel();                if ( !rc ) {                 	presto_mark_fset_dentry				(fset->fset_mtpt, ~0, FSET_HASPERMIT, NULL);                	fset->fset_permit_count++;                }                CDEBUG(D_INODE, "permit count now %d, ino %lx (likely 1), rc %d\n",         		fset->fset_permit_count, inode->i_ino, rc);                unlock_kernel();                EXIT;                return rc;        }}int presto_put_permit(struct inode * inode){        struct dentry *de;        struct presto_file_set *fset;        int minor = presto_i2m(inode);        ENTRY;        if (minor < 0) {                EXIT;                return -1;        }        if ( ISLENTO(minor) ) {                EXIT;                return -1;        }        if (list_empty(&inode->i_dentry)) {                printk("No alias for inode %d\n", (int) inode->i_ino);                EXIT;                return -1;        }        de = list_entry(inode->i_dentry.next, struct dentry, d_alias);        fset = presto_fset(de);        if ( !fset ) {                printk("Presto: no fileset in presto_get_permit!\n");                EXIT;                return -1;        }        lock_kernel();        if (fset->fset_flags & FSET_HASPERMIT) {                if (fset->fset_permit_count > 0) fset->fset_permit_count--;                else printk("Put permit while permit count is 0, inode %lx!\n",                                inode->i_ino);         } else {        	fset->fset_permit_count=0;        	printk("Put permit while no permit, inode %lx, flags %x!\n",                		inode->i_ino, fset->fset_flags);        }        CDEBUG(D_INODE, "permit count now %d, inode %lx\n",         		fset->fset_permit_count, inode->i_ino);        if (fset->fset_flags & FSET_PERMIT_WAITING &&                    fset->fset_permit_count == 0) {                CDEBUG(D_INODE, "permit count now 0, ino %lx, notify Lento\n",                        inode->i_ino);                presto_mark_fset_dentry(fset->fset_mtpt, ~FSET_PERMIT_WAITING, 0, NULL);                presto_mark_fset_dentry(fset->fset_mtpt, ~FSET_HASPERMIT, 0, NULL);                lento_release_permit(fset->fset_cache->cache_psdev->uc_minor,                                     fset->fset_permit_cookie);                fset->fset_permit_cookie = 0;         }        unlock_kernel();        EXIT;        return 0;}void presto_getversion(struct presto_version * presto_version,                       struct inode * inode){        presto_version->pv_mtime = cpu_to_le64((__u64)inode->i_mtime);        presto_version->pv_ctime = cpu_to_le64((__u64)inode->i_ctime);        presto_version->pv_size = cpu_to_le64((__u64)inode->i_size);}/* *  note: this routine "pins" a dentry for a fileset root */int presto_set_fsetroot(char *path, char *fsetname, unsigned int fsetid,                        unsigned int flags){        struct presto_file_set *fset;        struct presto_file_set *fset2;        struct dentry *dentry;        struct presto_cache *cache;        int error;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -