1/*
2 * Copyright (c) 2000-2008,2010-2011,2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/* $FreeBSD: src/sys/msdosfs/fat.h,v 1.9 1999/12/29 04:54:53 peter Exp $ */
24/*	$NetBSD: fat.h,v 1.12 1997/11/17 15:36:36 ws Exp $	*/
25
26/*-
27 * Copyright (C) 1994, 1997 Wolfgang Solfrank.
28 * Copyright (C) 1994, 1997 TooLs GmbH.
29 * All rights reserved.
30 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 *    notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 *    notice, this list of conditions and the following disclaimer in the
39 *    documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 *    must display the following acknowledgement:
42 *	This product includes software developed by TooLs GmbH.
43 * 4. The name of TooLs GmbH may not be used to endorse or promote products
44 *    derived from this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57/*
58 * Written by Paul Popelka (paulp@uts.amdahl.com)
59 *
60 * You can do anything you want with this software, just don't say you wrote
61 * it, and don't remove this notice.
62 *
63 * This software is provided "as is".
64 *
65 * The author supplies this software to be publicly redistributed on the
66 * understanding that the author is not responsible for the correct
67 * functioning of this software in any circumstances and is not liable for
68 * any damages caused by this software.
69 *
70 * October 1992
71 */
72
73
74/*
75 * Some useful cluster numbers.
76 */
77#define	MSDOSFSROOT	0		/* cluster 0 means the root dir */
78#define	CLUST_FREE	0		/* cluster 0 also means a free cluster */
79#define	MSDOSFSFREE	CLUST_FREE
80#define	CLUST_FIRST	2		/* first legal cluster number */
81#define	CLUST_RSRVD	0xfffffff6	/* reserved cluster range */
82#define	CLUST_BAD	0xfffffff7	/* a cluster with a defect */
83#define	CLUST_EOFS	0xfffffff8	/* start of eof cluster range */
84#define	CLUST_EOFE	0xffffffff	/* end of eof cluster range */
85
86/*
87 * Note: FILENO_EMPTY must be larger than FAT32_MASK so that it can't accidentally
88 * occur as a valid cluster number.
89 */
90#define FILENO_EMPTY	999999999	/* Fake file number used for empty files */
91#define FILENO_ROOT	1		/* File number used for root directory of FAT12 and FAT16 */
92
93#define	FAT12_MASK	0x00000fff	/* mask for 12 bit cluster numbers */
94#define	FAT16_MASK	0x0000ffff	/* mask for 16 bit cluster numbers */
95#define	FAT32_MASK	0x0fffffff	/* mask for FAT32 cluster numbers */
96
97/*
98 * MSDOSFS:
99 * Return true if filesystem uses 12 bit fats. Microsoft Programmer's
100 * Reference says if the maximum cluster number in a filesystem is greater
101 * than 4078 ((CLUST_RSRVS - CLUST_FIRST) & FAT12_MASK) then we've got a
102 * 16 bit fat filesystem. While mounting, the result of this test is stored
103 * in pm_fatentrysize.
104 * GEMDOS-flavour (atari):
105 * If the filesystem is on floppy we've got a 12 bit fat filesystem, otherwise
106 * 16 bit. We check the d_type field in the disklabel struct while mounting
107 * and store the result in the pm_fatentrysize. Note that this kind of
108 * detection gets flakey when mounting a vnd-device.
109 */
110#define	FAT12(pmp)	(pmp->pm_fatmask == FAT12_MASK)
111#define	FAT16(pmp)	(pmp->pm_fatmask == FAT16_MASK)
112#define	FAT32(pmp)	(pmp->pm_fatmask == FAT32_MASK)
113
114#define	MSDOSFSEOF(pmp, cn)	((((cn) | ~(pmp)->pm_fatmask) & CLUST_EOFS) == CLUST_EOFS)
115
116/*
117		Symbolic Links for FAT
118
119FAT does not have native support for symbolic links (symlinks).  We
120implement them using ordinary files with a particular format.  Our
121symlink file format is modeled after the SMB for Mac OS X implementation.
122
123Symlink files are ordinary text files that look like:
124
125XSym
1261234
12700112233445566778899AABBCCDDEEFF
128/the/sym/link/path
129
130The lines of the file are separated by ASCII newline (0x0A).  The first
131line is a "magic" value to help identify the file.  The second line is
132the length of the symlink itself; it is four decimal digits, with leading
133zeroes.  The third line is the MD5 checksum of the symlink as 16
134hexadecimal bytes.  The fourth line is the symlink, up to 1024 bytes long.
135If the symlink is less than 1024 bytes, then it is padded with a single
136newline character and as many spaces as needed to occupy 1024 bytes.
137
138The file size is exactly 1067 (= 4 + 1 + 4 + 1 + 32 + 1 + 1024) bytes.
139When we encounter an ordinary file whose length is 1067, we must read
140it to verify that the header (including length and MD5 checksum) is
141correct.
142
143Since the file size is constant, we use the de_FileSize field in the
144denode to store the actual length of the symlink.  That way, we only
145check and parse the header once at vnode creation time.
146
147*/
148
149static const char symlink_magic[5] = "XSym\n";
150
151#define SYMLINK_LINK_MAX 1024
152
153struct symlink {
154	char magic[5];		/* == symlink_magic */
155	char length[4];		/* four decimal digits */
156	char newline1;		/* '\n' */
157	char md5[32];		/* MD5 hex digest of "length" bytes of "link" field */
158	char newline2;		/* '\n' */
159	char link[SYMLINK_LINK_MAX]; /* "length" bytes, padded by '\n' and spaces */
160};
161
162#ifdef KERNEL
163/*
164 * These are the values for the function argument to the function
165 * msdosfs_fatentry().
166 */
167#define	FAT_GET		0x0001	/* get a fat entry */
168#define	FAT_SET		0x0002	/* set a fat entry */
169#define	FAT_GET_AND_SET	(FAT_GET | FAT_SET)
170
171/*
172 * Flags to msdosfs_extendfile:
173 */
174#define	DE_CLEAR	1	/* Zero out the blocks allocated */
175#define DE_SYNC		IO_SYNC	/* 0x4 do it synchronisly...from vnode.h */
176
177
178void msdosfs_fat_init(void);
179void msdosfs_fat_uninit(void);
180int  msdosfs_fat_init_vol(struct msdosfsmount *pmp);
181void msdosfs_fat_uninit_vol(struct msdosfsmount *pmp);
182int msdosfs_update_fsinfo(struct msdosfsmount *pmp, int waitfor, vfs_context_t context);
183int msdosfs_pcbmap (struct denode *dep, uint32_t findcn, uint32_t numclusters, daddr64_t *bnp, uint32_t *cnp, uint32_t *sp);
184int msdosfs_pcbmap_internal(struct denode *dep, uint32_t findcn, uint32_t numclusters, daddr64_t *bnp, uint32_t *cnp, uint32_t *sp);
185int msdosfs_clusteralloc(struct msdosfsmount *pmp, uint32_t start, uint32_t count, uint32_t fillwith, uint32_t *retcluster, uint32_t *got);
186int msdosfs_fatentry(int function, struct msdosfsmount *pmp, uint32_t cluster, uint32_t *oldcontents, uint32_t newcontents);
187int msdosfs_freeclusterchain(struct msdosfsmount *pmp, uint32_t startchain);
188int msdosfs_extendfile(struct denode *dep, uint32_t count, uint32_t *numAllocated);
189
190/* [2753891]
191 * Routine to mark a FAT16 or FAT32 volume as "clean" or "dirty" by manipulating the upper bit
192 * of the FAT entry for cluster 1.  Note that this bit is not defined for FAT12 volumes.
193 */
194int msdosfs_markvoldirty(struct msdosfsmount *pmp, int dirty);
195
196/*
197 * Write the primary/active FAT and all directories to the device.  This
198 * skips the boot sector, FSInfo sector, and non-active copies of the FAT.
199 */
200void msdosfs_meta_flush(struct msdosfsmount *pmp, int sync);
201void msdosfs_meta_sync_callback(void *pmp, void *unused);
202
203enum vtype msdosfs_check_link(struct denode *dep, vfs_context_t context);
204
205extern u_char l2u[256];
206
207/*
208 * Tunables to control delayed metadata sync.
209 */
210extern uint32_t msdosfs_meta_delay;
211
212#endif	/* KERNEL */
213