2 * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/fs/udf/udf_vfsops.c,v 1.16 2003/11/05 06:56:08 scottl Exp $
30 /* Implement the VFS side of things */
33 * Ok, here's how it goes. The UDF specs are pretty clear on how each data
34 * structure is made up, but not very clear on how they relate to each other.
35 * Here is the skinny... This demostrates a filesystem with one file in the
36 * root directory. Subdirectories are treated just as normal files, but they
37 * have File Id Descriptors of their children as their file data. As for the
38 * Anchor Volume Descriptor Pointer, it can exist in two of the following three
39 * places: sector 256, sector n (the max sector of the disk), or sector
40 * n - 256. It's a pretty good bet that one will exist at sector 256 though.
41 * One caveat is unclosed CD media. For that, sector 256 cannot be written,
42 * so the Anchor Volume Descriptor Pointer can exist at sector 512 until the
47 * n: Anchor Volume Descriptor Pointer
50 * |-->Main Volume Descriptor Sequence
53 * | |-->Logical Volume Descriptor
55 * |-->Partition Descriptor |
58 * |-->Fileset Descriptor
61 * |-->Root Dir File Entry
74 #include <sys/types.h>
75 #include <sys/param.h>
76 #include <sys/systm.h>
80 #include <sys/fcntl.h>
81 #include <sys/module.h>
82 #include <sys/kernel.h>
83 #include <sys/malloc.h>
84 #include <sys/mount.h>
85 #include <sys/nlookup.h>
88 #include <sys/queue.h>
89 #include <sys/vnode.h>
93 #include <vfs/udf/ecma167-udf.h>
94 #include <vfs/udf/osta.h>
95 #include <vfs/udf/udf.h>
96 #include <vfs/udf/udf_mount.h>
98 extern struct vop_ops udf_vnode_vops
;
100 MALLOC_DEFINE(M_UDFNODE
, "UDF node", "UDF node structure");
101 MALLOC_DEFINE(M_UDFMOUNT
, "UDF mount", "UDF mount structure");
102 MALLOC_DEFINE(M_UDFFENTRY
, "UDF fentry", "UDF file entry structure");
104 static int udf_mount(struct mount
*, char *, caddr_t
, struct ucred
*);
105 static int udf_unmount(struct mount
*, int);
106 static int udf_root(struct mount
*, struct vnode
**);
107 static int udf_statfs(struct mount
*, struct statfs
*, struct ucred
*);
108 static int udf_fhtovp(struct mount
*, struct vnode
*,
109 struct fid
*, struct vnode
**);
110 static int udf_vptofh(struct vnode
*, struct fid
*);
112 static int udf_find_partmaps(struct udf_mnt
*, struct logvol_desc
*);
114 static struct vfsops udf_vfsops
= {
116 .vfs_mount
= udf_mount
,
117 .vfs_unmount
= udf_unmount
,
118 .vfs_root
= udf_root
,
119 .vfs_statfs
= udf_statfs
,
120 .vfs_vget
= udf_vget
,
121 .vfs_fhtovp
= udf_fhtovp
,
122 .vfs_vptofh
= udf_vptofh
124 VFS_SET(udf_vfsops
, udf
, VFCF_READONLY
);
126 MODULE_VERSION(udf
, 1);
128 static int udf_mountfs(struct vnode
*, struct mount
*);
131 udf_mount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
133 struct vnode
*devvp
; /* vnode of the mount device */
134 struct udf_args args
;
135 struct udf_mnt
*imp
= NULL
;
138 struct nlookupdata nd
;
140 if ((mp
->mnt_flag
& MNT_RDONLY
) == 0)
144 * No root filesystem support. Probably not a big deal, since the
145 * bootloader doesn't understand UDF.
147 if (mp
->mnt_flag
& MNT_ROOTFS
)
150 if ((error
= copyin(data
, (caddr_t
)&args
, sizeof(struct udf_args
))))
153 if (mp
->mnt_flag
& MNT_UPDATE
) {
154 imp
= VFSTOUDFFS(mp
);
155 if (args
.fspec
== NULL
)
156 return(vfs_export(mp
, &imp
->im_export
, &args
.export
));
159 /* Check that the mount device exists */
161 error
= nlookup_init(&nd
, args
.fspec
, UIO_USERSPACE
, NLC_FOLLOW
);
163 error
= nlookup(&nd
);
165 error
= cache_vref(&nd
.nl_nch
, nd
.nl_cred
, &devvp
);
170 if (vn_isdisk(devvp
, &error
) == 0) {
175 /* Check the access rights on the mount device */
176 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
177 error
= VOP_EACCESS(devvp
, VREAD
, cred
);
179 error
= caps_priv_check(cred
, SYSCAP_RESTRICTEDROOT
);
186 if ((error
= udf_mountfs(devvp
, mp
))) {
191 imp
= VFSTOUDFFS(mp
);
193 imp
->im_flags
= args
.flags
;
195 copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1, &size
);
196 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
197 udf_statfs(mp
, &mp
->mnt_stat
, cred
);
202 * Check the descriptor tag for both the correct id and correct checksum.
203 * Return zero if all is good, EINVAL if not.
206 udf_checktag(struct desc_tag
*tag
, uint16_t id
)
209 uint8_t i
, cksum
= 0;
211 itag
= (uint8_t *)tag
;
216 for (i
= 0; i
< 15; i
++)
217 cksum
= cksum
+ itag
[i
];
218 cksum
= cksum
- itag
[4];
220 if (cksum
== tag
->cksum
)
227 udf_mountfs(struct vnode
*devvp
, struct mount
*mp
)
229 struct buf
*bp
= NULL
;
230 struct anchor_vdp avdp
;
231 struct udf_mnt
*udfmp
= NULL
;
232 struct part_desc
*pd
;
233 struct logvol_desc
*lvd
;
234 struct fileset_desc
*fsd
;
235 struct file_entry
*root_fentry
;
237 uint32_t sector
, size
, mvds_start
, mvds_end
;
238 uint32_t fsd_offset
= 0;
239 uint16_t part_num
= 0, fsd_part
= 0;
240 int error
= EINVAL
, needclose
= 0;
241 int logvol_found
= 0, part_found
= 0, fsd_found
= 0;
245 * Disallow multiple mounts of the same device. Flush the buffer
246 * cache for the device.
248 if ((error
= vfs_mountedon(devvp
)))
250 if (vcount(devvp
) > 0)
252 if ((error
= vinvalbuf(devvp
, V_SAVE
, 0, 0)))
255 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
256 error
= VOP_OPEN(devvp
, FREAD
, FSCRED
, NULL
);
263 udfmp
= kmalloc(sizeof(*udfmp
), M_UDFMOUNT
, M_WAITOK
| M_ZERO
);
265 mp
->mnt_data
= (qaddr_t
)udfmp
;
266 mp
->mnt_stat
.f_fsid
.val
[0] = devid_from_dev(dev
);
267 mp
->mnt_stat
.f_fsid
.val
[1] = mp
->mnt_vfc
->vfc_typenum
;
268 mp
->mnt_maxsymlinklen
= 0;
269 mp
->mnt_flag
|= MNT_LOCAL
;
270 udfmp
->im_mountp
= mp
;
272 udfmp
->im_devvp
= devvp
;
274 bsize
= 2048; /* XXX Should probe the media for it's size */
277 * Get the Anchor Volume Descriptor Pointer from sector 256.
278 * XXX Should also check sector n - 256, n, and 512.
281 if ((error
= bread(devvp
, (off_t
)sector
* bsize
, bsize
, &bp
)) != 0)
283 if ((error
= udf_checktag((struct desc_tag
*)bp
->b_data
, TAGID_ANCHOR
)))
286 bcopy(bp
->b_data
, &avdp
, sizeof(struct anchor_vdp
));
291 * Extract the Partition Descriptor and Logical Volume Descriptor
292 * from the Volume Descriptor Sequence.
293 * XXX Should we care about the partition type right now?
294 * XXX What about multiple partitions?
296 mvds_start
= avdp
.main_vds_ex
.loc
;
297 mvds_end
= mvds_start
+ (avdp
.main_vds_ex
.len
- 1) / bsize
;
298 for (sector
= mvds_start
; sector
< mvds_end
; sector
++) {
299 if ((error
= bread(devvp
, (off_t
)sector
* bsize
, bsize
,
301 kprintf("Can't read sector %d of VDS\n", sector
);
304 lvd
= (struct logvol_desc
*)bp
->b_data
;
305 if (!udf_checktag(&lvd
->tag
, TAGID_LOGVOL
)) {
306 udfmp
->bsize
= lvd
->lb_size
;
307 udfmp
->bmask
= udfmp
->bsize
- 1;
308 udfmp
->bshift
= ffs(udfmp
->bsize
) - 1;
309 fsd_part
= lvd
->_lvd_use
.fsd_loc
.loc
.part_num
;
310 fsd_offset
= lvd
->_lvd_use
.fsd_loc
.loc
.lb_num
;
311 if (udf_find_partmaps(udfmp
, lvd
))
315 pd
= (struct part_desc
*)bp
->b_data
;
316 if (!udf_checktag(&pd
->tag
, TAGID_PARTITION
)) {
318 part_num
= pd
->part_num
;
319 udfmp
->part_len
= pd
->part_len
;
320 udfmp
->part_start
= pd
->start_loc
;
325 if ((part_found
) && (logvol_found
))
329 if (!part_found
|| !logvol_found
) {
334 if (fsd_part
!= part_num
) {
335 kprintf("FSD does not lie within the partition!\n");
342 * Grab the Fileset Descriptor
343 * Thanks to Chuck McCrobie <mccrobie@cablespeed.com> for pointing
344 * me in the right direction here.
346 sector
= udfmp
->part_start
+ fsd_offset
;
347 if ((error
= RDSECTOR(devvp
, sector
, udfmp
->bsize
, &bp
)) != 0) {
348 kprintf("Cannot read sector %d of FSD\n", sector
);
351 fsd
= (struct fileset_desc
*)bp
->b_data
;
352 if (!udf_checktag(&fsd
->tag
, TAGID_FSD
)) {
354 bcopy(&fsd
->rootdir_icb
, &udfmp
->root_icb
,
355 sizeof(struct long_ad
));
362 kprintf("Couldn't find the fsd\n");
367 vfs_add_vnodeops(mp
, &udf_vnode_vops
, &mp
->mnt_vn_norm_ops
);
370 * Find the file entry for the root directory.
372 sector
= udfmp
->root_icb
.loc
.lb_num
+ udfmp
->part_start
;
373 size
= udfmp
->root_icb
.len
;
374 if ((error
= udf_readlblks(udfmp
, sector
, size
, &bp
)) != 0) {
375 kprintf("Cannot read sector %d\n", sector
);
379 root_fentry
= (struct file_entry
*)bp
->b_data
;
380 if ((error
= udf_checktag(&root_fentry
->tag
, TAGID_FENTRY
))) {
381 kprintf("Invalid root file entry!\n");
388 lwkt_token_init(&udfmp
->hash_token
, "udfihash");
389 udfmp
->hashtbl
= phashinit(UDF_HASHTBLSIZE
, M_UDFMOUNT
, &udfmp
->hashsz
);
395 kfree(udfmp
, M_UDFMOUNT
);
399 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
400 VOP_CLOSE(devvp
, FREAD
, NULL
);
407 udf_unmount(struct mount
*mp
, int mntflags
)
409 struct udf_mnt
*udfmp
;
410 int error
, flags
= 0;
412 udfmp
= VFSTOUDFFS(mp
);
414 if (mntflags
& MNT_FORCE
)
417 if ((error
= vflush(mp
, 0, flags
)))
420 udfmp
->im_devvp
->v_rdev
->si_mountpoint
= NULL
;
421 vn_lock(udfmp
->im_devvp
, LK_EXCLUSIVE
| LK_RETRY
);
422 error
= VOP_CLOSE(udfmp
->im_devvp
, FREAD
, NULL
);
423 vn_unlock(udfmp
->im_devvp
);
424 vrele(udfmp
->im_devvp
);
427 kfree(udfmp
->s_table
, M_UDFMOUNT
);
429 kfree(udfmp
->hashtbl
, M_UDFMOUNT
);
430 kfree(udfmp
, M_UDFMOUNT
);
432 mp
->mnt_data
= (qaddr_t
)0;
433 mp
->mnt_flag
&= ~MNT_LOCAL
;
439 udf_root(struct mount
*mp
, struct vnode
**vpp
)
441 struct udf_mnt
*udfmp
;
446 udfmp
= VFSTOUDFFS(mp
);
448 id
= udf_getid(&udfmp
->root_icb
);
450 error
= udf_vget(mp
, NULL
, id
, vpp
);
455 vsetflags(vp
, VROOT
);
462 udf_statfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
464 struct udf_mnt
*udfmp
;
466 udfmp
= VFSTOUDFFS(mp
);
468 sbp
->f_bsize
= udfmp
->bsize
;
469 sbp
->f_iosize
= udfmp
->bsize
;
470 sbp
->f_blocks
= udfmp
->part_len
;
475 if (sbp
!= &mp
->mnt_stat
) {
476 sbp
->f_type
= mp
->mnt_vfc
->vfc_typenum
;
477 bcopy(mp
->mnt_stat
.f_mntfromname
, sbp
->f_mntfromname
, MNAMELEN
);
484 udf_vget(struct mount
*mp
, struct vnode
*dvp
, ino_t ino
, struct vnode
**vpp
)
488 struct udf_mnt
*udfmp
;
490 struct udf_node
*unode
;
491 struct file_entry
*fe
;
492 int error
, sector
, size
;
494 udfmp
= VFSTOUDFFS(mp
);
496 /* See if we already have this in the cache */
497 if ((error
= udf_hashlookup(udfmp
, ino
, vpp
)) != 0)
504 * Allocate memory and check the tag id's before grabbing a new
505 * vnode, since it's hard to roll back if there is a problem.
507 unode
= kmalloc(sizeof(*unode
), M_UDFNODE
, M_WAITOK
| M_ZERO
);
510 * Copy in the file entry. Per the spec, the size can only be 1 block.
512 sector
= ino
+ udfmp
->part_start
;
513 devvp
= udfmp
->im_devvp
;
514 if ((error
= RDSECTOR(devvp
, sector
, udfmp
->bsize
, &bp
)) != 0) {
515 kprintf("Cannot read sector %d\n", sector
);
516 kfree(unode
, M_UDFNODE
);
520 fe
= (struct file_entry
*)bp
->b_data
;
521 if (udf_checktag(&fe
->tag
, TAGID_FENTRY
)) {
522 kprintf("Invalid file entry!\n");
523 kfree(unode
, M_UDFNODE
);
527 size
= UDF_FENTRY_SIZE
+ fe
->l_ea
+ fe
->l_ad
;
528 unode
->fentry
= kmalloc(size
, M_UDFFENTRY
, M_WAITOK
| M_ZERO
);
530 bcopy(bp
->b_data
, unode
->fentry
, size
);
535 if ((error
= udf_allocv(mp
, &vp
))) {
536 kprintf("Error from udf_allocv\n");
537 kfree(unode
, M_UDFNODE
);
542 unode
->hash_id
= ino
;
543 unode
->i_devvp
= udfmp
->im_devvp
;
544 unode
->i_dev
= udfmp
->im_dev
;
545 unode
->udfmp
= udfmp
;
547 vref(udfmp
->im_devvp
);
550 switch (unode
->fentry
->icbtag
.file_type
) {
577 * Locked and refd vnode returned
592 udf_fhtovp(struct mount
*mp
, struct vnode
*rootvp
,
593 struct fid
*fhp
, struct vnode
**vpp
)
599 ifhp
= (struct ifid
*)fhp
;
601 if ((error
= VFS_VGET(mp
, NULL
, ifhp
->ifid_ino
, &nvp
)) != 0) {
611 udf_vptofh (struct vnode
*vp
, struct fid
*fhp
)
613 struct udf_node
*node
;
617 ifhp
= (struct ifid
*)fhp
;
618 ifhp
->ifid_len
= sizeof(struct ifid
);
619 ifhp
->ifid_ino
= node
->hash_id
;
625 udf_find_partmaps(struct udf_mnt
*udfmp
, struct logvol_desc
*lvd
)
627 union udf_pmap
*pmap
;
628 struct part_map_spare
*pms
;
629 struct regid
*pmap_id
;
631 unsigned char regid_id
[UDF_REGID_ID_SIZE
+ 1];
632 int ptype
, psize
, error
;
635 for (i
= 0; i
< lvd
->n_pm
; i
++) {
636 pmap
= (union udf_pmap
*)&lvd
->maps
[i
* UDF_PMAP_SIZE
];
637 ptype
= pmap
->data
[0];
638 psize
= pmap
->data
[1];
639 if (((ptype
!= 1) && (ptype
!= 2)) ||
640 ((psize
!= UDF_PMAP_SIZE
) && (psize
!= 6))) {
641 kprintf("Invalid partition map found\n");
646 /* Type 1 map. We don't care */
650 /* Type 2 map. Gotta find out the details */
651 pmap_id
= (struct regid
*)&pmap
->data
[4];
652 bzero(®id_id
[0], UDF_REGID_ID_SIZE
);
653 bcopy(&pmap_id
->id
[0], ®id_id
[0], UDF_REGID_ID_SIZE
);
655 if (bcmp(®id_id
[0], "*UDF Sparable Partition",
656 UDF_REGID_ID_SIZE
)) {
657 kprintf("Unsupported partition map: %s\n", ®id_id
[0]);
662 udfmp
->s_table
= kmalloc(pms
->st_size
, M_UDFMOUNT
,
665 /* Calculate the number of sectors per packet. */
666 /* XXX Logical or physical? */
667 udfmp
->p_sectors
= pms
->packet_len
/ udfmp
->bsize
;
670 * XXX If reading the first Sparing Table fails, should look
673 if ((error
= udf_readlblks(udfmp
, pms
->st_loc
[0], pms
->st_size
,
677 kprintf("Failed to read Sparing Table at sector %d\n",
681 bcopy(bp
->b_data
, udfmp
->s_table
, pms
->st_size
);
684 if (udf_checktag(&udfmp
->s_table
->tag
, 0)) {
685 kprintf("Invalid sparing table found\n");
689 /* See how many valid entries there are here. The list is
690 * supposed to be sorted. 0xfffffff0 and higher are not valid
692 for (i
= 0; i
< udfmp
->s_table
->rt_l
; i
++) {
693 udfmp
->s_table_entries
= i
;
694 if (udfmp
->s_table
->entries
[i
].org
>= 0xfffffff0)