OpenAFS Master Repository branch, openafs-stable-1_8_x, updated. openafs-stable-1_8_5-56-g08f4388

Gerrit Code Review gerrit@openafs.org
Sun, 9 Feb 2020 18:16:43 -0500


The following commit has been merged in the openafs-stable-1_8_x branch:
commit 08f4388e207af62f7c7ea68c10bd4e4ab5a9e049
Author: Andrew Deason <adeason@dson.org>
Date:   Sun Nov 17 20:58:15 2019 -0600

    afs: Ensure CDirty is set during afs_write loop
    
    Currently, in afs_write(), we set CDirty on the given vcache, and then
    write the given data into various dcaches. When writing to a dcache,
    we call afs_DoPartialWrite, which may cause us to flush the dirty data
    to the fileserver and clear the CDirty bit.
    
    If we were given more than 1 chunk of data to write, we will then go
    through another iteration of the loop, writing more dirty data into
    dcaches, but CDirty will not be set. This can cause issues with, for
    example, afs_SimpleVStat() or afs_ProcessFS(), which use CDirty to
    determine whether or not to merge in FetchStatus info from the
    fileserver into our local cache. This can cause our local cache to
    incorrectly reflect the state of the file on the fileserver, instead
    of the state of the locally-modified file in our cache.
    
    A more detailed example is as follows. Consider a small C program that
    copies a file, fchmod()ing the destination before closing it:
    
        void
        do_copy(char *src_name, char *dest_name)
        {
            /* error checking elided */
            src_fd = open(src_name, O_RDONLY);
            dest_fd = open(dest_name, O_WRONLY|O_CREAT|O_TRUNC, 0755);
            fstat(src_fd, &st);
            src_buf = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, src_fd, 0);
            write(dest_fd, src_buf, st.st_size);
            munmap(src_buf, st.st_size);
            close(src_fd);
            fchmod(dest_fd, 0100644);
            close(dest_fd);
        }
    
    Currently, on FBSD, using this to copy a 7862648-byte file, using a
    smallish cache (10000 blocks) will cause the destination to appear to
    be truncated, because avc->f.m.Length will be incorrect, even though
    all of the relevant data was written to the fileserver.
    
    On most other platforms such as SOLARIS and LINUX, this is not a
    problem, since currently they only write one page of data at a time to
    afs_write(), and so they never hit multiple iterations of the while()
    loop inside afs_write().
    
    To fix this, just set CDirty on every iteration of the while() loop in
    afs_write(). In general, we need to set CDirty after calling
    afs_DoPartialStore() anywhere if the caller continues to write more
    data. But all callers already do this, except for this one instance in
    afs_write().
    
    Thanks to tcreech@tcreech.com for helping find occurrences of the
    relevant issue.
    
    FIXES 135041
    
    Reviewed-on: https://gerrit.openafs.org/13948
    Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
    Tested-by: BuildBot <buildbot@rampaginggeek.com>
    (cherry picked from commit 9d0854547522f7b2fb1bb7aa876fe9f901674747)
    
    Change-Id: Ie86313e9b9750bc6724bb6e18b7df8e010810023
    Reviewed-on: https://gerrit.openafs.org/13951
    Reviewed-by: Andrew Deason <adeason@sinenomine.net>
    Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
    Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
    Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
    Reviewed-by: Marcio Brito Barbosa <mbarbosa@sinenomine.net>
    Tested-by: BuildBot <buildbot@rampaginggeek.com>
    Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>

 src/afs/VNOPS/afs_vnop_write.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

-- 
OpenAFS Master Repository