Error check messages sent to the kernel.
authorNeil Brown <neilb@suse.de>
Thu, 11 Jan 2007 01:45:48 +0000 (12:45 +1100)
committerNeil Brown <neilb@suse.de>
Thu, 11 Jan 2007 01:45:48 +0000 (12:45 +1100)
And make sure that if we fail to export a filesystem in mountd,
then we don't try to get a filehandle on it, or a deadlock
might occur.

support/include/nfslib.h
support/nfs/cacheio.c
support/nfs/nfsexport.c
utils/gssd/cacheio.c
utils/gssd/cacheio.h
utils/gssd/svcgssd_proc.c
utils/mountd/cache.c
utils/mountd/mountd.c

index 3e25761..aba37c2 100644 (file)
@@ -132,7 +132,7 @@ struct nfs_fh_len * getfh_size(struct sockaddr *addr, const char *, int size);
 void qword_print(FILE *f, char *str);
 void qword_printhex(FILE *f, char *str, int slen);
 void qword_printint(FILE *f, int num);
-void qword_eol(FILE *f);
+int qword_eol(FILE *f);
 int readline(int fd, char **buf, int *lenp);
 int qword_get(char **bpp, char *dest, int bufsize);
 int qword_get_int(char **bpp, int *anint);
index 3e868d8..36473cf 100644 (file)
@@ -109,10 +109,10 @@ void qword_printint(FILE *f, int num)
        fprintf(f, "%d ", num);
 }
 
-void qword_eol(FILE *f)
+int qword_eol(FILE *f)
 {
        fprintf(f,"\n");
-       fflush(f);
+       return fflush(f);
 }
 
 
index aa0e49b..f129fd2 100644 (file)
@@ -38,6 +38,7 @@ exp_unexp(struct nfsctl_export *exp, int export)
        char fsidstr[8];
        __u16 dev;
        __u32 inode;
+       int err;
 
 
        f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
@@ -53,7 +54,7 @@ exp_unexp(struct nfsctl_export *exp, int export)
        } else
                qword_printint(f, 1);
 
-       qword_eol(f);
+       err = qword_eol(f);
        fclose(f);
 
        if (stat(exp->ex_path, &stb) != 0)
@@ -71,7 +72,7 @@ exp_unexp(struct nfsctl_export *exp, int export)
                } else
                        qword_printint(f, 1);
 
-               qword_eol(f);
+               err = qword_eol(f) || err;
        }
        qword_print(f,exp->ex_client);
        qword_printint(f,0);
@@ -85,9 +86,9 @@ exp_unexp(struct nfsctl_export *exp, int export)
                qword_print(f, exp->ex_path);
        } else
                qword_printint(f, 1);
-       qword_eol(f);
+       err = qword_eol(f) || err;
        fclose(f);
-       return 0;
+       return err;
 }
 
 int
index 75c7a5d..f2f2960 100644 (file)
@@ -173,11 +173,13 @@ void qword_printint(FILE *f, int num)
        printerr(2, "%d ", num);
 }
 
-void qword_eol(FILE *f)
+int qword_eol(FILE *f)
 {
+       int err;
        fprintf(f,"\n");
-       fflush(f);
+       err = fflush(f);
        printerr(2, "\n");
+       return err;
 }
 
 
index cc97b36..dfff258 100644 (file)
@@ -40,7 +40,7 @@ void qword_addeol(char **bpp, int *lp);
 void qword_print(FILE *f, char *str);
 void qword_printhex(FILE *f, char *str, int slen);
 void qword_printint(FILE *f, int num);
-void qword_eol(FILE *f);
+int qword_eol(FILE *f);
 int readline(int fd, char **buf, int *lenp);
 int qword_get(char **bpp, char *dest, int bufsize);
 int qword_get_int(char **bpp, int *anint);
index 7981399..4037159 100644 (file)
@@ -72,6 +72,7 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
        FILE *f;
        int i;
        char *fname = NULL;
+       int err;
 
        printerr(1, "doing downcall\n");
        if ((fname = mech2file(mech)) == NULL)
@@ -93,9 +94,9 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
                qword_printint(f, cred->cr_groups[i]);
        qword_print(f, fname);
        qword_printhex(f, context_token->value, context_token->length);
-       qword_eol(f);
+       err = qword_eol(f);
        fclose(f);
-       return 0;
+       return err;
 out_err:
        printerr(0, "WARNING: downcall failed\n");
        return -1;
index 726b98f..dcb5dac 100644 (file)
@@ -35,7 +35,7 @@
  * Record is terminated with newline.
  *
  */
-void cache_export_ent(char *domain, struct exportent *exp);
+int cache_export_ent(char *domain, struct exportent *exp);
 
 
 char *lbuf  = NULL;
@@ -352,12 +352,12 @@ int cache_process_req(fd_set *readfds)
  * % echo $domain $path $[now+30*60] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel
  */
 
-void cache_export_ent(char *domain, struct exportent *exp)
+int cache_export_ent(char *domain, struct exportent *exp)
 {
-
+       int err;
        FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
        if (!f)
-               return;
+               return -1;
 
        qword_print(f, domain);
        qword_print(f, exp->e_path);
@@ -366,28 +366,32 @@ void cache_export_ent(char *domain, struct exportent *exp)
        qword_printint(f, exp->e_anonuid);
        qword_printint(f, exp->e_anongid);
        qword_printint(f, exp->e_fsid);
-       qword_eol(f);
+       err = qword_eol(f);
 
        fclose(f);
+       return err;
 }
 
-void cache_export(nfs_export *exp)
+int cache_export(nfs_export *exp)
 {
+       int err;
        FILE *f;
 
        f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w");
        if (!f)
-               return;
+               return -1;
 
        qword_print(f, "nfsd");
        qword_print(f, inet_ntoa(exp->m_client->m_addrlist[0]));
        qword_printint(f, time(0)+30*60);
        qword_print(f, exp->m_client->m_hostname);
-       qword_eol(f);
+       err = qword_eol(f);
        
        fclose(f);
 
-       cache_export_ent(exp->m_client->m_hostname, &exp->m_export);
+       err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export)
+               || err;
+       return err;
 }
 
 /* Get a filehandle.
@@ -413,9 +417,10 @@ cache_get_filehandle(nfs_export *exp, int len, char *p)
        qword_print(f, exp->m_client->m_hostname);
        qword_print(f, p);
        qword_printint(f, len); 
-       qword_eol(f);
+       failed = qword_eol(f);
        
-       failed = (fgets(buf, sizeof(buf), f) == NULL);
+       if (!failed)
+               failed = (fgets(buf, sizeof(buf), f) == NULL);
        fclose(f);
        if (failed)
                return NULL;
index 08f294d..72332ce 100644 (file)
@@ -29,7 +29,7 @@
 
 extern void    cache_open(void);
 extern struct nfs_fh_len *cache_get_filehandle(nfs_export *exp, int len, char *p);
-extern void cache_export(nfs_export *exp);
+extern int cache_export(nfs_export *exp);
 
 extern void my_svc_run(void);
 
@@ -416,7 +416,10 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, mountstat3 *error, int v3)
                 */
                struct nfs_fh_len  *fh;
 
-               cache_export(exp);
+               if (cache_export(exp)) {
+                       *error = NFSERR_ACCES;
+                       return NULL;
+               }
                fh = cache_get_filehandle(exp, v3?64:32, p);
                if (fh == NULL) 
                        *error = NFSERR_ACCES;