| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: fss.c,v 1.81.4.1.4.1 2013/02/10 23:57:38 riz Exp $ */ | | 1 | /* $NetBSD: fss.c,v 1.81.4.1.4.2 2013/02/11 20:39:04 riz Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2003 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2003 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Juergen Hannken-Illjes. | | 8 | * by Juergen Hannken-Illjes. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -26,27 +26,27 @@ | | | @@ -26,27 +26,27 @@ |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * File system snapshot disk driver. | | 33 | * File system snapshot disk driver. |
34 | * | | 34 | * |
35 | * Block/character interface to the snapshot of a mounted file system. | | 35 | * Block/character interface to the snapshot of a mounted file system. |
36 | */ | | 36 | */ |
37 | | | 37 | |
38 | #include <sys/cdefs.h> | | 38 | #include <sys/cdefs.h> |
39 | __KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.81.4.1.4.1 2013/02/10 23:57:38 riz Exp $"); | | 39 | __KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.81.4.1.4.2 2013/02/11 20:39:04 riz Exp $"); |
40 | | | 40 | |
41 | #include <sys/param.h> | | 41 | #include <sys/param.h> |
42 | #include <sys/systm.h> | | 42 | #include <sys/systm.h> |
43 | #include <sys/namei.h> | | 43 | #include <sys/namei.h> |
44 | #include <sys/proc.h> | | 44 | #include <sys/proc.h> |
45 | #include <sys/errno.h> | | 45 | #include <sys/errno.h> |
46 | #include <sys/malloc.h> | | 46 | #include <sys/malloc.h> |
47 | #include <sys/buf.h> | | 47 | #include <sys/buf.h> |
48 | #include <sys/ioctl.h> | | 48 | #include <sys/ioctl.h> |
49 | #include <sys/disklabel.h> | | 49 | #include <sys/disklabel.h> |
50 | #include <sys/device.h> | | 50 | #include <sys/device.h> |
51 | #include <sys/disk.h> | | 51 | #include <sys/disk.h> |
52 | #include <sys/stat.h> | | 52 | #include <sys/stat.h> |
| @@ -610,27 +610,27 @@ fss_copy_on_write(void *v, struct buf *b | | | @@ -610,27 +610,27 @@ fss_copy_on_write(void *v, struct buf *b |
610 | /* | | 610 | /* |
611 | * Lookup and open needed files. | | 611 | * Lookup and open needed files. |
612 | * | | 612 | * |
613 | * For file system internal snapshot initializes sc_mntname, sc_mount, | | 613 | * For file system internal snapshot initializes sc_mntname, sc_mount, |
614 | * sc_bs_vp and sc_time. | | 614 | * sc_bs_vp and sc_time. |
615 | * | | 615 | * |
616 | * Otherwise returns dev and size of the underlying block device. | | 616 | * Otherwise returns dev and size of the underlying block device. |
617 | * Initializes sc_mntname, sc_mount, sc_bdev, sc_bs_vp and sc_mount | | 617 | * Initializes sc_mntname, sc_mount, sc_bdev, sc_bs_vp and sc_mount |
618 | */ | | 618 | */ |
619 | static int | | 619 | static int |
620 | fss_create_files(struct fss_softc *sc, struct fss_set *fss, | | 620 | fss_create_files(struct fss_softc *sc, struct fss_set *fss, |
621 | off_t *bsize, struct lwp *l) | | 621 | off_t *bsize, struct lwp *l) |
622 | { | | 622 | { |
623 | int error, bits, fsbsize; | | 623 | int i, error, bits, fsbsize; |
624 | uint64_t numsec; | | 624 | uint64_t numsec; |
625 | unsigned int secsize; | | 625 | unsigned int secsize; |
626 | struct timespec ts; | | 626 | struct timespec ts; |
627 | /* nd -> nd2 to reduce mistakes while updating only some namei calls */ | | 627 | /* nd -> nd2 to reduce mistakes while updating only some namei calls */ |
628 | struct pathbuf *pb2; | | 628 | struct pathbuf *pb2; |
629 | struct nameidata nd2; | | 629 | struct nameidata nd2; |
630 | struct vnode *vp; | | 630 | struct vnode *vp; |
631 | | | 631 | |
632 | /* | | 632 | /* |
633 | * Get the mounted file system. | | 633 | * Get the mounted file system. |
634 | */ | | 634 | */ |
635 | | | 635 | |
636 | error = namei_simple_user(fss->fss_mount, | | 636 | error = namei_simple_user(fss->fss_mount, |
| @@ -681,45 +681,51 @@ fss_create_files(struct fss_softc *sc, s | | | @@ -681,45 +681,51 @@ fss_create_files(struct fss_softc *sc, s |
681 | error = vn_lock(vp, LK_EXCLUSIVE); | | 681 | error = vn_lock(vp, LK_EXCLUSIVE); |
682 | if (error != 0) | | 682 | if (error != 0) |
683 | return error; | | 683 | return error; |
684 | error = VFS_SNAPSHOT(sc->sc_mount, sc->sc_bs_vp, &ts); | | 684 | error = VFS_SNAPSHOT(sc->sc_mount, sc->sc_bs_vp, &ts); |
685 | TIMESPEC_TO_TIMEVAL(&sc->sc_time, &ts); | | 685 | TIMESPEC_TO_TIMEVAL(&sc->sc_time, &ts); |
686 | | | 686 | |
687 | VOP_UNLOCK(sc->sc_bs_vp); | | 687 | VOP_UNLOCK(sc->sc_bs_vp); |
688 | | | 688 | |
689 | return error; | | 689 | return error; |
690 | } | | 690 | } |
691 | vrele(vp); | | 691 | vrele(vp); |
692 | | | 692 | |
693 | /* | | 693 | /* |
694 | * Get the block device it is mounted on. | | 694 | * Get the block device it is mounted on and its size. |
695 | */ | | 695 | */ |
696 | | | 696 | |
697 | error = namei_simple_kernel(sc->sc_mount->mnt_stat.f_mntfromname, | | 697 | mutex_enter(&device_lock); |
698 | NSM_FOLLOW_NOEMULROOT, &vp); | | 698 | for (i = 0; i < SPECHSZ; i++) { |
699 | if (error != 0) | | 699 | for (vp = specfs_hash[i]; vp; vp = vp->v_specnext) { |
700 | return error; | | 700 | if (vp->v_type == VBLK && |
701 | | | 701 | vp == vp->v_specnode->sn_dev->sd_bdevvp && |
702 | if (vp->v_type != VBLK) { | | 702 | vp->v_specmountpoint == sc->sc_mount) |
703 | vrele(vp); | | 703 | break; |
| | | 704 | } |
| | | 705 | if (vp != NULL) |
| | | 706 | break; |
| | | 707 | } |
| | | 708 | if (vp == NULL) { |
| | | 709 | mutex_exit(&device_lock); |
704 | return EINVAL; | | 710 | return EINVAL; |
705 | } | | 711 | } |
706 | | | 712 | mutex_enter(vp->v_interlock); |
| | | 713 | mutex_exit(&device_lock); |
| | | 714 | error = vget(vp, 0); |
| | | 715 | if (error) |
| | | 716 | return error; |
707 | sc->sc_bdev = vp->v_rdev; | | 717 | sc->sc_bdev = vp->v_rdev; |
708 | | | 718 | |
709 | /* | | | |
710 | * Get the block device size. | | | |
711 | */ | | | |
712 | | | | |
713 | error = getdisksize(vp, &numsec, &secsize); | | 719 | error = getdisksize(vp, &numsec, &secsize); |
714 | vrele(vp); | | 720 | vrele(vp); |
715 | if (error) | | 721 | if (error) |
716 | return error; | | 722 | return error; |
717 | | | 723 | |
718 | *bsize = (off_t)numsec*secsize; | | 724 | *bsize = (off_t)numsec*secsize; |
719 | | | 725 | |
720 | /* | | 726 | /* |
721 | * Get the backing store | | 727 | * Get the backing store |
722 | */ | | 728 | */ |
723 | | | 729 | |
724 | error = pathbuf_copyin(fss->fss_bstore, &pb2); | | 730 | error = pathbuf_copyin(fss->fss_bstore, &pb2); |
725 | if (error) { | | 731 | if (error) { |