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

📄 presto.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * intermezzo.c * * This file implements basic routines supporting the semantics * * Author: Peter J. Braam  <braam@cs.cmu.edu> * Copyright (C) 1998 Stelias Computing Inc * Copyright (C) 1999 Red Hat Inc. * */#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/stat.h>#include <linux/errno.h>#include <linux/vmalloc.h>#include <linux/slab.h>#include <linux/locks.h>#include <asm/segment.h>#include <asm/uaccess.h>#include <linux/string.h>#include <linux/smp_lock.h>#include <linux/intermezzo_fs.h>#include <linux/intermezzo_upcall.h>#include <linux/intermezzo_psdev.h>#include <linux/intermezzo_kml.h>extern int presto_init_last_rcvd_file(struct presto_file_set *);extern int presto_init_lml_file(struct presto_file_set *);extern int presto_init_kml_file(struct presto_file_set *);int presto_walk(const char *name, struct nameidata *nd){        int err;        /* we do not follow symlinks to support symlink operations            correctly. The vfs should always hand us resolved dentries           so we should not be required to use LOOKUP_FOLLOW. At the	   reintegrating end, lento again should be working with the            resolved pathname and not the symlink. SHP           XXX: This code implies that direct symlinks do not work. SHP        */        unsigned int flags = LOOKUP_POSITIVE;        ENTRY;        err = 0;        if (path_init(name, flags, nd))                 err = path_walk(name, nd);        return err;}static inline int presto_dentry_is_fsetroot(struct dentry *dentry){        return ((long) dentry->d_fsdata) & PRESTO_FSETROOT;}static inline struct presto_file_set *presto_dentry2fset(struct dentry *dentry){        return (struct presto_file_set *)                (((long) dentry->d_fsdata) - PRESTO_FSETROOT);}/* find the presto minor device for this inode */int presto_i2m(struct inode *inode){        struct presto_cache *cache;        ENTRY;        cache = presto_get_cache(inode);        CDEBUG(D_PSDEV, "\n");        if ( !cache ) {                printk("PRESTO: BAD: cannot find cache for dev %d, ino %ld\n",                       inode->i_dev, inode->i_ino);                EXIT;                return -1;        }        EXIT;        return cache->cache_psdev->uc_minor;}inline int presto_f2m(struct presto_file_set *fset){        return fset->fset_cache->cache_psdev->uc_minor;}inline int presto_c2m(struct presto_cache *cache){        return cache->cache_psdev->uc_minor;}int presto_has_all_data(struct inode *inode){        ENTRY;        if ( (inode->i_size >> inode->i_sb->s_blocksize_bits) >             inode->i_blocks) {                EXIT;                return 0;        }        EXIT;        return 1;}/* find the fileset dentry for this dentry */struct presto_file_set *presto_fset(struct dentry *de){        struct dentry *fsde;        ENTRY;        fsde = de;        for ( ; ; ) {                if ( presto_dentry_is_fsetroot(fsde) ) {                        EXIT;                        return presto_dentry2fset(fsde);                }                /* are we at the cache "/" ?? */                if ( fsde->d_parent == fsde ) {                        if ( !de->d_inode ) {                                printk("Warning %*s has no fileset inode.\n",                                       de->d_name.len, de->d_name.name);                        }                        /* better to return a BAD thing */                        EXIT;                        return NULL;                }                fsde = fsde->d_parent;        }        /* not reached */        EXIT;        return NULL;}/* XXX check this out */struct presto_file_set *presto_path2fileset(const char *name){        struct nameidata nd;        struct presto_file_set *fileset;        int error;        ENTRY;        error = presto_walk(name, &nd);        if (!error) { #if 0                error = do_revalidate(nd.dentry);#endif                if (!error)                         fileset = presto_fset(nd.dentry);                 path_release(&nd);                 EXIT;        } else                 fileset = ERR_PTR(error);        EXIT;        return fileset;}/* check a flag on this dentry or fset root.  Semantics:   - most flags: test if it is set   - PRESTO_ATTR, PRESTO_DATA return 1 if PRESTO_FSETINSYNC is set*/int presto_chk(struct dentry *dentry, int flag){        int minor;        struct presto_file_set *fset = presto_fset(dentry);        ENTRY;        minor = presto_i2m(dentry->d_inode);        if ( upc_comms[minor].uc_no_filter ) {                EXIT;                return ~0;        }        /* if the fileset is in sync DATA and ATTR are OK */        if ( fset &&             (flag == PRESTO_ATTR || flag == PRESTO_DATA) &&             (fset->fset_flags & FSET_INSYNC) ) {                CDEBUG(D_INODE, "fset in sync (ino %ld)!\n",                       fset->fset_mtpt->d_inode->i_ino);                EXIT;                return 1;        }        /* if it is a fsetroot, it's stored in the fset_flags */        if ( fset && presto_dentry_is_fsetroot(dentry) ) {                EXIT;                return fset->fset_data & flag;        }        EXIT;        return ((int)(long)dentry->d_fsdata & flag);}/* set a bit in the dentry flags */void presto_set(struct dentry *dentry, int flag){        if ( dentry->d_inode ) {                CDEBUG(D_INODE, "SET ino %ld, flag %x\n",                       dentry->d_inode->i_ino, flag);        }        if ( presto_dentry_is_fsetroot(dentry)) {                struct presto_file_set *fset = presto_dentry2fset(dentry);                if (fset) {                        fset->fset_data |= flag;                        CDEBUG(D_INODE, "Setting fset->fset_data: now %x\n",                               fset->fset_data);                }        } else {                CDEBUG(D_INODE, "Setting dentry->d_fsdata\n");                ((int)(long)dentry->d_fsdata) |= flag;        }}/* given a path: complete the closes on the fset */int lento_complete_closes(char *path){        struct nameidata nd;        struct dentry *dentry;        int error;        struct presto_file_set *fset;        ENTRY;        error = presto_walk(path, &nd);        if (error) {                EXIT;                return error;        }        dentry = nd.dentry;        error = -ENXIO;        if ( !presto_ispresto(dentry->d_inode) ) {                EXIT;                goto out_complete;        }                fset = presto_fset(dentry);        error = -EINVAL;        if ( !fset ) {                printk("No fileset!\n");                EXIT;                goto out_complete;        }                /* transactions and locking are internal to this function */         error = presto_complete_lml(fset);                EXIT; out_complete:        path_release(&nd);         return error;}       /* set the fset recno and offset to a given value */ int lento_reset_fset(char *path, __u64 offset, __u32 recno){        struct nameidata nd;        struct dentry *dentry;        int error;        struct presto_file_set *fset;        ENTRY;        error = presto_walk(path, &nd);        if (error)                return error;        dentry = nd.dentry;        error = -ENXIO;        if ( !presto_ispresto(dentry->d_inode) ) {                EXIT;                goto out_complete;        }                fset = presto_fset(dentry);        error = -EINVAL;        if ( !fset ) {                printk("No fileset!\n");                EXIT;                goto out_complete;        }        write_lock(&fset->fset_kml.fd_lock);        fset->fset_kml.fd_recno = recno;        fset->fset_kml.fd_offset = offset;        read_lock(&fset->fset_kml.fd_lock);                EXIT; out_complete:        path_release(&nd);        return error;}       /* given a path, write an LML record for it - thus must have root's    group array settings, since lento is doing this */ int lento_write_lml(char *path,                     __u64 remote_ino,                      __u32 remote_generation,                     __u32 remote_version,                     struct presto_version *remote_file_version){        struct nameidata nd;         struct rec_info rec;        struct dentry *dentry;        struct file file;        int error;        struct presto_file_set *fset;        ENTRY;        error = presto_walk(path, &nd);        if (error) {                EXIT;                return error;        }        dentry = nd.dentry;        file.f_dentry = dentry;        file.private_data = NULL;        error = -ENXIO;        if ( !presto_ispresto(dentry->d_inode) ) {                EXIT;                goto out_lml;        }                fset = presto_fset(dentry);        error = -EINVAL;        if ( !fset ) {                printk("No fileset!\n");                EXIT;                goto out_lml;        }                /* setting offset to -1 appends */        rec.offset = -1;        /* this only requires a transaction below which is automatic */        error = presto_write_lml_close(&rec,                                        fset,                                       &file,                                        remote_ino,                                       remote_generation,                                       remote_version,                                       remote_file_version);                EXIT; out_lml:        path_release(&nd);        return error;}       /* given a path: write a close record and cancel an LML record, finally   call truncate LML.  Lento is doing this so it goes in with uid/gid's    root. */ int lento_cancel_lml(char *path,                      __u64 lml_offset,                      __u64 remote_ino,                      __u32 remote_generation,                     __u32 remote_version,                      struct lento_vfs_context *info){        struct nameidata nd;        struct rec_info rec;        struct dentry *dentry;        int error;        struct presto_file_set *fset;        void *handle;         struct presto_version new_ver;        ENTRY;        error = presto_walk(path, &nd);        if (error) {                EXIT;                return error;        }        dentry = nd.dentry;        error = -ENXIO;        if ( !presto_ispresto(dentry->d_inode) ) {                EXIT;                goto out_cancel_lml;

⌨️ 快捷键说明

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