Hi,

This is indeed a real problem for me; I discovered it via some new automated
tests of wimlib.  For extraction to an NTFS volume, I had code that assumed any
return value from ntfs_attr_pwrite() other than the count that was passed in
indicated an error.  In practice I was usually passing a count of 32768 which
happened to avoid the problem, but when dealing with highly compressed WIM
archives the count could, in fact, be much larger.

The solution for me is, of course, to keep calling ntfs_attr_pwrite() until all
bytes have been written or a real error has occurred.  However, I'm suggesting
that something should also be done on the libntfs-3g side to make it harder for
people to run into this problem, whether that is updating the documentation or
updating ntfs_attr_pwrite() itself to always try to write the full count.  I am
also concerned about whether all internal callers of ntfs_attr_pwrite() in
libntfs-3g itself handle short writes correctly.  There are quite a few callers
and it looks like most don't use retry loops; however, many callers probably
either write small amounts of data only or rarely operate on compressed
attributes, thereby avoiding short writes in practice.

What if the existing ntfs_attr_pwrite() was simply moved to an internal
function, and ntfs_attr_pwrite() was written as a retry loop around the internal
function?

Eric

On Sat, Oct 31, 2015 at 07:06:01PM +0100, Jean-Pierre André wrote:
> Hi Eric,
> 
> Eric Biggers wrote:
> >Hi,
> >
> >The return value of ntfs_attr_pwrite() is documented as follows:
> >
> >>On success, return the number of successfully written bytes. If this number
> >>is lower than @count this means that an error was encountered during the
> >>write so that the write is partial. 0 means nothing was written (also return
> >>0 when @count is 0).
> >
> >Hence, a short count implies that an error occurred.  However, I discovered 
> >that
> >a short count may, in fact, be returned when successfully writing to a
> >compressed attribute, since ntfs_attr_pwrite() truncates the count to a 
> >single
> >compression block only:
> >
> >>       if (compressed) {
> >>               fullcount = (pos | (na->compression_block_size - 1)) + 1 - 
> >> pos;
> >>               if (count > fullcount)
> >>                       count = fullcount;
> >>       }
> >
> >There are two possible ways to fix this:
> >
> >     1) Update ntfs_attr_pwrite() to always try to write the full count
> >     2) Update ntfs_attr_pwrite() documentation to clarify that short returns
> >        are allowed and applications should, generally, continue calling
> >        ntfs_attr_pwrite() until all bytes have been written
> >
> >It looks like the callers of ntfs_attr_pwrite() in the FUSE drivers do retry
> >short writes, but this doesn't appear to be the case for all internal 
> >callers in
> >libntfs-3g itself.  So I think that option (1) is preferred, if it is at all
> >possible.
> 
> Actually, the current state is intentional, and motivated
> by the complexity of allocating clusters for compressed
> attributes. The promise should indeed have been mitigated
> for compressed attributes (a subset of data attributes).
> 
> If this is a problem (did you find a specific case ?), a
> reasonable solution is to insert a new function for writing
> to data attributes, which will repeat the call until done.
> 
> Jean-Pierre
> 
> >
> >Eric
> 

------------------------------------------------------------------------------
_______________________________________________
ntfs-3g-devel mailing list
ntfs-3g-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ntfs-3g-devel

Reply via email to