]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/stropts.c
Imported upstream 1.2.8
[nfs-utils.git] / utils / mount / stropts.c
index 314a806799bbe83ed8e805b94059726f152bb898..1dc38ef27ba50a83e8f221e1d18fb0fcfb3ae3bf 100644 (file)
@@ -540,6 +540,10 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options)
                        errno = EOPNOTSUPP;
                else if (rpc_createerr.cf_stat == RPC_AUTHERROR)
                        errno = EACCES;
+               else if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
+                       errno = ETIMEDOUT;
+               else if (rpc_createerr.cf_stat == RPC_PROGVERSMISMATCH)
+                       errno = EPROTONOSUPPORT;
                else if (rpc_createerr.cf_error.re_errno != 0)
                        errno = rpc_createerr.cf_error.re_errno;
                return 0;
@@ -663,11 +667,14 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi)
                case ECONNREFUSED:
                case EOPNOTSUPP:
                case EHOSTUNREACH:
+               case ETIMEDOUT:
+               case EACCES:
                        continue;
                default:
-                       break;
+                       goto out;
                }
        }
+out:
        return ret;
 }
 
@@ -676,6 +683,7 @@ static int nfs_do_mount_v4(struct nfsmount_info *mi,
 {
        struct mount_options *options = po_dup(mi->options);
        int result = 0;
+       char *extra_opts = NULL;
 
        if (!options) {
                errno = ENOMEM;
@@ -711,20 +719,26 @@ static int nfs_do_mount_v4(struct nfsmount_info *mi,
                goto out_fail;
        }
 
-       /*
-        * Update option string to be recorded in /etc/mtab.
-        */
-       if (po_join(options, mi->extra_opts) == PO_FAILED) {
+       if (po_join(options, &extra_opts) == PO_FAILED) {
                errno = ENOMEM;
                goto out_fail;
        }
 
        if (verbose)
                printf(_("%s: trying text-based options '%s'\n"),
-                       progname, *mi->extra_opts);
+                       progname, extra_opts);
 
        result = nfs_sys_mount(mi, options);
 
+       /*
+        * If success, update option string to be recorded in /etc/mtab.
+        */
+       if (result) {
+           free(*mi->extra_opts);
+           *mi->extra_opts = extra_opts;
+       } else
+           free(extra_opts);
+
 out_fail:
        po_destroy(options);
        return result;
@@ -749,11 +763,14 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi)
                switch (errno) {
                case ECONNREFUSED:
                case EHOSTUNREACH:
+               case ETIMEDOUT:
+               case EACCES:
                        continue;
                default:
-                       break;
+                       goto out;
                }
        }
+out:
        return ret;
 }
 
@@ -907,7 +924,8 @@ static int nfsmount_parent(struct nfsmount_info *mi)
        if (nfs_try_mount(mi))
                return EX_SUCCESS;
 
-       if (nfs_is_permanent_error(errno)) {
+       /* retry background mounts when the server is not up */
+       if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP) {
                mount_error(mi->spec, mi->node, errno);
                return EX_FAIL;
        }
@@ -942,7 +960,8 @@ static int nfsmount_child(struct nfsmount_info *mi)
                if (nfs_try_mount(mi))
                        return EX_SUCCESS;
 
-               if (nfs_is_permanent_error(errno))
+               /* retry background mounts when the server is not up */
+               if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP)
                        break;
 
                if (time(NULL) > timeout)