vfs_mount.c (c79126f2e4b31976a54d1c30961d8c7b0f740a3c) | vfs_mount.c (31260bf042555bba6523d127ed80172bb97c1839) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1999-2004 Poul-Henning Kamp 5 * Copyright (c) 1999 Michael Smith 6 * Copyright (c) 1989, 1993 7 * The Regents of the University of California. All rights reserved. 8 * (c) UNIX System Laboratories, Inc. --- 67 unchanged lines hidden (view full) --- 76static int vfs_domount(struct thread *td, const char *fstype, char *fspath, 77 uint64_t fsflags, struct vfsoptlist **optlist); 78static void free_mntarg(struct mntarg *ma); 79 80static int usermount = 0; 81SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, 82 "Unprivileged users may mount and unmount file systems"); 83 | 1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1999-2004 Poul-Henning Kamp 5 * Copyright (c) 1999 Michael Smith 6 * Copyright (c) 1989, 1993 7 * The Regents of the University of California. All rights reserved. 8 * (c) UNIX System Laboratories, Inc. --- 67 unchanged lines hidden (view full) --- 76static int vfs_domount(struct thread *td, const char *fstype, char *fspath, 77 uint64_t fsflags, struct vfsoptlist **optlist); 78static void free_mntarg(struct mntarg *ma); 79 80static int usermount = 0; 81SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, 82 "Unprivileged users may mount and unmount file systems"); 83 |
84static bool default_autoro = false; 85SYSCTL_BOOL(_vfs, OID_AUTO, default_autoro, CTLFLAG_RW, &default_autoro, 0, 86 "Retry failed r/w mount as r/o if no explicit ro/rw option is specified"); 87 |
|
84MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); 85MALLOC_DEFINE(M_STATFS, "statfs", "statfs structure"); 86static uma_zone_t mount_zone; 87 88/* List of mounted filesystems. */ 89struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist); 90 91/* For any iteration/modification of mountlist */ --- 449 unchanged lines hidden (view full) --- 541 mac_mount_destroy(mp); 542#endif 543 if (mp->mnt_opt != NULL) 544 vfs_freeopts(mp->mnt_opt); 545 crfree(mp->mnt_cred); 546 uma_zfree(mount_zone, mp); 547} 548 | 88MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); 89MALLOC_DEFINE(M_STATFS, "statfs", "statfs structure"); 90static uma_zone_t mount_zone; 91 92/* List of mounted filesystems. */ 93struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist); 94 95/* For any iteration/modification of mountlist */ --- 449 unchanged lines hidden (view full) --- 545 mac_mount_destroy(mp); 546#endif 547 if (mp->mnt_opt != NULL) 548 vfs_freeopts(mp->mnt_opt); 549 crfree(mp->mnt_cred); 550 uma_zfree(mount_zone, mp); 551} 552 |
553static bool 554vfs_should_downgrade_to_ro_mount(uint64_t fsflags, int error) 555{ 556 /* This is an upgrade of an exisiting mount. */ 557 if ((fsflags & MNT_UPDATE) != 0) 558 return (false); 559 /* This is already an R/O mount. */ 560 if ((fsflags & MNT_RDONLY) != 0) 561 return (false); 562 563 switch (error) { 564 case ENODEV: /* generic, geom, ... */ 565 case EACCES: /* cam/scsi, ... */ 566 case EROFS: /* md, mmcsd, ... */ 567 /* 568 * These errors can be returned by the storage layer to signal 569 * that the media is read-only. No harm in the R/O mount 570 * attempt if the error was returned for some other reason. 571 */ 572 return (true); 573 default: 574 return (false); 575 } 576} 577 |
|
549int 550vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) 551{ 552 struct vfsoptlist *optlist; 553 struct vfsopt *opt, *tmp_opt; 554 char *fstype, *fspath, *errmsg; 555 int error, fstypelen, fspathlen, errmsg_len, errmsg_pos; | 578int 579vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) 580{ 581 struct vfsoptlist *optlist; 582 struct vfsopt *opt, *tmp_opt; 583 char *fstype, *fspath, *errmsg; 584 int error, fstypelen, fspathlen, errmsg_len, errmsg_pos; |
585 bool autoro; |
|
556 557 errmsg = fspath = NULL; 558 errmsg_len = fspathlen = 0; 559 errmsg_pos = -1; | 586 587 errmsg = fspath = NULL; 588 errmsg_len = fspathlen = 0; 589 errmsg_pos = -1; |
590 autoro = default_autoro; |
|
560 561 error = vfs_buildopts(fsoptions, &optlist); 562 if (error) 563 return (error); 564 565 if (vfs_getopt(optlist, "errmsg", (void **)&errmsg, &errmsg_len) == 0) 566 errmsg_pos = vfs_getopt_pos(optlist, "errmsg"); 567 --- 75 unchanged lines hidden (view full) --- 643 opt->name = strdup("nonosuid", M_MOUNT); 644 } 645 else if (strcmp(opt->name, "nosymfollow") == 0) 646 fsflags |= MNT_NOSYMFOLLOW; 647 else if (strcmp(opt->name, "symfollow") == 0) { 648 free(opt->name, M_MOUNT); 649 opt->name = strdup("nonosymfollow", M_MOUNT); 650 } | 591 592 error = vfs_buildopts(fsoptions, &optlist); 593 if (error) 594 return (error); 595 596 if (vfs_getopt(optlist, "errmsg", (void **)&errmsg, &errmsg_len) == 0) 597 errmsg_pos = vfs_getopt_pos(optlist, "errmsg"); 598 --- 75 unchanged lines hidden (view full) --- 674 opt->name = strdup("nonosuid", M_MOUNT); 675 } 676 else if (strcmp(opt->name, "nosymfollow") == 0) 677 fsflags |= MNT_NOSYMFOLLOW; 678 else if (strcmp(opt->name, "symfollow") == 0) { 679 free(opt->name, M_MOUNT); 680 opt->name = strdup("nonosymfollow", M_MOUNT); 681 } |
651 else if (strcmp(opt->name, "noro") == 0) | 682 else if (strcmp(opt->name, "noro") == 0) { |
652 fsflags &= ~MNT_RDONLY; | 683 fsflags &= ~MNT_RDONLY; |
653 else if (strcmp(opt->name, "rw") == 0) | 684 autoro = false; 685 } 686 else if (strcmp(opt->name, "rw") == 0) { |
654 fsflags &= ~MNT_RDONLY; | 687 fsflags &= ~MNT_RDONLY; |
655 else if (strcmp(opt->name, "ro") == 0) | 688 autoro = false; 689 } 690 else if (strcmp(opt->name, "ro") == 0) { |
656 fsflags |= MNT_RDONLY; | 691 fsflags |= MNT_RDONLY; |
692 autoro = false; 693 } |
|
657 else if (strcmp(opt->name, "rdonly") == 0) { 658 free(opt->name, M_MOUNT); 659 opt->name = strdup("ro", M_MOUNT); 660 fsflags |= MNT_RDONLY; | 694 else if (strcmp(opt->name, "rdonly") == 0) { 695 free(opt->name, M_MOUNT); 696 opt->name = strdup("ro", M_MOUNT); 697 fsflags |= MNT_RDONLY; |
698 autoro = false; |
|
661 } | 699 } |
700 else if (strcmp(opt->name, "autoro") == 0) { 701 vfs_freeopt(optlist, opt); 702 autoro = true; 703 } |
|
662 else if (strcmp(opt->name, "suiddir") == 0) 663 fsflags |= MNT_SUIDDIR; 664 else if (strcmp(opt->name, "sync") == 0) 665 fsflags |= MNT_SYNCHRONOUS; 666 else if (strcmp(opt->name, "union") == 0) 667 fsflags |= MNT_UNION; 668 else if (strcmp(opt->name, "automounted") == 0) { 669 fsflags |= MNT_AUTOMOUNTED; --- 7 unchanged lines hidden (view full) --- 677 * terminating NUL. 678 */ 679 if (fstypelen > MFSNAMELEN || fspathlen > MNAMELEN) { 680 error = ENAMETOOLONG; 681 goto bail; 682 } 683 684 error = vfs_domount(td, fstype, fspath, fsflags, &optlist); | 704 else if (strcmp(opt->name, "suiddir") == 0) 705 fsflags |= MNT_SUIDDIR; 706 else if (strcmp(opt->name, "sync") == 0) 707 fsflags |= MNT_SYNCHRONOUS; 708 else if (strcmp(opt->name, "union") == 0) 709 fsflags |= MNT_UNION; 710 else if (strcmp(opt->name, "automounted") == 0) { 711 fsflags |= MNT_AUTOMOUNTED; --- 7 unchanged lines hidden (view full) --- 719 * terminating NUL. 720 */ 721 if (fstypelen > MFSNAMELEN || fspathlen > MNAMELEN) { 722 error = ENAMETOOLONG; 723 goto bail; 724 } 725 726 error = vfs_domount(td, fstype, fspath, fsflags, &optlist); |
727 728 /* 729 * See if we can mount in the read-only mode if the error code suggests 730 * that it could be possible and the mount options allow for that. 731 * Never try it if "[no]{ro|rw}" has been explicitly requested and not 732 * overridden by "autoro". 733 */ 734 if (autoro && vfs_should_downgrade_to_ro_mount(fsflags, error)) { 735 printf("%s: R/W mount failed, possibly R/O media," 736 " trying R/O mount\n", __func__); 737 fsflags |= MNT_RDONLY; 738 error = vfs_domount(td, fstype, fspath, fsflags, &optlist); 739 } |
|
685bail: 686 /* copyout the errmsg */ 687 if (errmsg_pos != -1 && ((2 * errmsg_pos + 1) < fsoptions->uio_iovcnt) 688 && errmsg_len > 0 && errmsg != NULL) { 689 if (fsoptions->uio_segflg == UIO_SYSSPACE) { 690 bcopy(errmsg, 691 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base, 692 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len); --- 1296 unchanged lines hidden --- | 740bail: 741 /* copyout the errmsg */ 742 if (errmsg_pos != -1 && ((2 * errmsg_pos + 1) < fsoptions->uio_iovcnt) 743 && errmsg_len > 0 && errmsg != NULL) { 744 if (fsoptions->uio_segflg == UIO_SYSSPACE) { 745 bcopy(errmsg, 746 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_base, 747 fsoptions->uio_iov[2 * errmsg_pos + 1].iov_len); --- 1296 unchanged lines hidden --- |