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