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

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