hi.
return value of close() (receiver.c) is ignored.
when running out of quota on NFS (for example),
this can happen (without the patch):
output file(s) is/are truncated to 0 bytes and rsync reports success.
with the fix, this happens:
close "/home/luser/.test.mp3.PwaG50": Disc quota exceeded
rsync error: error in file IO (code 11) at receiver.c(464)
...
...and additionally, test.mp3 is not zapped to 0 bytes.
to be REALLY sure, also fsync() should be used, but that's really
bad for performance if you are transferring _many_ files.
-f and --fsync options added to rsync for the paranoids.
--
-------------- next part --------------
--- rsync-2.6.1/receiver.c.bak 2004-03-23 18:50:40.000000000 +0200
+++ rsync-2.6.1/receiver.c 2004-04-27 19:11:46.000000000 +0300
@@ -45,6 +45,7 @@ extern int cleanup_got_literal;
extern int module_id;
extern int ignore_errors;
extern int orig_umask;
+extern int do_fsync;
static void delete_one(char *fn, int is_dir)
{
@@ -268,6 +269,12 @@ static int receive_data(int f_in,struct
exit_cleanup(RERR_FILEIO);
}
+ if (do_fsync && (fd != -1) && (fsync(fd) != 0)) {
+ rprintf(FERROR, "fsync failed on %s: %s\n",
+ full_fname(fname), strerror(errno));
+ exit_cleanup(RERR_FILEIO);
+ }
+
sum_end(file_sum1);
read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
@@ -458,7 +465,11 @@ int recv_files(int f_in,struct file_list
if (fd1 != -1) {
close(fd1);
}
- close(fd2);
+ if (close(fd2) != 0) {
+ rprintf(FERROR, "close failed on %s: %s\n",
+ full_fname(fnametmp), strerror(errno));
+ exit_cleanup(RERR_FILEIO);
+ }
if (verbose > 2)
rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
--- rsync-2.6.1/options.c.bak 2004-04-17 20:07:23.000000000 +0300
+++ rsync-2.6.1/options.c 2004-04-27 19:28:10.000000000 +0300
@@ -37,6 +37,7 @@ int make_backups = 0;
**/
int whole_file = -1;
+int do_fsync = 0;
int archive_mode = 0;
int copy_links = 0;
int preserve_links = 0;
@@ -230,6 +231,7 @@ void usage(enum logcode F)
rprintf(F," -b, --backup make backups (see --suffix &
--backup-dir)\n");
rprintf(F," --backup-dir make backups into this
directory\n");
rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o
--backup-dir)\n",BACKUP_SUFFIX);
+ rprintf(F," -f, --fsync fsync every written
file\n");
rprintf(F," -u, --update update only (don't overwrite
newer files)\n");
rprintf(F," -l, --links copy symlinks as
symlinks\n");
rprintf(F," -L, --copy-links copy the referent of all
symlinks\n");
@@ -332,6 +334,7 @@ static struct poptOption long_options[]
{"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0,
0 },
{"help", 'h', POPT_ARG_NONE, 0,
'h', 0, 0 },
{"backup", 'b', POPT_ARG_NONE,
&make_backups, 0, 0, 0 },
+ {"fsync", 'f', POPT_ARG_NONE, &do_fsync, 0,
0, 0 },
{"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0,
0, 0 },
{"sparse", 'S', POPT_ARG_NONE,
&sparse_files, 0, 0, 0 },
{"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude,
0, 0, 0 },
@@ -798,6 +801,8 @@ void server_options(char **args,int *arg
/* the -q option is intentionally left out */
if (make_backups)
argstr[x++] = 'b';
+ if (do_fsync)
+ argstr[x++] = 'f';
if (update_only)
argstr[x++] = 'u';
if (dry_run)
--- rsync-2.6.1/util.c.bak 2004-04-23 01:17:15.000000000 +0300
+++ rsync-2.6.1/util.c 2004-04-27 19:15:29.000000000 +0300
@@ -29,6 +29,7 @@
extern int verbose;
extern struct exclude_list_struct server_exclude_list;
+extern int do_fsync;
int sanitize_paths = 0;
@@ -281,8 +282,22 @@ int copy_file(char *source, char *dest,
}
}
- close(ifd);
- close(ofd);
+ if (close(ifd) != 0) {
+ rprintf(FINFO, "close failed on %s: %s\n",
+ source, strerror(errno));
+ }
+
+ if (do_fsync && (fsync(ofd) != 0)) {
+ rprintf(FERROR, "fsync failed on %s: %s\n",
+ dest, strerror(errno));
+ return -1;
+ }
+
+ if (close(ofd) != 0) {
+ rprintf(FERROR, "close failed on %s: %s\n",
+ dest, strerror(errno));
+ return -1;
+ }
if (len < 0) {
rprintf(FERROR,"read %s: %s\n",