Changeset 14147


Ignore:
Timestamp:
Jul 27, 2013, 4:18:12 PM (8 years ago)
Author:
jordan
Message:

(trunk, libt) #4147 'bad file descriptor': in cached_file_open(), ensure the file is always opened with writable permissions if we need to call ftruncate() to resize it. Large credit to karamanolev for tracking this down with strace.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/fdlimit.c

    r13905 r14147  
    336336  int flags;
    337337  struct stat sb;
    338   bool alreadyExisted;
     338  bool already_existed;
     339  bool resize_needed;
    339340
    340341  /* create subfolders, if any */
     
    352353    }
    353354
    354   alreadyExisted = !stat (filename, &sb) && S_ISREG (sb.st_mode);
    355 
    356   if (writable && !alreadyExisted && (allocation == TR_PREALLOCATE_FULL))
     355  already_existed = !stat (filename, &sb) && S_ISREG (sb.st_mode);
     356
     357  if (writable && !already_existed && (allocation == TR_PREALLOCATE_FULL))
    357358    if (preallocate_file_full (filename, file_size))
    358359      tr_logAddDebug ("Preallocated file \"%s\"", filename);
     360
     361  /* we can't resize the file w/o write permissions */
     362  resize_needed = already_existed && (file_size < (uint64_t)sb.st_size);
     363  writable |= resize_needed;
    359364
    360365  /* open the file */
     
    376381   * https://bugs.launchpad.net/ubuntu/+source/transmission/+bug/318249
    377382   */
    378   if (alreadyExisted && (file_size < (uint64_t)sb.st_size))
    379     {
    380       if (ftruncate (o->fd, file_size) == -1)
    381         {
    382           const int err = errno;
    383           tr_logAddError (_("Couldn't truncate \"%1$s\": %2$s"), filename, tr_strerror (err));
    384           return err;
    385         }
    386     }
    387 
    388   if (writable && !alreadyExisted && (allocation == TR_PREALLOCATE_SPARSE))
     383  if (resize_needed && (ftruncate (o->fd, file_size) == -1))
     384    {
     385      const int err = errno;
     386      tr_logAddError (_("Couldn't truncate \"%1$s\": %2$s"), filename, tr_strerror (err));
     387      return err;
     388    }
     389
     390  if (writable && !already_existed && (allocation == TR_PREALLOCATE_SPARSE))
    389391    preallocate_file_sparse (o->fd, file_size);
    390392
Note: See TracChangeset for help on using the changeset viewer.