📄 journal.c
字号:
sizeof(struct journal_prefix) + 4 * sizeof(*src_dir_ver) + sizeof(srcpathlen) + sizeof(pathlen) + sizeof(struct journal_suffix); if ( size > sizeof(record) ) { printk("PRESTO: BUFFER OVERFLOW in %s!\n", __FUNCTION__); } rec->is_kml = 1; rec->size = size + size_round(le32_to_cpu(pathlen)) + size_round(le32_to_cpu(srcpathlen)); logrecord = journal_log_prefix(record, opcode, rec); logrecord = logit(logrecord, src_dir_ver, sizeof(*src_dir_ver)); logrecord = log_version(logrecord, src->d_parent); logrecord = logit(logrecord, tgt_dir_ver, sizeof(*tgt_dir_ver)); logrecord = log_version(logrecord, tgt->d_parent); logrecord = logit(logrecord, &srcpathlen, sizeof(srcpathlen)); logrecord = logit(logrecord, &pathlen, sizeof(pathlen)); logrecord = journal_log_suffix(logrecord, record, fset, tgt, rec); error = presto_log(fset, rec, record, size, srcpath, size_round(le32_to_cpu(srcpathlen)), path, size_round(le32_to_cpu(pathlen)), NULL, 0); BUFF_FREE(buffer); BUFF_FREE(srcbuffer); EXIT; return error;}int presto_journal_unlink(struct rec_info *rec, struct presto_file_set *fset, struct dentry *dir, struct presto_version *tgt_dir_ver, struct presto_version *old_file_ver, int len, const char *name){ int opcode = PRESTO_OP_UNLINK; char *buffer; char *path; __u32 pathlen, llen; 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; llen = cpu_to_le32(len); BUFF_ALLOC(buffer, NULL); path = presto_path(dir, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); size = sizeof(__u32) * current->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(pathlen) + sizeof(llen) + sizeof(struct journal_suffix); if ( size > sizeof(record) ) { printk("PRESTO: BUFFER OVERFLOW in %s!\n", __FUNCTION__); } rec->is_kml = 1; rec->size = size + size_round(le32_to_cpu(pathlen)) + size_round(len); logrecord = journal_log_prefix(record, opcode, rec); logrecord = logit(logrecord, tgt_dir_ver, sizeof(*tgt_dir_ver)); logrecord = log_version(logrecord, dir); logrecord = logit(logrecord, old_file_ver, sizeof(*old_file_ver)); logrecord = logit(logrecord, &pathlen, sizeof(pathlen)); logrecord = logit(logrecord, &llen, sizeof(llen)); logrecord = journal_log_suffix(logrecord, record, fset, dir, rec); error = presto_log(fset, rec, record, size, path, size_round(le32_to_cpu(pathlen)), name, size_round(len), NULL, 0); BUFF_FREE(buffer); EXIT; return error;}intpresto_journal_close(struct rec_info *rec, struct presto_file_set *fset, struct file *file, struct dentry *dentry, struct presto_version *new_file_ver){ int opcode = PRESTO_OP_CLOSE; struct presto_file_data *fd; char *buffer; char *path; __u64 ino; __u32 pathlen; __u32 generation; int size; char *logrecord; char record[292]; struct dentry *root; int error; __u32 open_fsuid; __u32 open_fsgid; __u32 open_ngroups; __u32 open_groups[NGROUPS_MAX]; __u32 open_mode; __u32 open_uid; __u32 open_gid; int i; 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; fd = (struct presto_file_data *)file->private_data; if (fd) { open_ngroups = fd->fd_ngroups; for (i = 0; i < fd->fd_ngroups; i++) open_groups[i] = (__u32) fd->fd_groups[i]; open_mode = fd->fd_mode; open_uid = fd->fd_uid; open_gid = fd->fd_gid; open_fsuid = fd->fd_fsuid; open_fsgid = fd->fd_fsgid; } else { open_ngroups = current->ngroups; for (i=0; i<current->ngroups; i++) open_groups[i] = (__u32) current->groups[i]; open_mode = dentry->d_inode->i_mode; open_uid = dentry->d_inode->i_uid; open_gid = dentry->d_inode->i_gid; open_fsuid = current->fsuid; open_fsgid = current->fsgid; } BUFF_ALLOC(buffer, NULL); path = presto_path(dentry, root, buffer, PAGE_SIZE); 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) * open_ngroups + sizeof(open_mode) + sizeof(open_uid) + sizeof(open_gid) + sizeof(struct journal_prefix) + sizeof(*new_file_ver) + sizeof(ino) + sizeof(generation) + sizeof(pathlen) + sizeof(struct journal_suffix); if ( size > sizeof(record) ) { printk("PRESTO: BUFFER OVERFLOW in %s!\n", __FUNCTION__); } rec->is_kml = 1; rec->size = size + size_round(le32_to_cpu(pathlen)); logrecord = journal_log_prefix_with_groups_and_ids( record, opcode, rec, open_ngroups, open_groups, open_fsuid, open_fsgid); logrecord = logit(logrecord, &open_mode, sizeof(open_mode)); logrecord = logit(logrecord, &open_uid, sizeof(open_uid)); logrecord = logit(logrecord, &open_gid, sizeof(open_gid)); 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 = 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_rewrite_close(struct rec_info *rec, struct presto_file_set *fset, char *path, __u32 pathlen, int ngroups, __u32 *groups, __u64 ino, __u32 generation, struct presto_version *new_file_ver){ int opcode = PRESTO_OP_CLOSE; 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; size = sizeof(__u32) * ngroups + sizeof(struct journal_prefix) + sizeof(*new_file_ver) + sizeof(ino) + sizeof(generation) + sizeof(le32_to_cpu(pathlen)) + sizeof(struct journal_suffix); if ( size > sizeof(record) ) { printk("PRESTO: BUFFER OVERFLOW in %s!\n", __FUNCTION__); } rec->is_kml = 1; rec->size = size + size_round(le32_to_cpu(pathlen)); logrecord = journal_log_prefix_with_groups(record, opcode, rec, ngroups, groups); 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 = journal_log_suffix(logrecord, record, fset, NULL, rec); error = presto_log(fset, rec, record, size, path, size_round(le32_to_cpu(pathlen)), NULL, 0, NULL, 0); EXIT; return error;}/* write closes for the local close records in the LML */ int presto_complete_lml(struct presto_file_set *fset){ __u32 groups[NGROUPS_MAX]; loff_t lml_offset; loff_t read_offset; char *buffer; void *handle; struct rec_info rec; struct close_rec { struct presto_version new_file_ver; __u64 ino; __u32 generation; __u32 pathlen; __u64 remote_ino; __u32 remote_generation; __u32 remote_version; __u64 lml_offset; } close_rec; struct file *file = fset->fset_lml.fd_file; struct journal_prefix prefix; int rc = 0; ENTRY; lml_offset = 0; again: if (lml_offset >= file->f_dentry->d_inode->i_size) { EXIT; return rc; } read_offset = lml_offset; rc = presto_fread(file, (char *)&prefix, sizeof(prefix), &read_offset); if ( rc != sizeof(prefix) ) { EXIT; printk("presto_complete_lml: ioerror - 1, tell Peter\n"); return -EIO; } if ( prefix.opcode == PRESTO_OP_NOOP ) { lml_offset += prefix.len; goto again; } rc = presto_fread(file, (char *)groups, prefix.ngroups * sizeof(__u32), &read_offset); if ( rc != prefix.ngroups * sizeof(__u32) ) { EXIT; printk("presto_complete_lml: ioerror - 2, tell Peter\n"); return -EIO; } rc = presto_fread(file, (char *)&close_rec, sizeof(close_rec), &read_offset); if ( rc != sizeof(close_rec) ) { EXIT; printk("presto_complete_lml: ioerror - 3, tell Peter\n"); return -EIO; } /* is this a backfetch or a close record? */ if ( le64_to_cpu(close_rec.remote_ino) != 0 ) { lml_offset += prefix.len; goto again; } BUFF_ALLOC(buffer, NULL); rc = presto_fread(file, (char *)buffer, le32_to_cpu(close_rec.pathlen), &read_offset); if ( rc != le32_to_cpu(close_rec.pathlen) ) { EXIT; printk("presto_complete_lml: ioerror - 4, tell Peter\n"); return -EIO; } handle = presto_trans_start(fset, file->f_dentry->d_inode, PRESTO_OP_RELEASE); if ( !handle ) { EXIT; return -ENOMEM; } rc = presto_clear_lml_close(fset, lml_offset); if ( rc ) { printk("error during clearing: %d\n", rc); presto_trans_commit(fset, handle); EXIT; return rc; } rc = presto_rewrite_close(&rec, fset, buffer, close_rec.pathlen, prefix.ngroups, groups, close_rec.ino, close_rec.generation, &close_rec.new_file_ver); if ( rc ) { printk("error during rewrite close: %d\n", rc); presto_trans_commit(fset, handle); EXIT; return rc; } presto_trans_commit(fset, handle); if ( rc ) { printk("error during truncation: %d\n", rc); EXIT; return rc; } lml_offset += prefix.len; CDEBUG(D_JOURNAL, "next LML record at: %ld\n", (long)lml_offset); goto again; EXIT; return -EINVAL;}#ifdef CONFIG_FS_EXT_ATTR/* Journal an ea operation. A NULL buffer implies the attribute is * getting deleted. In this case we simply change the opcode, but nothing * else is affected. */int presto_journal_set_ext_attr (struct rec_info *rec, struct presto_file_set *fset, struct dentry *dentry, struct presto_version *ver, const char *name, const char *buffer, int buffer_len, int flags) { int opcode = (buffer == NULL) ? PRESTO_OP_DELEXTATTR : PRESTO_OP_SETEXTATTR ; char *temp; char *path; __u32 pathlen; int size; char *logrecord; char record[292]; struct dentry *root; int error; __u32 namelen=cpu_to_le32(strnlen(name,PRESTO_EXT_ATTR_NAME_MAX)); __u32 buflen=(buffer != NULL)? cpu_to_le32(buffer_len): cpu_to_le32(0); __u32 mode; 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -