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 $
27 * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.27 2008/01/06 16:55:53 swildner Exp $
31 /* Implement the VFS side of things */
34 * Ok, here's how it goes. The UDF specs are pretty clear on how each data
35 * structure is made up, but not very clear on how they relate to each other.
36 * Here is the skinny... This demostrates a filesystem with one file in the
37 * root directory. Subdirectories are treated just as normal files, but they
38 * have File Id Descriptors of their children as their file data. As for the
39 * Anchor Volume Descriptor Pointer, it can exist in two of the following three
40 * places: sector 256, sector n (the max sector of the disk), or sector
41 * n - 256. It's a pretty good bet that one will exist at sector 256 though.
42 * One caveat is unclosed CD media. For that, sector 256 cannot be written,
43 * so the Anchor Volume Descriptor Pointer can exist at sector 512 until the
48 * n: Anchor Volume Descriptor Pointer
51 * |-->Main Volume Descriptor Sequence
54 * | |-->Logical Volume Descriptor
56 * |-->Partition Descriptor |
59 * |-->Fileset Descriptor
62 * |-->Root Dir File Entry
75 #include <sys/types.h>
76 #include <sys/param.h>
77 #include <sys/systm.h>
81 #include <sys/fcntl.h>
82 #include <sys/module.h>
83 #include <sys/kernel.h>
84 #include <sys/malloc.h>
85 #include <sys/mount.h>
86 #include <sys/nlookup.h>
88 #include <sys/queue.h>
89 #include <sys/vnode.h>
91 #include <vfs/udf/ecma167-udf.h>
92 #include <vfs/udf/osta.h>
93 #include <vfs/udf/udf.h>
94 #include <vfs/udf/udf_mount.h>
96 extern struct vop_ops udf_vnode_vops
;
98 MALLOC_DEFINE(M_UDFNODE
, "UDF node", "UDF node structure");
99 MALLOC_DEFINE(M_UDFMOUNT
, "UDF mount", "UDF mount structure");
100 MALLOC_DEFINE(M_UDFFENTRY
, "UDF fentry", "UDF file entry structure");
102 static int udf_mount(struct mount
*, char *, caddr_t
, struct ucred
*);
103 static int udf_unmount(struct mount
*, int);
104 static int udf_root(struct mount
*, struct vnode
**);
105 static int udf_statfs(struct mount
*, struct statfs
*, struct ucred
*);
106 static int udf_fhtovp(struct mount
*, struct fid
*, struct vnode
**);
107 static int udf_vptofh(struct vnode
*, struct fid
*);
109 static int udf_find_partmaps(struct udf_mnt
*, struct logvol_desc
*);
111 static struct vfsops udf_vfsops
= {
112 .vfs_mount
= udf_mount
,
113 .vfs_unmount
= udf_unmount
,
114 .vfs_root
= udf_root
,
115 .vfs_statfs
= udf_statfs
,
116 .vfs_sync
= vfs_stdsync
,
117 .vfs_vget
= udf_vget
,
118 .vfs_fhtovp
= udf_fhtovp
,
119 .vfs_vptofh
= udf_vptofh
121 VFS_SET(udf_vfsops
, udf
, VFCF_READONLY
);
123 MODULE_VERSION(udf
, 1);
125 static int udf_mountfs(struct vnode
*, struct mount
*);
128 udf_mount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
130 struct vnode
*devvp
; /* vnode of the mount device */
131 struct udf_args args
;
132 struct udf_mnt
*imp
= 0;
135 struct nlookupdata nd
;
137 if ((mp
->mnt_flag
& MNT_RDONLY
) == 0)
141 * No root filesystem support. Probably not a big deal, since the
142 * bootloader doesn't understand UDF.
144 if (mp
->mnt_flag
& MNT_ROOTFS
)
147 if ((error
= copyin(data
, (caddr_t
)&args
, sizeof(struct udf_args
))))
150 if (mp
->mnt_flag
& MNT_UPDATE
) {
151 imp
= VFSTOUDFFS(mp
);
152 if (args
.fspec
== NULL
)
153 return(vfs_export(mp
, &imp
->im_export
, &args
.export
));
156 /* Check that the mount device exists */
158 error
= nlookup_init(&nd
, args
.fspec
, UIO_USERSPACE
, NLC_FOLLOW
);
160 error
= nlookup(&nd
);
162 error
= cache_vref(&nd
.nl_nch
, nd
.nl_cred
, &devvp
);
167 if (vn_isdisk(devvp
, &error
) == 0) {
172 /* Check the access rights on the mount device */
173 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
174 error
= VOP_ACCESS(devvp
, VREAD
, cred
);
176 error
= suser_cred(cred
, 0);
183 if ((error
= udf_mountfs(devvp
, mp
))) {
188 imp
= VFSTOUDFFS(mp
);
190 imp
->im_flags
= args
.flags
;
192 copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1, &size
);
193 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
194 udf_statfs(mp
, &mp
->mnt_stat
, cred
);
199 * Check the descriptor tag for both the correct id and correct checksum.
200 * Return zero if all is good, EINVAL if not.
203 udf_checktag(struct desc_tag
*tag
, uint16_t id
)
206 uint8_t i
, cksum
= 0;
208 itag
= (uint8_t *)tag
;
213 for (i
= 0; i
< 15; i
++)
214 cksum
= cksum
+ itag
[i
];
215 cksum
= cksum
- itag
[4];
217 if (cksum
== tag
->cksum
)
224 udf_mountfs(struct vnode
*devvp
, struct mount
*mp
)
226 struct buf
*bp
= NULL
;
227 struct anchor_vdp avdp
;
228 struct udf_mnt
*udfmp
= NULL
;
229 struct part_desc
*pd
;
230 struct logvol_desc
*lvd
;
231 struct fileset_desc
*fsd
;
232 struct file_entry
*root_fentry
;
234 uint32_t sector
, size
, mvds_start
, mvds_end
;
235 uint32_t fsd_offset
= 0;
236 uint16_t part_num
= 0, fsd_part
= 0;
237 int error
= EINVAL
, needclose
= 0;
238 int logvol_found
= 0, part_found
= 0, fsd_found
= 0;
242 * Disallow multiple mounts of the same device. Flush the buffer
243 * cache for the device.
245 if ((error
= vfs_mountedon(devvp
)))
247 if (count_udev(devvp
->v_umajor
, devvp
->v_uminor
) > 0)
249 if ((error
= vinvalbuf(devvp
, V_SAVE
, 0, 0)))
252 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
253 error
= VOP_OPEN(devvp
, FREAD
, FSCRED
, NULL
);
260 udfmp
= kmalloc(sizeof(*udfmp
), M_UDFMOUNT
, M_WAITOK
| M_ZERO
);
262 mp
->mnt_data
= (qaddr_t
)udfmp
;
263 mp
->mnt_stat
.f_fsid
.val
[0] = dev2udev(dev
);
264 mp
->mnt_stat
.f_fsid
.val
[1] = mp
->mnt_vfc
->vfc_typenum
;
265 mp
->mnt_maxsymlinklen
= 0;
266 mp
->mnt_flag
|= MNT_LOCAL
;
267 udfmp
->im_mountp
= mp
;
269 udfmp
->im_devvp
= devvp
;
271 bsize
= 2048; /* XXX Should probe the media for it's size */
274 * Get the Anchor Volume Descriptor Pointer from sector 256.
275 * XXX Should also check sector n - 256, n, and 512.
278 if ((error
= bread(devvp
, (off_t
)sector
* bsize
, bsize
, &bp
)) != 0)
280 if ((error
= udf_checktag((struct desc_tag
*)bp
->b_data
, TAGID_ANCHOR
)))
283 bcopy(bp
->b_data
, &avdp
, sizeof(struct anchor_vdp
));
288 * Extract the Partition Descriptor and Logical Volume Descriptor
289 * from the Volume Descriptor Sequence.
290 * XXX Should we care about the partition type right now?
291 * XXX What about multiple partitions?
293 mvds_start
= avdp
.main_vds_ex
.loc
;
294 mvds_end
= mvds_start
+ (avdp
.main_vds_ex
.len
- 1) / bsize
;
295 for (sector
= mvds_start
; sector
< mvds_end
; sector
++) {
296 if ((error
= bread(devvp
, (off_t
)sector
* bsize
, bsize
,
298 kprintf("Can't read sector %d of VDS\n", sector
);
301 lvd
= (struct logvol_desc
*)bp
->b_data
;
302 if (!udf_checktag(&lvd
->tag
, TAGID_LOGVOL
)) {
303 udfmp
->bsize
= lvd
->lb_size
;
304 udfmp
->bmask
= udfmp
->bsize
- 1;
305 udfmp
->bshift
= ffs(udfmp
->bsize
) - 1;
306 fsd_part
= lvd
->_lvd_use
.fsd_loc
.loc
.part_num
;
307 fsd_offset
= lvd
->_lvd_use
.fsd_loc
.loc
.lb_num
;
308 if (udf_find_partmaps(udfmp
, lvd
))
312 pd
= (struct part_desc
*)bp
->b_data
;
313 if (!udf_checktag(&pd
->tag
, TAGID_PARTITION
)) {
315 part_num
= pd
->part_num
;
316 udfmp
->part_len
= pd
->part_len
;
317 udfmp
->part_start
= pd
->start_loc
;
322 if ((part_found
) && (logvol_found
))
326 if (!part_found
|| !logvol_found
) {
331 if (fsd_part
!= part_num
) {
332 kprintf("FSD does not lie within the partition!\n");
339 * Grab the Fileset Descriptor
340 * Thanks to Chuck McCrobie <mccrobie@cablespeed.com> for pointing
341 * me in the right direction here.
343 sector
= udfmp
->part_start
+ fsd_offset
;
344 if ((error
= RDSECTOR(devvp
, sector
, udfmp
->bsize
, &bp
)) != 0) {
345 kprintf("Cannot read sector %d of FSD\n", sector
);
348 fsd
= (struct fileset_desc
*)bp
->b_data
;
349 if (!udf_checktag(&fsd
->tag
, TAGID_FSD
)) {
351 bcopy(&fsd
->rootdir_icb
, &udfmp
->root_icb
,
352 sizeof(struct long_ad
));
359 kprintf("Couldn't find the fsd\n");
364 vfs_add_vnodeops(mp
, &udf_vnode_vops
, &mp
->mnt_vn_norm_ops
);
367 * Find the file entry for the root directory.
369 sector
= udfmp
->root_icb
.loc
.lb_num
+ udfmp
->part_start
;
370 size
= udfmp
->root_icb
.len
;
371 if ((error
= udf_readlblks(udfmp
, sector
, size
, &bp
)) != 0) {
372 kprintf("Cannot read sector %d\n", sector
);
376 root_fentry
= (struct file_entry
*)bp
->b_data
;
377 if ((error
= udf_checktag(&root_fentry
->tag
, TAGID_FENTRY
))) {
378 kprintf("Invalid root file entry!\n");
385 lwkt_token_init(&udfmp
->hash_token
);
386 udfmp
->hashtbl
= phashinit(UDF_HASHTBLSIZE
, M_UDFMOUNT
, &udfmp
->hashsz
);
392 kfree(udfmp
, M_UDFMOUNT
);
396 VOP_CLOSE(devvp
, FREAD
);
401 udf_unmount(struct mount
*mp
, int mntflags
)
403 struct udf_mnt
*udfmp
;
404 int error
, flags
= 0;
406 udfmp
= VFSTOUDFFS(mp
);
408 if (mntflags
& MNT_FORCE
)
411 if ((error
= vflush(mp
, 0, flags
)))
414 udfmp
->im_devvp
->v_rdev
->si_mountpoint
= NULL
;
415 error
= VOP_CLOSE(udfmp
->im_devvp
, FREAD
);
416 vrele(udfmp
->im_devvp
);
419 kfree(udfmp
->s_table
, M_UDFMOUNT
);
421 kfree(udfmp
->hashtbl
, M_UDFMOUNT
);
422 kfree(udfmp
, M_UDFMOUNT
);
424 mp
->mnt_data
= (qaddr_t
)0;
425 mp
->mnt_flag
&= ~MNT_LOCAL
;
431 udf_root(struct mount
*mp
, struct vnode
**vpp
)
433 struct udf_mnt
*udfmp
;
438 udfmp
= VFSTOUDFFS(mp
);
440 id
= udf_getid(&udfmp
->root_icb
);
442 error
= udf_vget(mp
, id
, vpp
);
454 udf_statfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
456 struct udf_mnt
*udfmp
;
458 udfmp
= VFSTOUDFFS(mp
);
460 sbp
->f_bsize
= udfmp
->bsize
;
461 sbp
->f_iosize
= udfmp
->bsize
;
462 sbp
->f_blocks
= udfmp
->part_len
;
467 if (sbp
!= &mp
->mnt_stat
) {
468 sbp
->f_type
= mp
->mnt_vfc
->vfc_typenum
;
469 bcopy(mp
->mnt_stat
.f_mntfromname
, sbp
->f_mntfromname
, MNAMELEN
);
476 udf_vget(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
)
480 struct udf_mnt
*udfmp
;
483 struct udf_node
*unode
;
484 struct file_entry
*fe
;
485 int error
, sector
, size
;
488 udfmp
= VFSTOUDFFS(mp
);
490 /* See if we already have this in the cache */
491 if ((error
= udf_hashlookup(udfmp
, ino
, vpp
)) != 0)
498 * Allocate memory and check the tag id's before grabbing a new
499 * vnode, since it's hard to roll back if there is a problem.
501 unode
= kmalloc(sizeof(*unode
), M_UDFNODE
, M_WAITOK
| M_ZERO
);
504 * Copy in the file entry. Per the spec, the size can only be 1 block.
506 sector
= ino
+ udfmp
->part_start
;
507 devvp
= udfmp
->im_devvp
;
508 if ((error
= RDSECTOR(devvp
, sector
, udfmp
->bsize
, &bp
)) != 0) {
509 kprintf("Cannot read sector %d\n", sector
);
510 kfree(unode
, M_UDFNODE
);
514 fe
= (struct file_entry
*)bp
->b_data
;
515 if (udf_checktag(&fe
->tag
, TAGID_FENTRY
)) {
516 kprintf("Invalid file entry!\n");
517 kfree(unode
, M_UDFNODE
);
521 size
= UDF_FENTRY_SIZE
+ fe
->l_ea
+ fe
->l_ad
;
522 unode
->fentry
= kmalloc(size
, M_UDFFENTRY
, M_WAITOK
| M_ZERO
);
524 bcopy(bp
->b_data
, unode
->fentry
, size
);
529 if ((error
= udf_allocv(mp
, &vp
))) {
530 kprintf("Error from udf_allocv\n");
531 kfree(unode
, M_UDFNODE
);
536 unode
->hash_id
= ino
;
537 unode
->i_devvp
= udfmp
->im_devvp
;
538 unode
->i_dev
= udfmp
->im_dev
;
539 unode
->udfmp
= udfmp
;
541 vref(udfmp
->im_devvp
);
544 switch (unode
->fentry
->icbtag
.file_type
) {
571 * Locked and refd vnode returned
586 udf_fhtovp(struct mount
*mp
, struct fid
*fhp
, struct vnode
**vpp
)
592 ifhp
= (struct ifid
*)fhp
;
594 if ((error
= VFS_VGET(mp
, ifhp
->ifid_ino
, &nvp
)) != 0) {
604 udf_vptofh (struct vnode
*vp
, struct fid
*fhp
)
606 struct udf_node
*node
;
610 ifhp
= (struct ifid
*)fhp
;
611 ifhp
->ifid_len
= sizeof(struct ifid
);
612 ifhp
->ifid_ino
= node
->hash_id
;
618 udf_find_partmaps(struct udf_mnt
*udfmp
, struct logvol_desc
*lvd
)
620 union udf_pmap
*pmap
;
621 struct part_map_spare
*pms
;
622 struct regid
*pmap_id
;
624 unsigned char regid_id
[UDF_REGID_ID_SIZE
+ 1];
625 int ptype
, psize
, error
;
628 for (i
= 0; i
< lvd
->n_pm
; i
++) {
629 pmap
= (union udf_pmap
*)&lvd
->maps
[i
* UDF_PMAP_SIZE
];
630 ptype
= pmap
->data
[0];
631 psize
= pmap
->data
[1];
632 if (((ptype
!= 1) && (ptype
!= 2)) ||
633 ((psize
!= UDF_PMAP_SIZE
) && (psize
!= 6))) {
634 kprintf("Invalid partition map found\n");
639 /* Type 1 map. We don't care */
643 /* Type 2 map. Gotta find out the details */
644 pmap_id
= (struct regid
*)&pmap
->data
[4];
645 bzero(®id_id
[0], UDF_REGID_ID_SIZE
);
646 bcopy(&pmap_id
->id
[0], ®id_id
[0], UDF_REGID_ID_SIZE
);
648 if (bcmp(®id_id
[0], "*UDF Sparable Partition",
649 UDF_REGID_ID_SIZE
)) {
650 kprintf("Unsupported partition map: %s\n", ®id_id
[0]);
655 udfmp
->s_table
= kmalloc(pms
->st_size
, M_UDFMOUNT
,
658 /* Calculate the number of sectors per packet. */
659 /* XXX Logical or physical? */
660 udfmp
->p_sectors
= pms
->packet_len
/ udfmp
->bsize
;
663 * XXX If reading the first Sparing Table fails, should look
666 if ((error
= udf_readlblks(udfmp
, pms
->st_loc
[0], pms
->st_size
,
670 kprintf("Failed to read Sparing Table at sector %d\n",
674 bcopy(bp
->b_data
, udfmp
->s_table
, pms
->st_size
);
677 if (udf_checktag(&udfmp
->s_table
->tag
, 0)) {
678 kprintf("Invalid sparing table found\n");
682 /* See how many valid entries there are here. The list is
683 * supposed to be sorted. 0xfffffff0 and higher are not valid
685 for (i
= 0; i
< udfmp
->s_table
->rt_l
; i
++) {
686 udfmp
->s_table_entries
= i
;
687 if (udfmp
->s_table
->entries
[i
].org
>= 0xfffffff0)