Whamcloud - gitweb
LU-6389 utils: fix lustre_rsync read retry 75/18275/2
authorAndreas Dilger <andreas.dilger@intel.com>
Wed, 3 Feb 2016 02:48:35 +0000 (19:48 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 20 Feb 2016 05:40:10 +0000 (05:40 +0000)
The read() syscall could return less than the amount of data
requested.  Retry the read call until all data is read or an
error is returned.

Even though Lustre will retry the short read internally, the
code may as well be written correctly.

Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Change-Id: I712969c4f920b53fa6dc27ddcb968cb82df88a44
Reviewed-on: http://review.whamcloud.com/18275
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/utils/lustre_rsync.c

index 404ae58..e0f7599 100644 (file)
@@ -391,31 +391,39 @@ int lr_copy_data(struct lr_info *info)
                 info->bufsize = bufsize;
         }
 
-        while (1) {
-                rsize = read(fd_src, info->buf, bufsize);
-                if (rsize == 0) {
-                        break;
-                } else if (rsize < 0) {
-                        rc = -errno;
-                        goto out;
-                }
-                errno = 0;
-                if (write(fd_dest, info->buf, rsize) != rsize) {
-                        if (errno != 0)
-                                rc = -errno;
-                        else
-                                rc = -EINTR;
-                }
-        }
-        fsync(fd_dest);
+       while (1) {
+               char *buf;
+               int wsize;
+
+               buf = info->buf;
+               rsize = read(fd_src, buf, bufsize);
+               if (rsize == 0) {
+                       rc = 0;
+                       break;
+               }
+               if (rsize < 0) {
+                       rc = -errno;
+                       break;
+               }
+               do {
+                       wsize = write(fd_dest, buf, rsize);
+                       if (wsize <= 0) {
+                               rc = -errno;
+                               break;
+                       }
+                       rsize -= wsize;
+                       buf += wsize;
+               } while (rsize > 0);
+       }
+       fsync(fd_dest);
 
 out:
-        if (fd_src != -1)
-                close(fd_src);
-        if (fd_dest != -1)
-                close(fd_dest);
+       if (fd_src != -1)
+               close(fd_src);
+       if (fd_dest != -1)
+               close(fd_dest);
 
-        return rc;
+       return rc;
 }
 
 /* Copy data from source to destination */