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;
}
Exemple #2
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
  }
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #9
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;
}
Exemple #10
0
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;
}
Exemple #11
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
}
Exemple #12
0
/**
 * 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;
}
Exemple #13
0
static void
recover_from_log(void)
{
  read_head();      
  cprintf("recovery: n=%d\n", log.lh.n);
  install_trans();
  log.lh.n = 0;
  write_head();
}
Exemple #14
0
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;
}
Exemple #15
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();
}
Exemple #16
0
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;
}
Exemple #17
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;
}
Exemple #18
0
/**
 * 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;
}
Exemple #19
0
int write_cmd(byte *buf,int len)
{
    write_head(len);
    return write_exact(buf,len);
}
Exemple #20
0
/**
 * 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;
}
Exemple #21
0
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;
}