+/*
+ * Do bookkeeping when a new file is created on a Volume. This is
+ * also done for disk files to generate the jobmedia records for
+ * quick seeking.
+ */
+static bool do_new_file_bookkeeping(DCR *dcr)
+{
+ DEVICE *dev = dcr->dev;
+ JCR *jcr = dcr->jcr;
+
+ /* Create a JobMedia record so restore can seek */
+ if (!dir_create_jobmedia_record(dcr)) {
+ Dmsg0(190, "Error from create_job_media.\n");
+ dev->dev_errno = EIO;
+ Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
+ dcr->VolCatInfo.VolCatName, jcr->Job);
+ terminate_writing_volume(dcr);
+ dev->dev_errno = EIO;
+ return false;
+ }
+ dev->VolCatInfo.VolCatFiles = dev->file;
+ if (!dir_update_volume_info(dcr, false)) {
+ Dmsg0(190, "Error from update_vol_info.\n");
+ terminate_writing_volume(dcr);
+ dev->dev_errno = EIO;
+ return false;
+ }
+ Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
+
+ /*
+ * Walk through all attached dcrs setting flag to call
+ * set_new_file_parameters() when that dcr is next used.
+ */
+ DCR *mdcr;
+ foreach_dlist(mdcr, dev->attached_dcrs) {
+ if (mdcr->jcr->JobId == 0) {
+ continue;
+ }
+ mdcr->NewFile = true; /* set reminder to do set_new_file_params */
+ }
+ /* Set new file/block parameters for current dcr */
+ set_new_file_parameters(dcr);
+ return true;
+}
+
+/*
+ * Do all checks for DVD sizes during writing.
+ */
+static bool do_dvd_size_checks(DCR *dcr)
+{
+ DEVICE *dev = dcr->dev;
+ JCR *jcr = dcr->jcr;
+ DEV_BLOCK *block = dcr->block;
+
+ /* Don't go further if the device is not a dvd */
+ if (!dev->is_dvd()) {
+ return true;
+ }
+
+ /* Limit maximum part size to value specified by user
+ */
+ if (dev->max_part_size > 0 && ((dev->part_size + block->binbuf) >= dev->max_part_size)) {
+ if (dev->part < dev->num_dvd_parts) {
+ Jmsg3(dcr->jcr, M_FATAL, 0, _("Error while writing, current part number"
+ " is less than the total number of parts (%d/%d, device=%s)\n"),
+ dev->part, dev->num_dvd_parts, dev->print_name());
+ dev->dev_errno = EIO;
+ return false;
+ }
+
+ if (dvd_open_next_part(dcr) < 0) {
+ Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
+ dev->print_name(), dev->bstrerror());
+ dev->dev_errno = EIO;
+ return false;
+ }
+
+ dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
+
+ if (!dir_update_volume_info(dcr, false)) {
+ Dmsg0(190, "Error from update_vol_info.\n");
+ dev->dev_errno = EIO;
+ return false;
+ }
+ }
+
+ if (!dev->is_freespace_ok()) {
+ update_free_space_dev(dev);
+ }
+
+ if (!dev->is_freespace_ok()) { /* Error while getting free space */
+ char ed1[50], ed2[50];
+ Dmsg1(10, "Cannot get free space on the device ERR=%s.\n", dev->errmsg);
+ Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s "
+ "(part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"),
+ dev->VolCatInfo.VolCatName,
+ dev->file, dev->block_num, dev->print_name(),
+ edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
+ dev->free_space_errno, dev->errmsg);
+ dev->dev_errno = dev->free_space_errno;
+ return false;
+ }
+
+ if ((dev->is_freespace_ok() && (dev->part_size + block->binbuf) >= dev->free_space)) {
+ char ed1[50], ed2[50];
+ Dmsg0(10, "==== Just enough free space on the device to write the current part...\n");
+ Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s "
+ "(part_size=%s, free_space=%s, free_space_errno=%d).\n"),
+ dev->VolCatInfo.VolCatName,
+ dev->file, dev->block_num, dev->print_name(),
+ edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
+ dev->free_space_errno);
+ terminate_writing_volume(dcr);
+ dev->dev_errno = ENOSPC;
+ return false;
+ }
+ return true;
+}
+