Esempio n. 1
0
void append_data_to_file(int inum, u8 *data, size_t size)
{
    printf("append data file at num %i\n", inum);
    inode *in = inode_at_num(inum);
    printf("inode: num: %i, size: %i, blocks: %i, end addr: %i\n",
            in->num, in->size, in->blocks, in->end_block);

    block *cur_blk = block_from_num(in->end_block); 
    printf("block addr: %i\n", in->end_block);
    int pos = in->size % BLOCK_SIZE;
    int blocks = (pos + size) / BLOCK_SIZE;
    int numbytes = BLOCK_SIZE - pos;
    write_data_to_block(cur_blk, data, size, pos);
    in->size += numbytes;
    //printf("%i:",pos);

    for (int i = 0; i < blocks; i++) {
        alloc_blocks(in, 1);
        cur_blk = block_from_num(in->end_block);
        int pos = in->size % BLOCK_SIZE;
        int numbytes = BLOCK_SIZE - pos;
        write_data_to_block(cur_blk, data, numbytes, pos);
        in->size += numbytes;
    }
    write_block_to_disk(cur_blk);
    in->size += size;
    write_inode_to_disk(in);
    
    free(in); 
    free(cur_blk);
}
Esempio n. 2
0
/*
 * Write a Record to the block
 *
 *  Returns: false on failure (none or partially written)
 *           true  on success (all bytes written)
 *
 *  and remainder returned in packet.
 *
 *  We require enough room for the header, and we deal with
 *  two special cases. 1. Only part of the record may have
 *  been transferred the last time (when remainder is
 *  non-zero), and 2. The remaining bytes to write may not
 *  all fit into the block.
 */
bool write_record_to_block(DCR *dcr, DEV_RECORD *rec)
{
   ssize_t n;
   bool retval = false;
   char buf1[100], buf2[100];
   DEV_BLOCK *block = dcr->block;

   /*
    * After this point the record is in nrec not rec e.g. its either converted
    * or is just a pointer to the same as the rec pointer being passed in.
    */

   while (1) {
      ASSERT(block->binbuf == (uint32_t)(block->bufp - block->buf));
      ASSERT(block->buf_len >= block->binbuf);

      Dmsg9(890, "%s() state=%d (%s) FI=%s SessId=%d Strm=%s len=%d "
            "block_navail=%d remainder=%d\n",
            __func__, rec->state, record_state_to_ascii(rec->state),
            FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
            stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len,
            block_write_navail(block), rec->remainder);

      switch (rec->state) {
      case st_none:
         /*
          * Figure out what to do
          */
         rec->state = st_header;
         rec->remainder = rec->data_len;   /* length of data remaining to write */
         continue;                         /* goto st_header */

      case st_header:
         /*
          * Write header
          */
         n = write_header_to_block(block, rec, rec->Stream);
         if (n < 0) {
            /*
             * the header did not fit into the block, so flush the current
             * block and come back to st_header and try again on the next block.
             */
            goto bail_out;
         }

         if (block_write_navail(block) == 0) {
            /*
             * The header fit, but no bytes of data will fit,
             * so flush this block and start the next block with a
             * continuation header.
             */
            rec->state = st_header_cont;
            goto bail_out;
         }

         /*
          * The header fit, and at least one byte of data will fit,
          * so move to the st_data state and start filling the block
          * with data bytes
          */
         rec->state = st_data;
         continue;

      case st_header_cont:
         /*
          * Write continuation header
          */
         n = write_header_to_block(block, rec, -rec->Stream);
         if (n < 0) {
            /*
             * The continuation header wouldn't fit, which is impossible
             * unless something is broken
             */
            Emsg0(M_ABORT, 0, _("couldn't write continuation header\n"));
         }

         /*
          * After successfully writing a continuation header, we always start writing
          * data, even if none will fit into this block.
          */
         rec->state = st_data;

         if (block_write_navail(block) == 0) {
            /*
             * The header fit, but no bytes of data will fit,
             * so flush the block and start the next block with
             * data bytes
             */
            goto bail_out;       /* Partial transfer */
         }

         continue;

      case st_data:
         /*
          * Write normal data
          *
          * Part of it may have already been transferred, and we
          * may not have enough room to transfer the whole this time.
          */
         if (rec->remainder > 0) {
            n = write_data_to_block(block, rec);
            if (n < 0) {
               /*
                * error appending data to block should be impossible
                * unless something is broken
                */
               Emsg0(M_ABORT, 0, _("data write error\n"));
            }

            rec->remainder -= n;

            if (rec->remainder > 0) {
               /*
                * Could not fit all of the data bytes into this block, so
                * flush the current block, and start the next block with a
                * continuation header
                */
               rec->state = st_header_cont;
               goto bail_out;
            }
         }

         rec->remainder = 0;               /* did whole transfer */
         rec->state = st_none;
         retval = true;
         goto bail_out;

      default:
         Emsg1(M_ABORT, 0, _("Something went wrong. Unknown state %d.\n"), rec->state);
         rec->state = st_none;
         retval = true;
         goto bail_out;
      }
   }

bail_out:
   return retval;
}
Esempio n. 3
0
/*
 * Write a Record to the block
 *
 *  Returns: false on failure (none or partially written)
 *           true  on success (all bytes written)
 *
 *  and remainder returned in packet.
 *
 *  We require enough room for the header, and we deal with
 *  two special cases. 1. Only part of the record may have
 *  been transferred the last time (when remainder is
 *  non-zero), and 2. The remaining bytes to write may not
 *  all fit into the block.
 */
bool write_record_to_block(DCR *dcr, DEV_RECORD *rec)
{
   bool retval = false;
   char buf1[100], buf2[100];
   DEV_BLOCK *block = dcr->block;

   /*
    * After this point the record is in nrec not rec e.g. its either converted
    * or is just a pointer to the same as the rec pointer being passed in.
    */

   while (1) {
      ASSERT(block->binbuf == (uint32_t)(block->bufp - block->buf));
      ASSERT(block->buf_len >= block->binbuf);

      Dmsg6(890, "write_record_to_block() FI=%s SessId=%d Strm=%s len=%d\n"
            "rem=%d remainder=%d\n",
            FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
            stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len,
            rec->remlen, rec->remainder);

      switch (rec->state) {
      case st_none:
         /*
          * Figure out what to do
          */
         rec->state = st_header;
         continue;              /* go to next state */

      case st_header:
         /*
          * Write header
          *
          * If rec->remainder is non-zero, we have been called a
          * second (or subsequent) time to finish writing a record
          * that did not previously fit into the block.
          */
          if (!write_header_to_block(block, rec)) {
             goto bail_out;      /* write block then come back here */
          }
          rec->state = st_data;  /* after header, now write data */
          continue;

      /*
       * Write continuation header
       */
      case st_header_cont:
         write_continue_header_to_block(block, rec);
         rec->state = st_data;
         if (rec->remlen == 0) {
            goto bail_out;       /* Partial transfer */
         }
         continue;

      /*
       * Write normal data
       */
      case st_data:
         /*
          * Write data
          *
          * Part of it may have already been transferred, and we
          * may not have enough room to transfer the whole this time.
          */
         if (rec->remainder > 0) {
            if (!write_data_to_block(block, rec)) {
               rec->state = st_header_cont;
               goto bail_out;
            }
         }
         rec->remainder = 0;               /* did whole transfer */
         rec->state = st_none;
         retval = true;
         goto bail_out;

      default:
         Dmsg0(000, "Something went wrong. Default state.\n");
         rec->state = st_none;
         retval = true;
         goto bail_out;
      }
   }

bail_out:
   return retval;
}