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

📄 journal.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 5 页
字号:
        EXIT;        return error;}int presto_init_lml_file(struct presto_file_set *fset){        int error = 0;        struct file *f;        ENTRY;        if (fset->fset_lml.fd_file) {                CDEBUG(D_INODE, "fset already has lml open\n");                EXIT;                return 0;        }        fset->fset_lml.fd_lock = RW_LOCK_UNLOCKED;        INIT_LIST_HEAD(&fset->fset_lml.fd_reservations);         f = presto_log_open(fset, "lml", O_RDWR | O_CREAT);        if ( IS_ERR(f) ) {                error = PTR_ERR(f);                return error;        }        fset->fset_lml.fd_file = f;        fset->fset_lml.fd_offset =                 fset->fset_lml.fd_file->f_dentry->d_inode->i_size;        EXIT;        return error;}/* Write the last_rcvd values to the last)_rcvd file */int presto_write_last_rcvd(struct rec_info *recinfo,                           struct presto_file_set *fset,                           struct lento_vfs_context *info){        int ret;        loff_t off = info->slot_offset;        struct {                __u32 remote_recno;                __u64 remote_offset;                __u32 local_recno;                __u64 local_offset;        } rcvd_rec;        rcvd_rec.remote_recno = cpu_to_le32(info->recno);        rcvd_rec.remote_offset = cpu_to_le64(info->kml_offset);        rcvd_rec.local_recno = cpu_to_le32(recinfo->recno);        rcvd_rec.local_offset = cpu_to_le64(recinfo->offset + recinfo->size);        ret = presto_fwrite(fset->fset_last_rcvd, (char *)(&rcvd_rec),                            sizeof(rcvd_rec), &off);        if (ret == sizeof(rcvd_rec))                ret = 0;        return ret;}/* LML records here *//* this writes the LML records for close, in conjunction with the KML  */int presto_write_lml_close(struct rec_info *rec,                           struct presto_file_set *fset,                            struct file *file,                           __u64 remote_ino,                           __u32 remote_generation,                           __u32 remote_version,                           struct presto_version *new_file_ver){        int opcode = PRESTO_OP_CLOSE;        char *buffer;        struct dentry *dentry = file->f_dentry;         __u64 ino;        __u32 pathlen;        char *path;        __u32 generation;        int size;        char *logrecord;        char record[292];        struct dentry *root;        int error;        ENTRY;        if ( presto_no_journal(fset) ) {          EXIT;          return 0;        }        root = fset->fset_mtpt;        BUFF_ALLOC(buffer, NULL);        path = presto_path(dentry, root, buffer, PAGE_SIZE);        CDEBUG(D_INODE, "Path: %s\n", path);        pathlen = cpu_to_le32(MYPATHLEN(buffer, path));        ino = cpu_to_le64(dentry->d_inode->i_ino);        generation = cpu_to_le32(dentry->d_inode->i_generation);        size =  sizeof(__u32) * current->ngroups +                 sizeof(struct journal_prefix) + sizeof(*new_file_ver) +                sizeof(ino) + sizeof(generation) + sizeof(pathlen) +                sizeof(remote_ino) + sizeof(remote_generation) +                 sizeof(remote_version) + sizeof(rec->offset) +                sizeof(struct journal_suffix);        if ( size > sizeof(record) ) {                printk("PRESTO: BUFFER OVERFLOW in %s!\n", __FUNCTION__);        }        rec->is_kml = 0;        rec->size = size + size_round(le32_to_cpu(pathlen));        logrecord = journal_log_prefix(record, opcode, rec);        logrecord = logit(logrecord, new_file_ver, sizeof(*new_file_ver));        logrecord = logit(logrecord, &ino, sizeof(ino));        logrecord = logit(logrecord, &generation, sizeof(generation));        logrecord = logit(logrecord, &pathlen, sizeof(pathlen));        logrecord = logit(logrecord, &remote_ino, sizeof(remote_ino));        logrecord = logit(logrecord, &remote_generation,                          sizeof(remote_generation));        logrecord = logit(logrecord, &remote_version, sizeof(remote_version));        logrecord = logit(logrecord, &rec->offset, sizeof(rec->offset));        logrecord = journal_log_suffix(logrecord, record, fset, dentry, rec);        error = presto_log(fset, rec, record, size,                           path, size_round(le32_to_cpu(pathlen)),                           NULL, 0, NULL, 0);        BUFF_FREE(buffer);        EXIT;        return error;}int presto_journal_write(struct rec_info *rec,                         struct presto_file_set *fset,                          struct file *file){        struct presto_version file_version;        int rc;        ENTRY;        presto_getversion(&file_version, file->f_dentry->d_inode);         /* append this record */        rc = presto_write_lml_close                (rec,                  fset,                  file,                 0, /* remote_ino */                 0, /* remote_generation */                 0, /* remote_version */                 &file_version);        EXIT;        return rc;}/*  * Check if the given record is at the end of the file. If it is, truncate * the lml to the record's offset, removing it. Repeat on prior record, * until we reach an active record or a reserved record (as defined by the * reservations list). */static int presto_truncate_lml_tail(struct presto_file_set *fset){        loff_t lml_tail;        loff_t lml_last_rec;        loff_t lml_last_recsize;        loff_t local_offset;        int recno;        struct journal_prefix prefix;        struct inode *inode = fset->fset_lml.fd_file->f_dentry->d_inode;        void *handle;        int rc;        ENTRY;        /* If someone else is already truncating the LML, return. */        write_lock(&fset->fset_lml.fd_lock);         if (fset->fset_lml.fd_truncating == 1 ) {                write_unlock(&fset->fset_lml.fd_lock);                 EXIT;                return 0;        }        /* someone is about to write to the end of the LML */         if ( !list_empty(&fset->fset_lml.fd_reservations) ) {                write_unlock(&fset->fset_lml.fd_lock);                 EXIT;                return 0;        }       lml_tail = fset->fset_lml.fd_file->f_dentry->d_inode->i_size;       /* Nothing to truncate?*/       if (lml_tail == 0) {                write_unlock(&fset->fset_lml.fd_lock);                 EXIT;                return 0;       }       fset->fset_lml.fd_truncating = 1;       write_unlock(&fset->fset_lml.fd_lock);        presto_last_record(&fset->fset_lml, &lml_last_recsize,                          &lml_last_rec, &recno, lml_tail);       /* Do we have a record to check? If not we have zeroes at the          beginning of the file. -SHP       */       if (lml_last_recsize != 0) {       		local_offset = lml_last_rec - lml_last_recsize;       		rc = presto_fread(fset->fset_lml.fd_file, (char *)&prefix,                            		sizeof(prefix), &local_offset);         	if (rc != sizeof(prefix)) {                	EXIT;                	goto tr_out;        	}               	if ( prefix.opcode != PRESTO_OP_NOOP ) {                	EXIT;                	rc = 0;                        /* We may have zeroes at the end of the file, should			   we clear them out? -SHP                        */                	goto tr_out;        	}	} else 	 	lml_last_rec=0;        handle = presto_trans_start(fset, inode, PRESTO_OP_TRUNC);        if ( !handle ) {                EXIT;                rc = -ENOMEM;                goto tr_out;        }        rc = presto_do_truncate(fset, fset->fset_lml.fd_file->f_dentry,                                 lml_last_rec - lml_last_recsize, lml_tail);        presto_trans_commit(fset, handle);         if ( rc == 0 ) {                rc = 1;        }        EXIT; tr_out:        CDEBUG(D_JOURNAL, "rc = %d\n", rc);        write_lock(&fset->fset_lml.fd_lock);        fset->fset_lml.fd_truncating = 0;        write_unlock(&fset->fset_lml.fd_lock);        return rc;}int presto_truncate_lml(struct presto_file_set *fset){        int rc;         ENTRY;                while ( (rc = presto_truncate_lml_tail(fset)) > 0);        if ( rc < 0 && rc != -EALREADY) {                printk("truncate_lml error %d\n", rc);         }        EXIT;        return rc;}int presto_clear_lml_close(struct presto_file_set *fset,                            loff_t  lml_offset){        int rc;        struct journal_prefix record;        loff_t offset = lml_offset;        ENTRY;        if ( presto_no_journal(fset) ) {                EXIT;                return 0;        }        CDEBUG(D_JOURNAL, "reading prefix: off %ld, size %Zd\n",                (long)lml_offset, sizeof(record));        rc = presto_fread(fset->fset_lml.fd_file, (char *)&record,                          sizeof(record), &offset);        if ( rc != sizeof(record) ) {                printk("presto: clear_lml io error %d\n", rc);                 EXIT;                return -EIO;        }        /* overwrite the prefix */         CDEBUG(D_JOURNAL, "overwriting prefix: off %ld\n", (long)lml_offset);        record.opcode = PRESTO_OP_NOOP;        offset = lml_offset;        /* note: this does just a single transaction in the cache */        rc = presto_fwrite(fset->fset_lml.fd_file, (char *)(&record),                               sizeof(record), &offset);        if ( rc != sizeof(record) ) {                EXIT;                return -EIO;        }        EXIT;        return 0; }/* now a journal function for every operation */int presto_journal_setattr(struct rec_info *rec,                            struct presto_file_set *fset,                            struct dentry *dentry,                           struct presto_version *old_ver, struct iattr *iattr){        int opcode = PRESTO_OP_SETATTR;        char *buffer;        char *path;        __u32 pathlen;        int size;        char *logrecord;        char record[292];        struct dentry *root;        __u32 uid, gid, mode, valid, flags;        __u64 fsize, mtime, ctime;        int error;        ENTRY;        if ( presto_no_journal(fset) ) {                EXIT;                return 0;        }        if (!dentry->d_inode || (dentry->d_inode->i_nlink == 0) ) {                EXIT;                return 0;        }        root = fset->fset_mtpt;        BUFF_ALLOC(buffer, NULL);        path = presto_path(dentry, root, buffer, PAGE_SIZE);        pathlen = cpu_to_le32(MYPATHLEN(buffer, path));        size =  sizeof(__u32) * current->ngroups +                 sizeof(struct journal_prefix) + sizeof(*old_ver) +                sizeof(valid) + sizeof(mode) + sizeof(uid) + sizeof(gid) +                sizeof(fsize) + sizeof(mtime) + sizeof(ctime) + sizeof(flags) +                sizeof(pathlen) + sizeof(struct journal_suffix);        if ( size > sizeof(record) ) {                printk("PRESTO: BUFFER OVERFLOW in %s!\n", __FUNCTION__);        }        /* Only journal one kind of mtime, and not atime at all.  Also don't         * journal bogus data in iattr, to make the journal more compressible.         */        if (iattr->ia_valid & ATTR_MTIME_SET)                iattr->ia_valid = iattr->ia_valid | ATTR_MTIME;        valid = cpu_to_le32(iattr->ia_valid & ~(ATTR_ATIME | ATTR_MTIME_SET |                                                ATTR_ATIME_SET));        mode = iattr->ia_valid & ATTR_MODE ? cpu_to_le32(iattr->ia_mode): 0;        uid = iattr->ia_valid & ATTR_UID ? cpu_to_le32(iattr->ia_uid): 0;        gid = iattr->ia_valid & ATTR_GID ? cpu_to_le32(iattr->ia_gid): 0;        fsize = iattr->ia_valid & ATTR_SIZE ? cpu_to_le64(iattr->ia_size): 0;        mtime = iattr->ia_valid & ATTR_MTIME ? cpu_to_le64(iattr->ia_mtime): 0;        ctime = iattr->ia_valid & ATTR_CTIME ? cpu_to_le64(iattr->ia_ctime): 0;        flags = iattr->ia_valid & ATTR_ATTR_FLAG ?                cpu_to_le32(iattr->ia_attr_flags): 0;        rec->is_kml = 1;        rec->size = size + size_round(le32_to_cpu(pathlen));        logrecord = journal_log_prefix(record, opcode, rec);        logrecord = logit(logrecord, old_ver, sizeof(*old_ver));        logrecord = logit(logrecord, &valid, sizeof(valid));        logrecord = logit(logrecord, &mode, sizeof(mode));        logrecord = logit(logrecord, &uid, sizeof(uid));        logrecord = logit(logrecord, &gid, sizeof(gid));        logrecord = logit(logrecord, &fsize, sizeof(fsize));        logrecord = logit(logrecord, &mtime, sizeof(mtime));        logrecord = logit(logrecord, &ctime, sizeof(ctime));        logrecord = logit(logrecord, &flags, sizeof(flags));        logrecord = logit(logrecord, &pathlen, sizeof(pathlen));        logrecord = journal_log_suffix(logrecord, record, fset, dentry, rec);        error = presto_log(fset, rec, record, size,                           path, size_round(le32_to_cpu(pathlen)),                           NULL, 0, NULL, 0);        BUFF_FREE(buffer);        EXIT;        return error;}int presto_journal_create(struct rec_info *rec, struct presto_file_set *fset,                          struct dentry *dentry,                          struct presto_version *tgt_dir_ver,                          struct presto_version *new_file_ver, int mode){        int opcode = PRESTO_OP_CREATE;        char *buffer;        char *path;        __u32 pathlen;        int size;        char *logrecord;

⌨️ 快捷键说明

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