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

📄 journal.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 5 页
字号:
int presto_fread(struct file *file, char *str, int len, loff_t *off){        int rc;        mm_segment_t old_fs;        ENTRY;        if ( len > 512 ) {                printk("presto_fread: read at %Ld for %d bytes, ino %ld\n",                       *off, len, file->f_dentry->d_inode->i_ino);         }        rc = -EINVAL;        if ( !off ) {                EXIT;                return rc;        }        if ( ! file ) {                EXIT;                return rc;        }        if ( ! file->f_op ) {                EXIT;                return rc;        }        if ( ! file->f_op->read ) {                EXIT;                return rc;        }        old_fs = get_fs();        set_fs(get_ds());        rc = file->f_op->read(file, str, len, off);        if (rc != len) {                printk("presto_fread: read %d bytes instead of "                       "%d at %ld\n", rc, len, (long)*off);                rc = -EIO;         }        set_fs(old_fs);        return rc;}static int presto_kml_dispatch(struct presto_file_set *fset){        int rc = 0;        unsigned int kml_recno;        struct presto_log_fd *fd = &fset->fset_kml;        loff_t  offset;        ENTRY;        write_lock(&fd->fd_lock);         /* Determine the largest valid offset, i.e. up until the first         * reservation held on the file. */        if ( !list_empty(&fd->fd_reservations) ) {                struct presto_reservation_data *rd;                rd = list_entry(fd->fd_reservations.next,                                 struct presto_reservation_data,                                 ri_list);                offset = rd->ri_offset;                kml_recno = rd->ri_recno;        } else {                offset = fd->fd_file->f_dentry->d_inode->i_size;                kml_recno = fset->fset_kml.fd_recno;         }        if ( kml_recno < fset->fset_lento_recno ) {                printk("presto_kml_dispatch: smoke is coming\n");                 write_unlock(&fd->fd_lock);                return 0;         } else if ( kml_recno == fset->fset_lento_recno ) {                write_unlock(&fd->fd_lock);                EXIT;                return 0;         }        CDEBUG(D_PIOCTL, "fset: %s\n", fset->fset_name);        rc = lento_kml(fset->fset_cache->cache_psdev->uc_minor,                       fset->fset_lento_off, fset->fset_lento_recno,                       offset, kml_recno, strlen(fset->fset_name),                       fset->fset_name);        if ( rc ) {                write_unlock(&fd->fd_lock);                EXIT;                return rc;        }        fset->fset_lento_off = offset;        fset->fset_lento_recno = kml_recno;         write_unlock(&fd->fd_lock);        EXIT;        return 0;}/* structure of an extended log record:   buf-prefix  buf-body [string1 [string2 [string3]]] buf-suffix   note: moves offset forward*/static inline int presto_write_record(struct file *f, loff_t *off,                        const char *buf, size_t size,                        const char *string1, int len1,                         const char *string2, int len2,                        const char *string3, int len3){        size_t prefix_size;         int rc;        prefix_size = size - sizeof(struct journal_suffix);        rc = presto_fwrite(f, buf, prefix_size, off);        if ( rc != prefix_size ) {                printk("Write error!\n");                EXIT;                return -EIO;        }        if  ( string1  && len1 ) {                rc = presto_fwrite(f, string1, len1, off);                if ( rc != len1 ) {                        printk("Write error!\n");                        EXIT;                        return -EIO;                }        }        if  ( string2 && len2 ) {                rc = presto_fwrite(f, string2, len2, off);                if ( rc != len2 ) {                        printk("Write error!\n");                        EXIT;                        return -EIO;                }        }        if  ( string3 && len3 ) {                rc = presto_fwrite(f, string3, len3, off);                if ( rc != len3 ) {                        printk("Write error!\n");                        EXIT;                        return -EIO;                }        }        rc = presto_fwrite(f, buf + prefix_size,                           sizeof(struct journal_suffix), off);        if ( rc != sizeof(struct journal_suffix) ) {                printk("Write error!\n");                EXIT;                return -EIO;        }        return 0;}/* * rec->size must be valid prior to calling this function. */static int presto_log(struct presto_file_set *fset, struct rec_info *rec,                      const char *buf, size_t size,                      const char *string1, int len1,                       const char *string2, int len2,                      const char *string3, int len3){        int rc;        struct presto_reservation_data rd;        loff_t offset;        struct presto_log_fd *fd;        struct journal_suffix *s;        int prefix_size;         ENTRY;        /* buf is NULL when no_journal is in effect */        if (!buf) {                EXIT;                return -EINVAL;        }        if (rec->is_kml) {                fd = &fset->fset_kml;        } else {                fd = &fset->fset_lml;        }        presto_reserve_record(fset, fd, rec, &rd);        offset = rec->offset;        /* now we know the record number */         prefix_size = size - sizeof(struct journal_suffix);        s = (struct journal_suffix *) (buf + prefix_size);         s->recno =  cpu_to_le32(rec->recno);         rc = presto_write_record(fd->fd_file, &offset, buf, size,                                  string1, len1, string2, len2, string3, len3);         if (rc) {                printk("presto: error writing record to %s\n",                        rec->is_kml ? "KML" : "LML");                 return rc;        }        presto_release_record(fd, &rd);        rc = presto_kml_dispatch(fset);        EXIT;        return rc;}/* read from the record at tail */static int presto_last_record(struct presto_log_fd *fd, loff_t *size,                              loff_t *tail_offset, __u32 *recno, loff_t tail){        struct journal_suffix suffix;        int rc;        loff_t zeroes;        *recno = 0;        *tail_offset = 0;        *size = 0;                if (tail < sizeof(struct journal_prefix) + sizeof(suffix)) {                EXIT;                return 0;        }        zeroes = tail - sizeof(int);        while ( zeroes >= 0 ) {                int data;                rc = presto_fread(fd->fd_file, (char *)&data, sizeof(data),                                   &zeroes);                if ( rc != sizeof(data) ) {                         rc = -EIO;                        return rc;                }                if (data)                        break;                zeroes -= 2 * sizeof(data);        }        /* zeroes at the begining of file. this is needed to prevent	   presto_fread errors  -SHP	*/        if (zeroes <= 0) return 0;                               zeroes -= sizeof(suffix);        rc = presto_fread(fd->fd_file, (char *)&suffix, sizeof(suffix), &zeroes);        if ( rc != sizeof(suffix) ) {                EXIT;                return rc;        }        if ( suffix.len > 500 ) {                printk("PRESTO: Warning long record tail at %ld, rec tail_offset at %ld (size %d)\n",                         (long) zeroes, (long)*tail_offset, suffix.len);         }        *recno = suffix.recno;        *size = suffix.len;        *tail_offset = zeroes;        return 0;}static int presto_kml_last_recno(struct presto_file_set *fset){        int rc;         loff_t size;        loff_t tail_offset;        int recno;        loff_t tail = fset->fset_kml.fd_file->f_dentry->d_inode->i_size;        if ((rc = presto_last_record(&fset->fset_kml, &size,                                         &tail_offset, &recno, tail)) ) {                EXIT;                return rc;        }        fset->fset_kml.fd_offset = tail_offset;        fset->fset_kml.fd_recno = recno;        CDEBUG(D_JOURNAL, "setting fset_kml->fd_recno to %d, offset  %Ld\n",               recno, tail_offset);         EXIT;        return 0;}static struct file *presto_log_open(struct presto_file_set *fset, char *name, int flags){        struct presto_cache *cache = fset->fset_cache;        struct file *f;        int error;        int mtpt_len, path_len;        char *path;        ENTRY;        mtpt_len = strlen(cache->cache_mtpt);        path_len = mtpt_len + strlen("/.intermezzo/") +                strlen(fset->fset_name) + strlen(name);        error = -ENOMEM;        PRESTO_ALLOC(path, char *, path_len + 1);        if ( !path ) {                EXIT;                return ERR_PTR(-ENOMEM);        }        sprintf(path, "%s/.intermezzo/%s/%s", cache->cache_mtpt,                fset->fset_name, name);        CDEBUG(D_INODE, "opening file %s\n", path);        f = filp_open(path, flags, 0);        error = PTR_ERR(f);        if (IS_ERR(f)) {                CDEBUG(D_INODE, "Error %d\n", error);                EXIT;                goto out_free;        }        error = -EINVAL;        if ( cache != presto_get_cache(f->f_dentry->d_inode) ) {                printk("PRESTO: %s cache does not match fset cache!\n", name);                fset->fset_kml.fd_file = NULL;                filp_close(f, NULL);                goto out_free;        }        if (cache->cache_filter &&  cache->cache_filter->o_trops &&	    cache->cache_filter->o_trops->tr_journal_data) {		CDEBUG(D_INODE, "\n");                cache->cache_filter->o_trops->tr_journal_data                        (f->f_dentry->d_inode);        } else {                printk("WARNING: InterMezzo no file data logging!\n");         } out_free:        PRESTO_FREE(path, path_len + 1);        EXIT;        return f;}int presto_init_kml_file(struct presto_file_set *fset){        int error = 0;        struct file *f;        ENTRY;        if (fset->fset_kml.fd_file) {                CDEBUG(D_INODE, "fset already has KML open\n");                EXIT;                return 0;        }        fset->fset_kml.fd_lock = RW_LOCK_UNLOCKED;        INIT_LIST_HEAD(&fset->fset_kml.fd_reservations);         f = presto_log_open(fset, "kml",  O_RDWR | O_CREAT);        if ( IS_ERR(f) ) {                error = PTR_ERR(f);                return error;        }        fset->fset_kml.fd_file = f;        error = presto_kml_last_recno(fset);        if ( error ) {                EXIT;                fset->fset_kml.fd_file = NULL;                filp_close(f, NULL);                printk("presto: IO error in KML of fset %s\n",                        fset->fset_name);        }        fset->fset_lento_off = fset->fset_kml.fd_offset;        fset->fset_lento_recno = fset->fset_kml.fd_recno;        EXIT;        return error;}int presto_init_last_rcvd_file(struct presto_file_set *fset){        int error = 0;        struct file *f;        ENTRY;        if (fset->fset_last_rcvd) {                CDEBUG(D_INODE, "fset already has last_rcvd open\n");                EXIT;                return 0;        }        f = presto_log_open(fset, "last_rcvd", O_RDWR | O_CREAT);        if ( IS_ERR(f) ) {                error = PTR_ERR(f);                return error;        }        fset->fset_last_rcvd = f;

⌨️ 快捷键说明

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