int req_get(int sockfd, struct message_s *msg) { char *filepath = payload_malloc(sockfd, msg, true); char *repopath = make_path(filepath); printf("client wants %s\n", repopath); int local_fd = open(repopath, O_RDONLY); free(filepath); free(repopath); if (local_fd == -1) { write_head(sockfd, TYPE_GET_REP, 0, 0); /* though not readable, don't terminate because it is legal */ return -1; } /* send GET_REPLY success header */ write_head(sockfd, TYPE_GET_REP, 1, 0); struct stat st; fstat(local_fd, &st); /* send FILE_DATA header */ write_head(sockfd, TYPE_FILE_DATA, STATUS_UNUSED, st.st_size); #ifdef __linux__ int ret = transfer_file_sys(sockfd, local_fd, st.st_size, NULL); #else int ret = transfer_file_copy(sockfd, local_fd, st.st_size, NULL); #endif close(local_fd); if (ret == -1) close_serving_thread(sockfd); return 0; }
static void commit(void) { if (log.lh.n > 0) { write_log(); // Write modified blocks from cache to log write_head(); // Write header to disk -- the real commit install_trans(); // Now install writes to home locations log.lh.n = 0; write_head(); // Erase the transaction from the log } }
void commit_trans(void) { if (log.lh.n > 0) { write_head(); // Write header to disk -- the real commit install_trans(); // Now install writes to home locations log.lh.n = 0; write_head(); // Erase the transaction from the log } acquire(&log.lock); log.busy = 0; wakeup(&log); release(&log.lock); }
void commit_trans(void) { if (log.lh.n > 0) { write_head(); // Causes all blocks till log.head to be commited install_trans(); // Install all the transactions till head log.lh.n = 0; write_head(); // Reclaim log } acquire(&log.lock); log.intrans = 0; wakeup(&log); release(&log.lock); }
int req_auth(int sockfd, struct message_s *msg) { char *payload = payload_malloc(sockfd, msg, true); struct user guest; if (!parse_user(payload, &guest)) return -1; int res = -1; for (int i=0; i < USER_MAX; i++) { if (!user_list[i].id) { /* reach the end */ res = -1; break; } if (strcmp(user_list[i].id, guest.id) == 0 && (strcmp(user_list[i].passwd, guest.passwd) == 0)) { /* match */ printf("%s logged in\n", guest.id); res = 0; break; } } free(payload); write_head(sockfd, TYPE_AUTH_REP, (res == 0 ? 1 : 0), 0); return res; }
int req_quit(int sockfd, struct message_s *msg) { write_head(sockfd, TYPE_QUIT_REP, STATUS_UNUSED, 0); puts("client request to quit"); close_serving_thread(sockfd); return 0; }
int req_ls(int sockfd, struct message_s *msg) { char buff[2048]; DIR *dirp; if (!(dirp = opendir(ROOT_DIR))) { perror(ROOT_DIR " not exist"); return -1; } struct dirent *dp; int char_len = 0; while ((dp = readdir(dirp))) { if(dp->d_type == DT_DIR) continue; int new_len = char_len + (strlen(dp->d_name) + 1); if (new_len >= (2048-1)) break; strcpy(buff + char_len, dp->d_name); strcpy(buff + char_len + strlen(dp->d_name), "\n"); printf("%d\n", char_len); char_len = new_len; } closedir(dirp); /* not sending terminate '\0' */ printf("%d\n", char_len); write_head(sockfd, TYPE_LS_REP, 1, char_len); swrite(sockfd, buff, char_len); return 0; }
int req_put(int sockfd, struct message_s *msg) { char *filepath = payload_malloc(sockfd, msg, true); char *repopath = make_path(filepath); printf("client put %s\n", repopath); int saveto_fd = open(repopath, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); free(filepath); free(repopath); if (saveto_fd == -1) { perror("cannot open file to write"); close_serving_thread(sockfd); } /* always says that you can upload */ write_head(sockfd, TYPE_PUT_REP, 1, 0); /* receive DATA_FILE */ struct message_s recv_msg; read_head(sockfd, &recv_msg); off_t size = payload_size(&recv_msg); int ret = transfer_file_copy(saveto_fd, sockfd, size, NULL); close(saveto_fd); if (ret == -1) close_serving_thread(sockfd); return 0; }
/** * ubifs_jnl_write_2_inodes - write 2 inodes to the journal. * @c: UBIFS file-system description object * @inode1: first inode to write * @inode2: second inode to write * @sync: non-zero if the write-buffer has to be synchronized * * This function writes 2 inodes @inode1 and @inode2 to the journal (to the * base head - first @inode1, then @inode2). Returns zero in case of success * and a negative error code in case of failure. */ int ubifs_jnl_write_2_inodes(struct ubifs_info *c, const struct inode *inode1, const struct inode *inode2, int sync) { int err, len1, len2, aligned_len, aligned_len1, lnum, offs; struct ubifs_ino_node *ino; union ubifs_key key; dbg_jnl("ino %lu, ino %lu", inode1->i_ino, inode2->i_ino); ubifs_assert(inode1->i_nlink > 0); ubifs_assert(inode2->i_nlink > 0); len1 = UBIFS_INO_NODE_SZ + ubifs_inode(inode1)->data_len; len2 = UBIFS_INO_NODE_SZ + ubifs_inode(inode2)->data_len; aligned_len1 = ALIGN(len1, 8); aligned_len = aligned_len1 + ALIGN(len2, 8); ino = kmalloc(aligned_len, GFP_NOFS); if (!ino) return -ENOMEM; /* Make reservation before allocating sequence numbers */ err = make_reservation(c, BASEHD, aligned_len); if (err) goto out_free; pack_inode(c, ino, inode1, 0, 0); pack_inode(c, (void *)ino + aligned_len1, inode2, 1, 0); err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); if (!sync && !err) { struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; ubifs_wbuf_add_ino_nolock(wbuf, inode1->i_ino); ubifs_wbuf_add_ino_nolock(wbuf, inode2->i_ino); } release_head(c, BASEHD); if (err) goto out_ro; ino_key_init(c, &key, inode1->i_ino); err = ubifs_tnc_add(c, &key, lnum, offs, len1); if (err) goto out_ro; ino_key_init(c, &key, inode2->i_ino); err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2); if (err) goto out_ro; finish_reservation(c); kfree(ino); return 0; out_ro: ubifs_ro_mode(c, err); finish_reservation(c); out_free: kfree(ino); return err; }
int ana_head(struct sbpfs_head* head, char* data) { char* ip; int port; char* headmethod; char* blocknumc; char* offsetc; char* lengthc; blocknumc = get_head_entry_value(head, "Arg0"); offsetc = get_head_entry_value(head, "Arg1"); lengthc = get_head_entry_value(head, "Arg2"); u64_t blocknum = atoll(blocknumc); req_len = atoll(lengthc); u64_t req_offset = atoll(offsetc); if ((headmethod = get_head_entry_value(head, "method")) == NULL) { perror("fail to ananlyse! \n"); return -1; } else if (strcmp(headmethod, "READ") == 0) { int succeed=readblock(blocknum, req_offset, req_len); sbphead = read_head(databuf, req_len,succeed); build_headr(&send_buf, &sbphead); } else if (strcmp(headmethod, "WRITE") == 0) { int succeed = writeblock(blocknum, req_offset, req_len, data); sbphead = write_head(databuf, req_len,succeed); build_headw(&send_buf, &sbphead); reportwrite(ip, blocknum, port, succeed); } return 0; }
static void recover_from_log(void) { read_head(); install_trans(); // if committed, copy from log to disk log.lh.n = 0; write_head(); // clear the log }
/** * ubifs_jrn_write_inode - flush inode to the journal. * @c: UBIFS file-system description object * @inode: inode to flush * @last_reference: inode has been deleted * @sync: non-zero if the write-buffer has to be synchronized * * This function writes inode @inode to the journal (to the base head). Returns * zero in case of success and a negative error code in case of failure. */ int ubifs_jrn_write_inode(struct ubifs_info *c, const struct inode *inode, int last_reference, int sync) { int err, len, lnum, offs; struct ubifs_ino_node *ino; struct ubifs_inode *ui = ubifs_inode(inode); dbg_jrn("ino %lu%s", inode->i_ino, last_reference ? " (last reference)" : ""); if (last_reference) ubifs_assert(inode->i_nlink == 0); /* If the inode is deleted, do not write the attached data */ len = UBIFS_INO_NODE_SZ; if (!last_reference) len += ui->data_len; ino = kmalloc(len, GFP_NOFS); if (!ino) return -ENOMEM; pack_inode(c, ino, inode, 1, last_reference); err = make_reservation(c, BASEHD, len); if (err) goto out_free; err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); if (!sync && !err) ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inode->i_ino); release_head(c, BASEHD); if (err) goto out_ro; if (last_reference) { err = ubifs_tnc_remove_ino(c, inode->i_ino); if (err) goto out_ro; ubifs_delete_orphan(c, inode->i_ino); err = ubifs_add_dirt(c, lnum, len); } else { union ubifs_key key; ino_key_init(c, &key, inode->i_ino); err = ubifs_tnc_add(c, &key, lnum, offs, len); } if (err) goto out_ro; finish_reservation(c); kfree(ino); return 0; out_ro: ubifs_ro_mode(c, err); finish_reservation(c); out_free: kfree(ino); return err; }
static void recover_from_log(void) { read_head(); cprintf("recovery: n=%d\n", log.lh.n); install_trans(); log.lh.n = 0; write_head(); }
int text_to_speech(byte *buf, int len) { const char* sess_id = NULL; char *obuf = NULL; unsigned int audio_len = 0; unsigned int olen = 0; int synth_status = 1; int ret = 0; byte erlret = 0; debug("Texting to speech %d bytes, %s", len, buf); ret = MSPLogin(NULL, NULL, login_configs); if ( ret != MSP_SUCCESS ) { debug("MSPLogin failed: %d", ret); return ret; } sess_id = QTTSSessionBegin(tts_params, &ret); if ( ret != MSP_SUCCESS ) { debug("QTTSSessionBegin failed: %d", ret); return ret; } ret = QTTSTextPut(sess_id, buf, len, NULL ); if ( ret != MSP_SUCCESS ) { debug("QTTSTextPut failed: %d", ret); QTTSSessionEnd(sess_id, "TextPutError"); return ret; } while (1) { const void *data = QTTSAudioGet(sess_id, &audio_len, &synth_status, &ret); if (NULL != data) { obuf = realloc(obuf, olen+audio_len); memcpy(obuf+olen, data, audio_len); olen += audio_len; } usleep(15000); if (synth_status == 2 || ret != 0) break; } debug("got %d bytes speech", olen); write_head(sizeof(erlret)+olen); write_exact(&erlret, sizeof(erlret)); write_exact(obuf, olen); free(obuf); QTTSSessionEnd(sess_id, NULL); MSPLogout(); return 0; }
/** * @brief Start operations to retrieve data from the data file and make the new * hosts file for the current operating system. */ void MakeHosts::make() { RetrieveData::Instance()->connect_db(); make_time = QDateTime::currentDateTime(); hosts_file->open(QIODevice::WriteOnly); write_head(); write_info(); get_hosts(make_cfg); hosts_file->close(); RetrieveData::Instance()->disconnect_db(); }
int DxfMap::save(char *filename, int savefeatureNum, double scaleFactor) { FILE *fp; int i; double x, y; for (i = 0; i < savefeatureNum; i++) { x = feature[i].y / scaleFactor; y = feature[i].x / scaleFactor; feature[i].x = x; feature[i].y = y; x = feature[i].y2 / scaleFactor; y = feature[i].x2 / scaleFactor; feature[i].x2 = x; feature[i].y2 = y; } if ((fp = fopen(filename, "w")) == NULL) { printf("Can't open dxf file \"%s\"\n", filename); return -EIO; } write_head(fp); for (i = 0; i < savefeatureNum; i ++) { if (feature[i].l == 0) { write_point(fp, &feature[i]); } else { write_line(fp, &feature[i]); } } write_eof(fp); fclose(fp); return 0; }
/** * ubifs_jrn_truncate - update the journal for a truncation. * @c: UBIFS file-system description object * @inum: inode number of inode being truncated * @old_size: old size * @new_size: new size * * When the size of a file decreases due to truncation, a truncation node is * written, the journal tree is updated, and the last data block is re-written * if it has been affected. * * This function returns %0 in the case of success, and a negative error code in * case of failure. */ int ubifs_jrn_truncate(struct ubifs_info *c, ino_t inum, loff_t old_size, loff_t new_size) { union ubifs_key key, to_key; struct ubifs_trun_node *trun; struct ubifs_data_node *dn; int err, dlen, len, lnum, offs, bit, sz; unsigned int blk; dbg_jrn("ino %lu, size %lld -> %lld", inum, old_size, new_size); sz = UBIFS_TRUN_NODE_SZ + UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; trun = kmalloc(sz, GFP_NOFS); if (!trun) return -ENOMEM; trun->ch.node_type = UBIFS_TRUN_NODE; trun_key_init_flash(c, &trun->key, inum); trun->old_size = cpu_to_le64(old_size); trun->new_size = cpu_to_le64(new_size); ubifs_prepare_node(c, trun, UBIFS_TRUN_NODE_SZ, 0); dlen = new_size & (UBIFS_BLOCK_SIZE - 1); if (dlen) { /* Get last data block so it can be truncated */ dn = (void *)trun + ALIGN(UBIFS_TRUN_NODE_SZ, 8); blk = new_size / UBIFS_BLOCK_SIZE; data_key_init(c, &key, inum, blk); dbg_jrn_key(c, &key, "key"); err = ubifs_tnc_lookup(c, &key, dn); if (err == -ENOENT) dlen = 0; /* Not found (so it is a hole) */ else if (err) goto out_free; else { if (le32_to_cpu(dn->size) <= dlen) dlen = 0; /* Nothing to do */ else { int compr_type = le16_to_cpu(dn->compr_type); if (compr_type != UBIFS_COMPR_NONE) { err = recomp_data_node(dn, &dlen); if (err) goto out_free; } else { dn->size = cpu_to_le32(dlen); dlen += UBIFS_DATA_NODE_SZ; } zero_data_node_unused(dn); ubifs_prepare_node(c, dn, dlen, 0); } } } if (dlen) len = ALIGN(UBIFS_TRUN_NODE_SZ, 8) + dlen; else len = UBIFS_TRUN_NODE_SZ; err = make_reservation(c, BASEHD, len); if (err) goto out_free; err = write_head(c, BASEHD, trun, len, &lnum, &offs, 0); if (!err) ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum); release_head(c, BASEHD); if (err) goto out_ro; if (dlen) { offs += ALIGN(UBIFS_TRUN_NODE_SZ, 8); err = ubifs_tnc_add(c, &key, lnum, offs, dlen); if (err) goto out_ro; } err = ubifs_add_dirt(c, lnum, UBIFS_TRUN_NODE_SZ); if (err) goto out_ro; bit = new_size & (UBIFS_BLOCK_SIZE - 1); blk = new_size / UBIFS_BLOCK_SIZE + (bit ? 1 : 0); data_key_init(c, &key, inum, blk); bit = old_size & (UBIFS_BLOCK_SIZE - 1); blk = old_size / UBIFS_BLOCK_SIZE - (bit ? 0: 1); data_key_init(c, &to_key, inum, blk); err = ubifs_tnc_remove_range(c, &key, &to_key); if (err) goto out_ro; finish_reservation(c); kfree(trun); return 0; out_ro: ubifs_ro_mode(c, err); finish_reservation(c); out_free: kfree(trun); return err; }
/** * ubifs_jrn_rename - rename a directory entry. * @c: UBIFS file-system description object * @old_dir: parent inode of directory entry to rename * @old_dentry: directory entry to rename * @new_dir: parent inode of directory entry to rename * @new_dentry: new directory entry (or directory entry to replace) * @sync: non-zero if the write-buffer has to be synchronized * * Returns zero in case of success and a negative error code in case of failure. */ int ubifs_jrn_rename(struct ubifs_info *c, const struct inode *old_dir, const struct dentry *old_dentry, const struct inode *new_dir, const struct dentry *new_dentry, int sync) { const struct inode *old_inode = old_dentry->d_inode; const struct inode *new_inode = new_dentry->d_inode; int err, dlen1, dlen2, ilen, lnum, offs, len; int aligned_dlen1, aligned_dlen2, plen = UBIFS_INO_NODE_SZ; int last_reference = !!(new_inode && new_inode->i_nlink == 0); struct ubifs_dent_node *dent, *dent2; void *p; union ubifs_key key; dbg_jrn("dent '%.*s' in dir ino %lu to dent '%.*s' in dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name, old_dir->i_ino, new_dentry->d_name.len, new_dentry->d_name.name, new_dir->i_ino); ubifs_assert(ubifs_inode(old_dir)->data_len == 0); ubifs_assert(ubifs_inode(new_dir)->data_len == 0); dlen1 = UBIFS_DENT_NODE_SZ + new_dentry->d_name.len + 1; dlen2 = UBIFS_DENT_NODE_SZ + old_dentry->d_name.len + 1; if (new_inode) { ilen = UBIFS_INO_NODE_SZ; if (!last_reference) ilen += ubifs_inode(new_inode)->data_len; } else ilen = 0; aligned_dlen1 = ALIGN(dlen1, 8); aligned_dlen2 = ALIGN(dlen2, 8); len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); if (old_dir != new_dir) len += plen; dent = kmalloc(len, GFP_NOFS); if (!dent) return -ENOMEM; /* Make new dent */ dent->ch.node_type = UBIFS_DENT_NODE; dent_key_init_flash(c, &dent->key, new_dir->i_ino, &new_dentry->d_name); dent->inum = cpu_to_le64(old_inode->i_ino); dent->type = get_dent_type(old_inode->i_mode); dent->nlen = cpu_to_le16(new_dentry->d_name.len); memcpy(dent->name, new_dentry->d_name.name, new_dentry->d_name.len); dent->name[new_dentry->d_name.len] = '\0'; zero_dent_node_unused(dent); ubifs_prep_grp_node(c, dent, dlen1, 0); dent2 = (void *)dent + aligned_dlen1; /* Make deletion dent */ dent2->ch.node_type = UBIFS_DENT_NODE; dent_key_init_flash(c, &dent2->key, old_dir->i_ino, &old_dentry->d_name); dent2->inum = cpu_to_le64(0); dent2->type = DT_UNKNOWN; dent2->nlen = cpu_to_le16(old_dentry->d_name.len); memcpy(dent2->name, old_dentry->d_name.name, old_dentry->d_name.len); dent2->name[old_dentry->d_name.len] = '\0'; zero_dent_node_unused(dent2); ubifs_prep_grp_node(c, dent2, dlen2, 0); p = (void *)dent2 + aligned_dlen2; if (new_inode) { pack_inode(c, p, new_inode, 0, last_reference); p += ALIGN(ilen, 8); } if (old_dir == new_dir) pack_inode(c, p, old_dir, 1, 0); else { pack_inode(c, p, old_dir, 0, 0); p += ALIGN(plen, 8); pack_inode(c, p, new_dir, 1, 0); } err = make_reservation(c, BASEHD, len); if (err) goto out_free; if (last_reference) { err = ubifs_add_orphan(c, new_inode->i_ino); if (err) { release_head(c, BASEHD); goto out_finish; } } err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync); if (!sync && !err) { struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; ubifs_wbuf_add_ino_nolock(wbuf, new_dir->i_ino); ubifs_wbuf_add_ino_nolock(wbuf, old_dir->i_ino); } release_head(c, BASEHD); if (err) goto out_ro; if (new_inode) ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, new_inode->i_ino); dent_key_init(c, &key, new_dir->i_ino, &new_dentry->d_name); err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, &new_dentry->d_name); if (err) goto out_ro; err = ubifs_add_dirt(c, lnum, dlen2); if (err) goto out_ro; dent_key_init(c, &key, old_dir->i_ino, &old_dentry->d_name); err = ubifs_tnc_remove_nm(c, &key, &old_dentry->d_name); if (err) goto out_ro; offs += aligned_dlen1 + aligned_dlen2; if (new_inode) { ino_key_init(c, &key, new_inode->i_ino); err = ubifs_tnc_add(c, &key, lnum, offs, ilen); if (err) goto out_ro; offs += ALIGN(ilen, 8); } ino_key_init(c, &key, old_dir->i_ino); err = ubifs_tnc_add(c, &key, lnum, offs, plen); if (err) goto out_ro; if (old_dir != new_dir) { offs += ALIGN(plen, 8); ino_key_init(c, &key, new_dir->i_ino); err = ubifs_tnc_add(c, &key, lnum, offs, plen); if (err) goto out_ro; } finish_reservation(c); kfree(dent); return 0; out_ro: ubifs_ro_mode(c, err); if (last_reference) ubifs_delete_orphan(c, new_inode->i_ino); out_finish: finish_reservation(c); out_free: kfree(dent); return err; }
int write_cmd(byte *buf,int len) { write_head(len); return write_exact(buf,len); }
/** * ubifs_jrn_update - update inode. * @c: UBIFS file-system description object * @dir: parent inode or host inode in case of extended attributes * @nm: directory entry name * @inode: inode * @deletion: indicates a directory entry deletion i.e unlink or rmdir * @sync: non-zero if the write-buffer has to be synchronized * @xent: non-zero if the directory entry is an extended attribute entry * * This function updates an inode by writing a directory entry (or extended * attribute entry), the inode itself, and the parent directory inode (or the * host inode) to the journal. * * The function writes the host inode @dir last, which is important in case of * extended attributes. Indeed, then we guarantee that if the host inode gets * synchronized, and the write-buffer it sits in gets flushed, the extended * attribute inode gets flushed too. And this is exactly what the user expects - * synchronizing the host inode synchronizes its extended attributes. * Similarly, this guarantees that if @dir is synchronized, its directory entry * corresponding to @nm gets synchronized too. * * This function returns %0 on success and a negative error code on failure. */ int ubifs_jrn_update(struct ubifs_info *c, const struct inode *dir, const struct qstr *nm, const struct inode *inode, int deletion, int sync, int xent) { int err, dlen, ilen, len, lnum, ino_offs, dent_offs; int aligned_dlen, aligned_ilen; int last_reference = !!(deletion && inode->i_nlink == 0); struct ubifs_dent_node *dent; struct ubifs_ino_node *ino; union ubifs_key dent_key, ino_key; dbg_jrn("ino %lu, dent '%.*s', data len %d in dir ino %lu", inode->i_ino, nm->len, nm->name, ubifs_inode(inode)->data_len, dir->i_ino); ubifs_assert(ubifs_inode(dir)->data_len == 0); dlen = UBIFS_DENT_NODE_SZ + nm->len + 1; ilen = UBIFS_INO_NODE_SZ; /* * If the last reference to the inode is being deleted, then there is no * need to attach and write inode data, it is being deleted anyway. */ if (!last_reference) ilen += ubifs_inode(inode)->data_len; aligned_dlen = ALIGN(dlen, 8); aligned_ilen = ALIGN(ilen, 8); len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; dent = kmalloc(len, GFP_NOFS); if (!dent) return -ENOMEM; if (!xent) { dent->ch.node_type = UBIFS_DENT_NODE; dent_key_init(c, &dent_key, dir->i_ino, nm); } else { dent->ch.node_type = UBIFS_XENT_NODE; xent_key_init(c, &dent_key, dir->i_ino, nm); } key_write(c, &dent_key, dent->key); dent->inum = deletion ? 0 : cpu_to_le64(inode->i_ino); dent->type = get_dent_type(inode->i_mode); dent->nlen = cpu_to_le16(nm->len); memcpy(dent->name, nm->name, nm->len); dent->name[nm->len] = '\0'; zero_dent_node_unused(dent); ubifs_prep_grp_node(c, dent, dlen, 0); ino = (void *)dent + aligned_dlen; pack_inode(c, ino, inode, 0, last_reference); ino = (void *)ino + aligned_ilen; pack_inode(c, ino, dir, 1, 0); err = make_reservation(c, BASEHD, len); if (err) goto out_free; if (last_reference) { err = ubifs_add_orphan(c, inode->i_ino); if (err) { release_head(c, BASEHD); goto out_finish; } } err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync); if (!sync && !err) { struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; ubifs_wbuf_add_ino_nolock(wbuf, inode->i_ino); ubifs_wbuf_add_ino_nolock(wbuf, dir->i_ino); } release_head(c, BASEHD); kfree(dent); if (err) goto out_ro; if (deletion) { err = ubifs_tnc_remove_nm(c, &dent_key, nm); if (err) goto out_ro; err = ubifs_add_dirt(c, lnum, dlen); } else err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, nm); if (err) goto out_ro; /* * Note, we do not remove the inode from TNC even if the last reference * to it has just been deleted, because the inode may still be opened. * Instead, the inode has been added to orphan lists and the orphan * subsystem will take further care about it. */ ino_key_init(c, &ino_key, inode->i_ino); ino_offs = dent_offs + aligned_dlen; err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen); if (err) goto out_ro; ino_key_init(c, &ino_key, dir->i_ino); ino_offs += aligned_ilen; err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, UBIFS_INO_NODE_SZ); if (err) goto out_ro; finish_reservation(c); return 0; out_finish: finish_reservation(c); out_free: kfree(dent); return err; out_ro: ubifs_ro_mode(c, err); if (last_reference) ubifs_delete_orphan(c, inode->i_ino); finish_reservation(c); return err; }
int ubifs_jrn_delete_xattr(struct ubifs_info *c, const struct inode *host, const struct inode *inode, const struct qstr *nm, int sync) { int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen; struct ubifs_dent_node *xent; struct ubifs_ino_node *ino; union ubifs_key xent_key, key1, key2; dbg_jrn("host %lu, xattr ino %lu, name '%s', data len %d", host->i_ino, inode->i_ino, nm->name, ubifs_inode(inode)->data_len); ubifs_assert(inode->i_nlink == 0); /* * Since we are deleting the inode, we do not bother to attach any data * to it and assume its length is %UBIFS_INO_NODE_SZ. */ xlen = UBIFS_DENT_NODE_SZ + nm->len + 1; aligned_xlen = ALIGN(xlen, 8); hlen = ubifs_inode(host)->data_len + UBIFS_INO_NODE_SZ; len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); xent = kmalloc(len, GFP_NOFS); if (!xent) return -ENOMEM; xent->ch.node_type = UBIFS_XENT_NODE; xent_key_init(c, &xent_key, host->i_ino, nm); key_write(c, &xent_key, xent->key); xent->inum = 0; xent->type = get_dent_type(inode->i_mode); xent->nlen = cpu_to_le16(nm->len); memcpy(xent->name, nm->name, nm->len); xent->name[nm->len] = '\0'; zero_dent_node_unused(xent); ubifs_prep_grp_node(c, xent, xlen, 0); ino = (void *)xent + aligned_xlen; pack_inode(c, ino, inode, 0, 1); ino = (void *)ino + UBIFS_INO_NODE_SZ; pack_inode(c, ino, host, 1, 0); err = make_reservation(c, BASEHD, len); if (err) { kfree(xent); return err; } err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); if (!sync && !err) ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino); release_head(c, BASEHD); kfree(xent); if (err) goto out_ro; /* Remove the extended attribute entry from TNC */ err = ubifs_tnc_remove_nm(c, &xent_key, nm); if (err) goto out_ro; err = ubifs_add_dirt(c, lnum, xlen); if (err) goto out_ro; /* * Remove all nodes belonging to the extended attribute inode from TNC. * Well, there actually must be only one node - the inode itself. */ lowest_ino_key(c, &key1, inode->i_ino); highest_ino_key(c, &key2, inode->i_ino); err = ubifs_tnc_remove_range(c, &key1, &key2); if (err) goto out_ro; err = ubifs_add_dirt(c, lnum, UBIFS_INO_NODE_SZ); if (err) goto out_ro; /* And update TNC with the new host inode position */ ino_key_init(c, &key1, host->i_ino); err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen); if (err) goto out_ro; finish_reservation(c); return 0; out_ro: ubifs_ro_mode(c, err); finish_reservation(c); return err; }
int req_open(int sockfd, struct message_s *msg) { write_head(sockfd, TYPE_OPEN_REP, 1, 0); return 0; }