aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux/mount.c')
-rw-r--r--util-linux/mount.c90
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
336static long parse_mount_options(char *options, char **unrecognized) 336static 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
776static bool_t xdr_fhandle(XDR *xdrs, fhandle objp) 786static 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
783static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp) 791static 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
798static bool_t xdr_dirpath(XDR *xdrs, dirpath *objp) 800static 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
805static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp) 805static 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
816static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) 812static 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
831static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp) 823static 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
838static bool_t xdr_mountres3(XDR *xdrs, mountres3 *objp) 828static 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