fs getserverprefs needs a larger buffer
authorDerrick Brashear <shadow@dementia.org>
Tue, 25 May 2010 04:03:16 +0000 (00:03 -0400)
committerDerrick Brashear <shadow@dementia.org>
Tue, 25 May 2010 04:43:20 +0000 (21:43 -0700)
it's very easy for the size of server preferences to be too large for the
default buffer. cope.

Change-Id: I0535edf784eb9e9a309dc17e571719e204b9d29b
Reviewed-on: http://gerrit.openafs.org/2021
Reviewed-by: Russ Allbery <rra@stanford.edu>
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/venus/fs.c

index f79138e..e37a404 100644 (file)
@@ -3204,11 +3204,20 @@ GetPrefCmd(struct cmd_syndesc *as, void *arock)
            (AFS_PIOCTL_MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
        in->flags = vlservers;
 
-       code = pioctl(0, VIOC_GETSPREFS, &blob, 1);
-       if (code) {
-           perror("getserverprefs pioctl");
-           return 1;
-       }
+       do {
+           code = pioctl(0, VIOC_GETSPREFS, &blob, 1);
+           if (code) {
+               if ((errno != E2BIG) || (2 * blob.out_size > 0x7FFF)) {
+                   perror("getserverprefs pioctl");
+                   return 1;
+               }
+               blob.out_size *= 2;
+               if (blob.out == space)
+                   blob.out = malloc(blob.out_size);
+               else
+                   blob.out = realloc(blob.out, blob.out_size);
+           }
+       } while (code != 0);
 
        out = (struct sprefinfo *)blob.out;
 
@@ -3227,6 +3236,9 @@ GetPrefCmd(struct cmd_syndesc *as, void *arock)
        in->offset = out->next_offset;
     } while (out->next_offset > 0);
 
+    if (blob.out != space)
+       free(blob.out);
+
     return 0;
 }