diff options
Diffstat (limited to 'util-linux/mount.c')
-rw-r--r-- | util-linux/mount.c | 90 |
1 files changed, 37 insertions, 53 deletions
diff --git a/util-linux/mount.c b/util-linux/mount.c index 5e85f9986..0f213bb30 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -332,7 +332,7 @@ static void append_mount_options(char **oldopts, const char *newopts) | |||
332 | } | 332 | } |
333 | 333 | ||
334 | // Use the mount_options list to parse options into flags. | 334 | // Use the mount_options list to parse options into flags. |
335 | // Also return list of unrecognized options if unrecognized != NULL | 335 | // Also update list of unrecognized options if unrecognized != NULL |
336 | static long parse_mount_options(char *options, char **unrecognized) | 336 | static long parse_mount_options(char *options, char **unrecognized) |
337 | { | 337 | { |
338 | long flags = MS_SILENT; | 338 | long flags = MS_SILENT; |
@@ -348,25 +348,35 @@ static long parse_mount_options(char *options, char **unrecognized) | |||
348 | // FIXME: use hasmntopt() | 348 | // FIXME: use hasmntopt() |
349 | // Find this option in mount_options | 349 | // Find this option in mount_options |
350 | for (i = 0; i < ARRAY_SIZE(mount_options); i++) { | 350 | for (i = 0; i < ARRAY_SIZE(mount_options); i++) { |
351 | if (!strcasecmp(option_str, options)) { | 351 | if (strcasecmp(option_str, options) == 0) { |
352 | long fl = mount_options[i]; | 352 | long fl = mount_options[i]; |
353 | if (fl < 0) flags &= fl; | 353 | if (fl < 0) |
354 | else flags |= fl; | 354 | flags &= fl; |
355 | break; | 355 | else |
356 | flags |= fl; | ||
357 | goto found; | ||
356 | } | 358 | } |
357 | option_str += strlen(option_str) + 1; | 359 | option_str += strlen(option_str) + 1; |
358 | } | 360 | } |
359 | // If unrecognized not NULL, append unrecognized mount options | 361 | // We did not recognize this option. |
360 | if (unrecognized && i == ARRAY_SIZE(mount_options)) { | 362 | // If "unrecognized" is not NULL, append option there. |
363 | // Note that we should not append *empty* option - | ||
364 | // in this case we want to pass NULL, not "", to "data" | ||
365 | // parameter of mount(2) syscall. | ||
366 | // This is crucial for filesystems that don't accept | ||
367 | // any arbitrary mount options, like cgroup fs: | ||
368 | // "mount -t cgroup none /mnt" | ||
369 | if (options[0] && unrecognized) { | ||
361 | // Add it to strflags, to pass on to kernel | 370 | // Add it to strflags, to pass on to kernel |
362 | i = *unrecognized ? strlen(*unrecognized) : 0; | 371 | char *p = *unrecognized; |
363 | *unrecognized = xrealloc(*unrecognized, i + strlen(options) + 2); | 372 | unsigned len = p ? strlen(p) : 0; |
373 | *unrecognized = p = xrealloc(p, len + strlen(options) + 2); | ||
364 | 374 | ||
365 | // Comma separated if it's not the first one | 375 | // Comma separated if it's not the first one |
366 | if (i) (*unrecognized)[i++] = ','; | 376 | if (len) p[len++] = ','; |
367 | strcpy((*unrecognized)+i, options); | 377 | strcpy(p + len, options); |
368 | } | 378 | } |
369 | 379 | found: | |
370 | if (!comma) | 380 | if (!comma) |
371 | break; | 381 | break; |
372 | // Advance to next option | 382 | // Advance to next option |
@@ -775,78 +785,52 @@ static char *nfs_strerror(int status) | |||
775 | 785 | ||
776 | static bool_t xdr_fhandle(XDR *xdrs, fhandle objp) | 786 | static bool_t xdr_fhandle(XDR *xdrs, fhandle objp) |
777 | { | 787 | { |
778 | if (!xdr_opaque(xdrs, objp, FHSIZE)) | 788 | return xdr_opaque(xdrs, objp, FHSIZE); |
779 | return FALSE; | ||
780 | return TRUE; | ||
781 | } | 789 | } |
782 | 790 | ||
783 | static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp) | 791 | static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp) |
784 | { | 792 | { |
785 | if (!xdr_u_int(xdrs, &objp->fhs_status)) | 793 | if (!xdr_u_int(xdrs, &objp->fhs_status)) |
786 | return FALSE; | 794 | return FALSE; |
787 | switch (objp->fhs_status) { | 795 | if (objp->fhs_status == 0) |
788 | case 0: | 796 | return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle); |
789 | if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) | ||
790 | return FALSE; | ||
791 | break; | ||
792 | default: | ||
793 | break; | ||
794 | } | ||
795 | return TRUE; | 797 | return TRUE; |
796 | } | 798 | } |
797 | 799 | ||
798 | static bool_t xdr_dirpath(XDR *xdrs, dirpath *objp) | 800 | static bool_t xdr_dirpath(XDR *xdrs, dirpath *objp) |
799 | { | 801 | { |
800 | if (!xdr_string(xdrs, objp, MNTPATHLEN)) | 802 | return xdr_string(xdrs, objp, MNTPATHLEN); |
801 | return FALSE; | ||
802 | return TRUE; | ||
803 | } | 803 | } |
804 | 804 | ||
805 | static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp) | 805 | static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp) |
806 | { | 806 | { |
807 | if (!xdr_bytes(xdrs, (char **)&objp->fhandle3_val, | 807 | return xdr_bytes(xdrs, (char **)&objp->fhandle3_val, |
808 | (unsigned int *) &objp->fhandle3_len, | 808 | (unsigned int *) &objp->fhandle3_len, |
809 | FHSIZE3) | 809 | FHSIZE3); |
810 | ) { | ||
811 | return FALSE; | ||
812 | } | ||
813 | return TRUE; | ||
814 | } | 810 | } |
815 | 811 | ||
816 | static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) | 812 | static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) |
817 | { | 813 | { |
818 | if (!xdr_fhandle3(xdrs, &objp->fhandle)) | 814 | if (!xdr_fhandle3(xdrs, &objp->fhandle)) |
819 | return FALSE; | 815 | return FALSE; |
820 | if (!xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val), | 816 | return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val), |
821 | &(objp->auth_flavours.auth_flavours_len), | 817 | &(objp->auth_flavours.auth_flavours_len), |
822 | ~0, | 818 | ~0, |
823 | sizeof(int), | 819 | sizeof(int), |
824 | (xdrproc_t) xdr_int) | 820 | (xdrproc_t) xdr_int); |
825 | ) { | ||
826 | return FALSE; | ||
827 | } | ||
828 | return TRUE; | ||
829 | } | 821 | } |
830 | 822 | ||
831 | static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp) | 823 | static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp) |
832 | { | 824 | { |
833 | if (!xdr_enum(xdrs, (enum_t *) objp)) | 825 | return xdr_enum(xdrs, (enum_t *) objp); |
834 | return FALSE; | ||
835 | return TRUE; | ||
836 | } | 826 | } |
837 | 827 | ||
838 | static bool_t xdr_mountres3(XDR *xdrs, mountres3 *objp) | 828 | static bool_t xdr_mountres3(XDR *xdrs, mountres3 *objp) |
839 | { | 829 | { |
840 | if (!xdr_mountstat3(xdrs, &objp->fhs_status)) | 830 | if (!xdr_mountstat3(xdrs, &objp->fhs_status)) |
841 | return FALSE; | 831 | return FALSE; |
842 | switch (objp->fhs_status) { | 832 | if (objp->fhs_status == MNT_OK) |
843 | case MNT_OK: | 833 | return xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo); |
844 | if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo)) | ||
845 | return FALSE; | ||
846 | break; | ||
847 | default: | ||
848 | break; | ||
849 | } | ||
850 | return TRUE; | 834 | return TRUE; |
851 | } | 835 | } |
852 | 836 | ||