Blame SOURCES/0032-Propagate-errors-from-nfs-with-quota-to-client.patch

f22e83
From aa9cb48373018502ef99a57aad70b69c0c75ff65 Mon Sep 17 00:00:00 2001
f22e83
From: Martin Sehnoutka <msehnout@redhat.com>
f22e83
Date: Thu, 17 Nov 2016 13:29:59 +0100
f22e83
Subject: [PATCH 32/59] Propagate errors from nfs with quota to client.
f22e83
f22e83
vsftpd now checks for errors when closing newly uploaded file and
f22e83
forward errors to the client (e.g. when file system quota was
f22e83
exceeded)
f22e83
---
f22e83
 ftpcodes.h  |  1 +
f22e83
 postlogin.c | 32 ++++++++++++++++++++++++++++++--
f22e83
 sysutil.c   | 21 +++++++++++++++++++++
f22e83
 sysutil.h   |  1 +
f22e83
 4 files changed, 53 insertions(+), 2 deletions(-)
f22e83
f22e83
diff --git a/ftpcodes.h b/ftpcodes.h
f22e83
index 54dfae7..97801f3 100644
f22e83
--- a/ftpcodes.h
f22e83
+++ b/ftpcodes.h
f22e83
@@ -74,6 +74,7 @@
f22e83
 #define FTP_NOHANDLEPROT      536
f22e83
 #define FTP_FILEFAIL          550
f22e83
 #define FTP_NOPERM            550
f22e83
+#define FTP_DISKQUOTA         552
f22e83
 #define FTP_UPLOADFAIL        553
f22e83
 
f22e83
 #endif /* VSF_FTPCODES_H */
f22e83
diff --git a/postlogin.c b/postlogin.c
f22e83
index e473c34..8363c9c 100644
f22e83
--- a/postlogin.c
f22e83
+++ b/postlogin.c
f22e83
@@ -28,6 +28,8 @@
f22e83
 #include "vsftpver.h"
f22e83
 #include "opts.h"
f22e83
 
f22e83
+#include <errno.h>
f22e83
+
f22e83
 /* Private local functions */
f22e83
 static void handle_pwd(struct vsf_session* p_sess);
f22e83
 static void handle_cwd(struct vsf_session* p_sess);
f22e83
@@ -1035,8 +1037,10 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique)
f22e83
   struct vsf_transfer_ret trans_ret;
f22e83
   int new_file_fd;
f22e83
   int remote_fd;
f22e83
+  int close_errno;
f22e83
   int success = 0;
f22e83
   int created = 0;
f22e83
+  int closed = 0;
f22e83
   int do_truncate = 0;
f22e83
   filesize_t offset = p_sess->restart_pos;
f22e83
   p_sess->restart_pos = 0;
f22e83
@@ -1149,6 +1153,18 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique)
f22e83
     trans_ret = vsf_ftpdataio_transfer_file(p_sess, remote_fd,
f22e83
                                             new_file_fd, 1, 0);
f22e83
   }
f22e83
+
f22e83
+  /* Need to check close operation here because some errors
f22e83
+   * like EIO, EDQUOT, ENOSPC can be detected only on close
f22e83
+   * when using NFS
f22e83
+   */
f22e83
+  close_errno = vsf_sysutil_close_errno(new_file_fd);
f22e83
+  closed = 1;
f22e83
+  if (close_errno != 0)
f22e83
+  {
f22e83
+    trans_ret.retval = -1;
f22e83
+  }
f22e83
+
f22e83
   if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && trans_ret.retval == 0)
f22e83
   {
f22e83
     trans_ret.retval = -2;
f22e83
@@ -1161,7 +1177,16 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique)
f22e83
   }
f22e83
   if (trans_ret.retval == -1)
f22e83
   {
f22e83
-    vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure writing to local file.");
f22e83
+    /* Disk quota exceeded */
f22e83
+    if (close_errno == EDQUOT)
f22e83
+    {
f22e83
+      vsf_cmdio_write(p_sess, FTP_DISKQUOTA, "Disk quota exceeded.");
f22e83
+    }
f22e83
+    /* any other local error */
f22e83
+    else
f22e83
+    {
f22e83
+      vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure writing to local file.");
f22e83
+    }
f22e83
   }
f22e83
   else if (trans_ret.retval == -2)
f22e83
   {
f22e83
@@ -1183,7 +1208,10 @@ port_pasv_cleanup_out:
f22e83
   {
f22e83
     str_unlink(p_filename);
f22e83
   }
f22e83
-  vsf_sysutil_close(new_file_fd);
f22e83
+  if (!closed)
f22e83
+  {
f22e83
+    vsf_sysutil_close(new_file_fd);
f22e83
+  }
f22e83
 }
f22e83
 
f22e83
 static void
f22e83
diff --git a/sysutil.c b/sysutil.c
f22e83
index 42bcdf8..1c0422e 100644
f22e83
--- a/sysutil.c
f22e83
+++ b/sysutil.c
f22e83
@@ -1268,6 +1268,27 @@ vsf_sysutil_close(int fd)
f22e83
   }
f22e83
 }
f22e83
 
f22e83
+int
f22e83
+vsf_sysutil_close_errno(int fd)
f22e83
+{
f22e83
+  while (1)
f22e83
+  {
f22e83
+    int retval = close(fd);
f22e83
+    if (retval != 0)
f22e83
+    {
f22e83
+      if (errno == EINTR)
f22e83
+      {
f22e83
+        vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0);
f22e83
+        continue;
f22e83
+      }
f22e83
+      else {
f22e83
+        return errno;
f22e83
+      }
f22e83
+    }
f22e83
+    return 0;
f22e83
+  }
f22e83
+}
f22e83
+
f22e83
 int
f22e83
 vsf_sysutil_close_failok(int fd)
f22e83
 {
f22e83
diff --git a/sysutil.h b/sysutil.h
f22e83
index 2886bbc..be727f5 100644
f22e83
--- a/sysutil.h
f22e83
+++ b/sysutil.h
f22e83
@@ -92,6 +92,7 @@ int vsf_sysutil_create_or_open_file_append(const char* p_filename,
f22e83
 int vsf_sysutil_create_or_open_file(const char* p_filename, unsigned int mode);
f22e83
 void vsf_sysutil_dupfd2(int old_fd, int new_fd);
f22e83
 void vsf_sysutil_close(int fd);
f22e83
+int vsf_sysutil_close_errno(int fd);
f22e83
 int vsf_sysutil_close_failok(int fd);
f22e83
 int vsf_sysutil_unlink(const char* p_dead);
f22e83
 int vsf_sysutil_write_access(const char* p_filename);
f22e83
-- 
f22e83
2.14.4
f22e83