]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - fs/nfsd/export.c
NFSD: Using type of uint32_t for ex_nflavors instead of int
[mirror_ubuntu-jammy-kernel.git] / fs / nfsd / export.c
index 8513c598fabfbb7cc83e32357d4ff0f6ba8e087d..7884051070069a4fd143ef356aa7147791cf304f 100644 (file)
 #include <linux/exportfs.h>
 #include <linux/sunrpc/svc_xprt.h>
 
-#include <net/ipv6.h>
-
 #include "nfsd.h"
 #include "nfsfh.h"
 #include "netns.h"
 
 #define NFSDDBG_FACILITY       NFSDDBG_EXPORT
 
-typedef struct auth_domain     svc_client;
-typedef struct svc_export      svc_export;
-
 /*
  * We have two caches.
  * One maps client+vfsmnt+dentry to export options - the export map
@@ -73,7 +68,7 @@ static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_
 
 static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
 {
-       /* client fsidtype fsid [path] */
+       /* client fsidtype fsid expiry [path] */
        char *buf;
        int len;
        struct auth_domain *dom = NULL;
@@ -295,13 +290,19 @@ svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
 
 static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
 {
+       struct nfsd4_fs_location *locations = fsloc->locations;
        int i;
 
+       if (!locations)
+               return;
+
        for (i = 0; i < fsloc->locations_count; i++) {
-               kfree(fsloc->locations[i].path);
-               kfree(fsloc->locations[i].hosts);
+               kfree(locations[i].path);
+               kfree(locations[i].hosts);
        }
-       kfree(fsloc->locations);
+
+       kfree(locations);
+       fsloc->locations = NULL;
 }
 
 static void svc_export_put(struct kref *ref)
@@ -437,13 +438,14 @@ out_free_all:
 
 static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
 {
-       int listsize, err;
        struct exp_flavor_info *f;
+       u32 listsize;
+       int err;
 
-       err = get_int(mesg, &listsize);
+       err = get_uint(mesg, &listsize);
        if (err)
                return err;
-       if (listsize < 0 || listsize > MAX_SECINFO_LIST)
+       if (listsize > MAX_SECINFO_LIST)
                return -EINVAL;
 
        for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
@@ -474,6 +476,23 @@ static inline int
 secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
 #endif
 
+static inline int
+uuid_parse(char **mesg, char *buf, unsigned char **puuid)
+{
+       int len;
+
+       /* expect a 16 byte uuid encoded as \xXXXX... */
+       len = qword_get(mesg, buf, PAGE_SIZE);
+       if (len != EX_UUID_LEN)
+               return -EINVAL;
+
+       *puuid = kmemdup(buf, EX_UUID_LEN, GFP_KERNEL);
+       if (*puuid == NULL)
+               return -ENOMEM;
+
+       return 0;
+}
+
 static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 {
        /* client path expiry [flags anonuid anongid fsid] */
@@ -552,18 +571,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
                while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) {
                        if (strcmp(buf, "fsloc") == 0)
                                err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
-                       else if (strcmp(buf, "uuid") == 0) {
-                               /* expect a 16 byte uuid encoded as \xXXXX... */
-                               len = qword_get(&mesg, buf, PAGE_SIZE);
-                               if (len != 16)
-                                       err  = -EINVAL;
-                               else {
-                                       exp.ex_uuid =
-                                               kmemdup(buf, 16, GFP_KERNEL);
-                                       if (exp.ex_uuid == NULL)
-                                               err = -ENOMEM;
-                               }
-                       } else if (strcmp(buf, "secinfo") == 0)
+                       else if (strcmp(buf, "uuid") == 0)
+                               err = uuid_parse(&mesg, buf, &exp.ex_uuid);
+                       else if (strcmp(buf, "secinfo") == 0)
                                err = secinfo_parse(&mesg, buf, &exp);
                        else
                                /* quietly ignore unknown words and anything
@@ -649,7 +659,7 @@ static int svc_export_show(struct seq_file *m,
                if (exp->ex_uuid) {
                        int i;
                        seq_puts(m, ",uuid=");
-                       for (i=0; i<16; i++) {
+                       for (i = 0; i < EX_UUID_LEN; i++) {
                                if ((i&3) == 0 && i)
                                        seq_putc(m, ':');
                                seq_printf(m, "%02x", exp->ex_uuid[i]);
@@ -771,7 +781,7 @@ svc_export_update(struct svc_export *new, struct svc_export *old)
 
 
 static struct svc_expkey *
-exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type,
+exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type,
             u32 *fsidv, struct cache_req *reqp)
 {
        struct svc_expkey key, *ek;
@@ -793,9 +803,9 @@ exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type,
        return ek;
 }
 
-
-static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp,
-                                  const struct path *path, struct cache_req *reqp)
+static struct svc_export *
+exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp,
+               const struct path *path, struct cache_req *reqp)
 {
        struct svc_export *exp, key;
        int err;
@@ -819,11 +829,11 @@ static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp,
 /*
  * Find the export entry for a given dentry.
  */
-static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
-                                    struct path *path)
+static struct svc_export *
+exp_parent(struct cache_detail *cd, struct auth_domain *clp, struct path *path)
 {
        struct dentry *saved = dget(path->dentry);
-       svc_export *exp = exp_get_by_name(cd, clp, path, NULL);
+       struct svc_export *exp = exp_get_by_name(cd, clp, path, NULL);
 
        while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
                struct dentry *parent = dget_parent(path->dentry);
@@ -844,7 +854,7 @@ static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
  * since its harder to fool a kernel module than a user space program.
  */
 int
-exp_rootfh(struct net *net, svc_client *clp, char *name,
+exp_rootfh(struct net *net, struct auth_domain *clp, char *name,
           struct knfsd_fh *f, int maxsize)
 {
        struct svc_export       *exp;