Some improvements to the solaris xattr routines.
[rsync/rsync.git] / io.c
diff --git a/io.c b/io.c
index ed556b1..6a89c8f 100644 (file)
--- a/io.c
+++ b/io.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2001 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2008 Wayne Davison
+ * Copyright (C) 2003-2009 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -124,16 +124,7 @@ static void writefd(int fd, const char *buf, size_t len);
 static void writefd_unbuffered(int fd, const char *buf, size_t len);
 static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len, int convert);
 
-struct flist_ndx_item {
-       struct flist_ndx_item *next;
-       int ndx;
-};
-
-struct flist_ndx_list {
-       struct flist_ndx_item *head, *tail;
-};
-
-static struct flist_ndx_list redo_list, hlink_list;
+static flist_ndx_list redo_list, hlink_list;
 
 struct msg_list_item {
        struct msg_list_item *next;
@@ -147,39 +138,6 @@ struct msg_list {
 
 static struct msg_list msg_queue;
 
-static void flist_ndx_push(struct flist_ndx_list *lp, int ndx)
-{
-       struct flist_ndx_item *item;
-
-       if (!(item = new(struct flist_ndx_item)))
-               out_of_memory("flist_ndx_push");
-       item->next = NULL;
-       item->ndx = ndx;
-       if (lp->tail)
-               lp->tail->next = item;
-       else
-               lp->head = item;
-       lp->tail = item;
-}
-
-static int flist_ndx_pop(struct flist_ndx_list *lp)
-{
-       struct flist_ndx_item *next;
-       int ndx;
-
-       if (!lp->head)
-               return -1;
-
-       ndx = lp->head->ndx;
-       next = lp->head->next;
-       free(lp->head);
-       lp->head = next;
-       if (!next)
-               lp->tail = NULL;
-
-       return ndx;
-}
-
 static void got_flist_entry_status(enum festatus status, const char *buf)
 {
        int ndx = IVAL(buf, 0);
@@ -206,6 +164,11 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
                }
                break;
        case FES_REDO:
+               if (read_batch) {
+                       if (inc_recurse)
+                               flist->in_progress++;
+                       break;
+               }
                if (inc_recurse)
                        flist->to_redo++;
                flist_ndx_push(&redo_list, ndx);
@@ -484,9 +447,14 @@ static void read_msg_fd(void)
  * this, sender-side deletions were mostly happening at the end. */
 void increment_active_files(int ndx, int itemizing, enum logcode code)
 {
-       /* TODO: tune these limits? */
-       while (active_filecnt >= (active_bytecnt >= 128*1024 ? 10 : 50)) {
+       while (1) {
+               /* TODO: tune these limits? */
+               int limit = active_bytecnt >= 128*1024 ? 10 : 50;
+               if (active_filecnt < limit)
+                       break;
                check_for_finished_files(itemizing, code, 0);
+               if (active_filecnt < limit)
+                       break;
                if (iobuf_out_cnt)
                        io_flush(NORMAL_FLUSH);
                else
@@ -1081,6 +1049,13 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
                        send_msg_int(MSG_IO_ERROR, IVAL(line, 0));
                        io_error |= IVAL(line, 0);
                        break;
+               case MSG_DEL_STATS:
+                       if (msg_bytes)
+                               goto invalid_msg;
+                       read_del_stats(fd);
+                       if (am_sender && am_server)
+                               write_del_stats(sock_f_out);
+                       break;
                case MSG_DELETED:
                        if (msg_bytes >= sizeof line)
                                goto overflow;
@@ -1448,6 +1423,22 @@ static void sleep_for_bwlimit(int bytes_written)
        total_written = (sleep_usec - elapsed_usec) * bwlimit / (ONE_SEC/1024);
 }
 
+static const char *what_fd_is(int fd)
+{
+       static char buf[20];
+
+       if (fd == sock_f_out)
+               return "socket";
+       else if (fd == msg_fd_out)
+               return "message fd";
+       else if (fd == batch_fd)
+               return "batch file";
+       else {
+               snprintf(buf, sizeof buf, "fd %d", fd);
+               return buf;
+       }
+}
+
 /* Write len bytes to the file descriptor fd, looping as necessary to get
  * the job done and also (in certain circumstances) reading any data on
  * msg_fd_in to avoid deadlock.
@@ -1526,8 +1517,8 @@ static void writefd_unbuffered(int fd, const char *buf, size_t len)
                        if (am_server && fd == msg_fd_out)
                                exit_cleanup(RERR_STREAMIO);
                        rsyserr(FERROR, errno,
-                               "writefd_unbuffered failed to write %ld bytes [%s]",
-                               (long)len, who_am_i());
+                               "writefd_unbuffered failed to write %ld bytes to %s [%s]",
+                               (long)len, what_fd_is(fd), who_am_i());
                        /* If the other side is sending us error messages, try
                         * to grab any messages they sent before they died. */
                        while (!am_server && fd == sock_f_out && io_multiplexing_in) {
@@ -1585,10 +1576,8 @@ static void writefd(int fd, const char *buf, size_t len)
        if (fd == sock_f_out)
                stats.total_written += len;
 
-       if (fd == write_batch_monitor_out) {
-               if ((size_t)write(batch_fd, buf, len) != len)
-                       exit_cleanup(RERR_FILEIO);
-       }
+       if (fd == write_batch_monitor_out)
+               writefd_unbuffered(batch_fd, buf, len);
 
        if (!iobuf_out || fd != iobuf_f_out) {
                writefd_unbuffered(fd, buf, len);