xref: /openbmc/linux/fs/udf/super.c (revision e50e86dbcabda570fc8a1435fe2fca97e9ab7312)
15ce34554SBagas Sanjaya // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * super.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * PURPOSE
61da177e4SLinus Torvalds  *  Super block routines for the OSTA-UDF(tm) filesystem.
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * DESCRIPTION
91da177e4SLinus Torvalds  *  OSTA-UDF(tm) = Optical Storage Technology Association
101da177e4SLinus Torvalds  *  Universal Disk Format.
111da177e4SLinus Torvalds  *
121da177e4SLinus Torvalds  *  This code is based on version 2.00 of the UDF specification,
131da177e4SLinus Torvalds  *  and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
141da177e4SLinus Torvalds  *    http://www.osta.org/
15248727a4SAlexander A. Klimov  *    https://www.ecma.ch/
16248727a4SAlexander A. Klimov  *    https://www.iso.org/
171da177e4SLinus Torvalds  *
181da177e4SLinus Torvalds  * COPYRIGHT
191da177e4SLinus Torvalds  *  (C) 1998 Dave Boynton
201da177e4SLinus Torvalds  *  (C) 1998-2004 Ben Fennema
211da177e4SLinus Torvalds  *  (C) 2000 Stelias Computing Inc
221da177e4SLinus Torvalds  *
231da177e4SLinus Torvalds  * HISTORY
241da177e4SLinus Torvalds  *
251da177e4SLinus Torvalds  *  09/24/98 dgb  changed to allow compiling outside of kernel, and
261da177e4SLinus Torvalds  *                added some debugging.
271da177e4SLinus Torvalds  *  10/01/98 dgb  updated to allow (some) possibility of compiling w/2.0.34
281da177e4SLinus Torvalds  *  10/16/98      attempting some multi-session support
291da177e4SLinus Torvalds  *  10/17/98      added freespace count for "df"
301da177e4SLinus Torvalds  *  11/11/98 gr   added novrs option
311da177e4SLinus Torvalds  *  11/26/98 dgb  added fileset,anchor mount options
323a71fc5dSMarcin Slusarz  *  12/06/98 blf  really hosed things royally. vat/sparing support. sequenced
333a71fc5dSMarcin Slusarz  *                vol descs. rewrote option handling based on isofs
341da177e4SLinus Torvalds  *  12/20/98      find the free space bitmap (if it exists)
351da177e4SLinus Torvalds  */
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds #include "udfdecl.h"
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds #include <linux/blkdev.h>
401da177e4SLinus Torvalds #include <linux/slab.h>
411da177e4SLinus Torvalds #include <linux/kernel.h>
421da177e4SLinus Torvalds #include <linux/module.h>
431da177e4SLinus Torvalds #include <linux/parser.h>
441da177e4SLinus Torvalds #include <linux/stat.h>
451da177e4SLinus Torvalds #include <linux/cdrom.h>
461da177e4SLinus Torvalds #include <linux/nls.h>
471da177e4SLinus Torvalds #include <linux/vfs.h>
481da177e4SLinus Torvalds #include <linux/vmalloc.h>
49dc5d39beSMarcin Slusarz #include <linux/errno.h>
506da80894SMiklos Szeredi #include <linux/mount.h>
516da80894SMiklos Szeredi #include <linux/seq_file.h>
5201b954a3SMarcin Slusarz #include <linux/bitmap.h>
53f845fcedSBob Copeland #include <linux/crc-itu-t.h>
541df2ae31SJan Kara #include <linux/log2.h>
551da177e4SLinus Torvalds #include <asm/byteorder.h>
56a48fc69fSJan Kara #include <linux/iversion.h>
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds #include "udf_sb.h"
591da177e4SLinus Torvalds #include "udf_i.h"
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds #include <linux/init.h>
62e973606cSFabian Frederick #include <linux/uaccess.h>
631da177e4SLinus Torvalds 
644b8d4252SJan Kara enum {
654b8d4252SJan Kara 	VDS_POS_PRIMARY_VOL_DESC,
664b8d4252SJan Kara 	VDS_POS_UNALLOC_SPACE_DESC,
674b8d4252SJan Kara 	VDS_POS_LOGICAL_VOL_DESC,
684b8d4252SJan Kara 	VDS_POS_IMP_USE_VOL_DESC,
694b8d4252SJan Kara 	VDS_POS_LENGTH
704b8d4252SJan Kara };
711da177e4SLinus Torvalds 
7244499602SPeter A. Felvegi #define VSD_FIRST_SECTOR_OFFSET		32768
7344499602SPeter A. Felvegi #define VSD_MAX_SECTOR_OFFSET		0x800000
7444499602SPeter A. Felvegi 
75a47241cdSAlden Tondettar /*
76a47241cdSAlden Tondettar  * Maximum number of Terminating Descriptor / Logical Volume Integrity
77a47241cdSAlden Tondettar  * Descriptor redirections. The chosen numbers are arbitrary - just that we
78a47241cdSAlden Tondettar  * hopefully don't limit any real use of rewritten inode on write-once media
79a47241cdSAlden Tondettar  * but avoid looping for too long on corrupted media.
80a47241cdSAlden Tondettar  */
81a47241cdSAlden Tondettar #define UDF_MAX_TD_NESTING 64
82a47241cdSAlden Tondettar #define UDF_MAX_LVID_NESTING 1000
83a47241cdSAlden Tondettar 
848de52778SAl Viro enum { UDF_MAX_LINKS = 0xffff };
85c2efd13aSJan Kara /*
86c2efd13aSJan Kara  * We limit filesize to 4TB. This is arbitrary as the on-disk format supports
87c2efd13aSJan Kara  * more but because the file space is described by a linked list of extents,
88c2efd13aSJan Kara  * each of which can have at most 1GB, the creation and handling of extents
89c2efd13aSJan Kara  * gets unusably slow beyond certain point...
90c2efd13aSJan Kara  */
91c2efd13aSJan Kara #define UDF_MAX_FILESIZE (1ULL << 42)
928de52778SAl Viro 
931da177e4SLinus Torvalds /* These are the "meat" - everything else is stuffing */
941da177e4SLinus Torvalds static int udf_fill_super(struct super_block *, void *, int);
951da177e4SLinus Torvalds static void udf_put_super(struct super_block *);
96146bca72SJan Kara static int udf_sync_fs(struct super_block *, int);
971da177e4SLinus Torvalds static int udf_remount_fs(struct super_block *, int *, char *);
985ca4e4beSPekka Enberg static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
991da177e4SLinus Torvalds static void udf_open_lvid(struct super_block *);
1001da177e4SLinus Torvalds static void udf_close_lvid(struct super_block *);
1011da177e4SLinus Torvalds static unsigned int udf_count_free(struct super_block *);
102726c3342SDavid Howells static int udf_statfs(struct dentry *, struct kstatfs *);
10334c80b1dSAl Viro static int udf_show_options(struct seq_file *, struct dentry *);
1041da177e4SLinus Torvalds 
udf_sb_lvidiu(struct super_block * sb)10569d75671SJan Kara struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb)
1066c79e987SMarcin Slusarz {
10769d75671SJan Kara 	struct logicalVolIntegrityDesc *lvid;
10869d75671SJan Kara 	unsigned int partnum;
10969d75671SJan Kara 	unsigned int offset;
11069d75671SJan Kara 
11169d75671SJan Kara 	if (!UDF_SB(sb)->s_lvid_bh)
11269d75671SJan Kara 		return NULL;
11369d75671SJan Kara 	lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data;
11469d75671SJan Kara 	partnum = le32_to_cpu(lvid->numOfPartitions);
11569d75671SJan Kara 	/* The offset is to skip freeSpaceTable and sizeTable arrays */
11669d75671SJan Kara 	offset = partnum * 2 * sizeof(uint32_t);
117781d2a9aSJan Kara 	return (struct logicalVolIntegrityDescImpUse *)
118781d2a9aSJan Kara 					(((uint8_t *)(lvid + 1)) + offset);
1196c79e987SMarcin Slusarz }
1206c79e987SMarcin Slusarz 
1211da177e4SLinus Torvalds /* UDF filesystem type */
udf_mount(struct file_system_type * fs_type,int flags,const char * dev_name,void * data)122152a0836SAl Viro static struct dentry *udf_mount(struct file_system_type *fs_type,
123152a0836SAl Viro 		      int flags, const char *dev_name, void *data)
1241da177e4SLinus Torvalds {
125152a0836SAl Viro 	return mount_bdev(fs_type, flags, dev_name, data, udf_fill_super);
1261da177e4SLinus Torvalds }
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds static struct file_system_type udf_fstype = {
1291da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
1301da177e4SLinus Torvalds 	.name		= "udf",
131152a0836SAl Viro 	.mount		= udf_mount,
1321da177e4SLinus Torvalds 	.kill_sb	= kill_block_super,
1331da177e4SLinus Torvalds 	.fs_flags	= FS_REQUIRES_DEV,
1341da177e4SLinus Torvalds };
1353e64fe5bSEric W. Biederman MODULE_ALIAS_FS("udf");
1361da177e4SLinus Torvalds 
137e18b890bSChristoph Lameter static struct kmem_cache *udf_inode_cachep;
1381da177e4SLinus Torvalds 
udf_alloc_inode(struct super_block * sb)1391da177e4SLinus Torvalds static struct inode *udf_alloc_inode(struct super_block *sb)
1401da177e4SLinus Torvalds {
1411da177e4SLinus Torvalds 	struct udf_inode_info *ei;
142fd60b288SMuchun Song 	ei = alloc_inode_sb(sb, udf_inode_cachep, GFP_KERNEL);
1431da177e4SLinus Torvalds 	if (!ei)
1441da177e4SLinus Torvalds 		return NULL;
14595f8797fSDan Bastone 
14695f8797fSDan Bastone 	ei->i_unique = 0;
14795f8797fSDan Bastone 	ei->i_lenExtents = 0;
148ab9a3a73SSteven J. Magnani 	ei->i_lenStreams = 0;
14995f8797fSDan Bastone 	ei->i_next_alloc_block = 0;
15095f8797fSDan Bastone 	ei->i_next_alloc_goal = 0;
15195f8797fSDan Bastone 	ei->i_strat4096 = 0;
152ab9a3a73SSteven J. Magnani 	ei->i_streamdir = 0;
153fc8033a3SJan Kara 	ei->i_hidden = 0;
1544d0fb621SAlessio Igor Bogani 	init_rwsem(&ei->i_data_sem);
15599600051SNamjae Jeon 	ei->cached_extent.lstart = -1;
15699600051SNamjae Jeon 	spin_lock_init(&ei->i_extent_cache_lock);
157a48fc69fSJan Kara 	inode_set_iversion(&ei->vfs_inode, 1);
15895f8797fSDan Bastone 
1591da177e4SLinus Torvalds 	return &ei->vfs_inode;
1601da177e4SLinus Torvalds }
1611da177e4SLinus Torvalds 
udf_free_in_core_inode(struct inode * inode)162a78bb383SAl Viro static void udf_free_in_core_inode(struct inode *inode)
163fa0d7e3dSNick Piggin {
164fa0d7e3dSNick Piggin 	kmem_cache_free(udf_inode_cachep, UDF_I(inode));
165fa0d7e3dSNick Piggin }
166fa0d7e3dSNick Piggin 
init_once(void * foo)16751cc5068SAlexey Dobriyan static void init_once(void *foo)
1681da177e4SLinus Torvalds {
1690dafb7e6SLi zeming 	struct udf_inode_info *ei = foo;
1701da177e4SLinus Torvalds 
171382a2287SJan Kara 	ei->i_data = NULL;
1721da177e4SLinus Torvalds 	inode_init_once(&ei->vfs_inode);
1731da177e4SLinus Torvalds }
1741da177e4SLinus Torvalds 
init_inodecache(void)17553ea18deSFabian Frederick static int __init init_inodecache(void)
1761da177e4SLinus Torvalds {
1771da177e4SLinus Torvalds 	udf_inode_cachep = kmem_cache_create("udf_inode_cache",
1781da177e4SLinus Torvalds 					     sizeof(struct udf_inode_info),
179fffb60f9SPaul Jackson 					     0, (SLAB_RECLAIM_ACCOUNT |
1805d097056SVladimir Davydov 						 SLAB_MEM_SPREAD |
1815d097056SVladimir Davydov 						 SLAB_ACCOUNT),
18220c2df83SPaul Mundt 					     init_once);
18328de7948SCyrill Gorcunov 	if (!udf_inode_cachep)
1841da177e4SLinus Torvalds 		return -ENOMEM;
1851da177e4SLinus Torvalds 	return 0;
1861da177e4SLinus Torvalds }
1871da177e4SLinus Torvalds 
destroy_inodecache(void)1881da177e4SLinus Torvalds static void destroy_inodecache(void)
1891da177e4SLinus Torvalds {
1908c0a8537SKirill A. Shutemov 	/*
1918c0a8537SKirill A. Shutemov 	 * Make sure all delayed rcu free inodes are flushed before we
1928c0a8537SKirill A. Shutemov 	 * destroy cache.
1938c0a8537SKirill A. Shutemov 	 */
1948c0a8537SKirill A. Shutemov 	rcu_barrier();
1951a1d92c1SAlexey Dobriyan 	kmem_cache_destroy(udf_inode_cachep);
1961da177e4SLinus Torvalds }
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds /* Superblock operations */
199ee9b6d61SJosef 'Jeff' Sipek static const struct super_operations udf_sb_ops = {
2001da177e4SLinus Torvalds 	.alloc_inode	= udf_alloc_inode,
201a78bb383SAl Viro 	.free_inode	= udf_free_in_core_inode,
2021da177e4SLinus Torvalds 	.write_inode	= udf_write_inode,
2033aac2b62SAl Viro 	.evict_inode	= udf_evict_inode,
2041da177e4SLinus Torvalds 	.put_super	= udf_put_super,
205146bca72SJan Kara 	.sync_fs	= udf_sync_fs,
2061da177e4SLinus Torvalds 	.statfs		= udf_statfs,
2071da177e4SLinus Torvalds 	.remount_fs	= udf_remount_fs,
2086da80894SMiklos Szeredi 	.show_options	= udf_show_options,
2091da177e4SLinus Torvalds };
2101da177e4SLinus Torvalds 
211cb00ea35SCyrill Gorcunov struct udf_options {
2121da177e4SLinus Torvalds 	unsigned char novrs;
2131da177e4SLinus Torvalds 	unsigned int blocksize;
2141da177e4SLinus Torvalds 	unsigned int session;
2151da177e4SLinus Torvalds 	unsigned int lastblock;
2161da177e4SLinus Torvalds 	unsigned int anchor;
2171da177e4SLinus Torvalds 	unsigned int flags;
218faa17292SAl Viro 	umode_t umask;
219c2ba138aSEric W. Biederman 	kgid_t gid;
220c2ba138aSEric W. Biederman 	kuid_t uid;
221faa17292SAl Viro 	umode_t fmode;
222faa17292SAl Viro 	umode_t dmode;
2231da177e4SLinus Torvalds 	struct nls_table *nls_map;
2241da177e4SLinus Torvalds };
2251da177e4SLinus Torvalds 
init_udf_fs(void)2261da177e4SLinus Torvalds static int __init init_udf_fs(void)
2271da177e4SLinus Torvalds {
2281da177e4SLinus Torvalds 	int err;
22928de7948SCyrill Gorcunov 
2301da177e4SLinus Torvalds 	err = init_inodecache();
2311da177e4SLinus Torvalds 	if (err)
2321da177e4SLinus Torvalds 		goto out1;
2331da177e4SLinus Torvalds 	err = register_filesystem(&udf_fstype);
2341da177e4SLinus Torvalds 	if (err)
2351da177e4SLinus Torvalds 		goto out;
23628de7948SCyrill Gorcunov 
2371da177e4SLinus Torvalds 	return 0;
23828de7948SCyrill Gorcunov 
2391da177e4SLinus Torvalds out:
2401da177e4SLinus Torvalds 	destroy_inodecache();
24128de7948SCyrill Gorcunov 
2421da177e4SLinus Torvalds out1:
2431da177e4SLinus Torvalds 	return err;
2441da177e4SLinus Torvalds }
2451da177e4SLinus Torvalds 
exit_udf_fs(void)2461da177e4SLinus Torvalds static void __exit exit_udf_fs(void)
2471da177e4SLinus Torvalds {
2481da177e4SLinus Torvalds 	unregister_filesystem(&udf_fstype);
2491da177e4SLinus Torvalds 	destroy_inodecache();
2501da177e4SLinus Torvalds }
2511da177e4SLinus Torvalds 
udf_sb_alloc_partition_maps(struct super_block * sb,u32 count)252dc5d39beSMarcin Slusarz static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count)
253dc5d39beSMarcin Slusarz {
254dc5d39beSMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
255dc5d39beSMarcin Slusarz 
256033c9da0SMarkus Elfring 	sbi->s_partmaps = kcalloc(count, sizeof(*sbi->s_partmaps), GFP_KERNEL);
257dc5d39beSMarcin Slusarz 	if (!sbi->s_partmaps) {
258dc5d39beSMarcin Slusarz 		sbi->s_partitions = 0;
259dc5d39beSMarcin Slusarz 		return -ENOMEM;
260dc5d39beSMarcin Slusarz 	}
261dc5d39beSMarcin Slusarz 
262dc5d39beSMarcin Slusarz 	sbi->s_partitions = count;
263dc5d39beSMarcin Slusarz 	return 0;
264dc5d39beSMarcin Slusarz }
265dc5d39beSMarcin Slusarz 
udf_sb_free_bitmap(struct udf_bitmap * bitmap)266bff943afSJan Kara static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
267bff943afSJan Kara {
268bff943afSJan Kara 	int i;
269bff943afSJan Kara 	int nr_groups = bitmap->s_nr_groups;
270bff943afSJan Kara 
271bff943afSJan Kara 	for (i = 0; i < nr_groups; i++)
27257053b3bSJan Kara 		if (!IS_ERR_OR_NULL(bitmap->s_block_bitmap[i]))
273bff943afSJan Kara 			brelse(bitmap->s_block_bitmap[i]);
274bff943afSJan Kara 
2751d5cfdb0STetsuo Handa 	kvfree(bitmap);
276bff943afSJan Kara }
277bff943afSJan Kara 
udf_free_partition(struct udf_part_map * map)278bff943afSJan Kara static void udf_free_partition(struct udf_part_map *map)
279bff943afSJan Kara {
280bff943afSJan Kara 	int i;
281bff943afSJan Kara 	struct udf_meta_data *mdata;
282bff943afSJan Kara 
283bff943afSJan Kara 	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
284bff943afSJan Kara 		iput(map->s_uspace.s_table);
285bff943afSJan Kara 	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
286bff943afSJan Kara 		udf_sb_free_bitmap(map->s_uspace.s_bitmap);
287bff943afSJan Kara 	if (map->s_partition_type == UDF_SPARABLE_MAP15)
288bff943afSJan Kara 		for (i = 0; i < 4; i++)
289bff943afSJan Kara 			brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
290bff943afSJan Kara 	else if (map->s_partition_type == UDF_METADATA_MAP25) {
291bff943afSJan Kara 		mdata = &map->s_type_specific.s_metadata;
292bff943afSJan Kara 		iput(mdata->s_metadata_fe);
293bff943afSJan Kara 		mdata->s_metadata_fe = NULL;
294bff943afSJan Kara 
295bff943afSJan Kara 		iput(mdata->s_mirror_fe);
296bff943afSJan Kara 		mdata->s_mirror_fe = NULL;
297bff943afSJan Kara 
298bff943afSJan Kara 		iput(mdata->s_bitmap_fe);
299bff943afSJan Kara 		mdata->s_bitmap_fe = NULL;
300bff943afSJan Kara 	}
301bff943afSJan Kara }
302bff943afSJan Kara 
udf_sb_free_partitions(struct super_block * sb)303bff943afSJan Kara static void udf_sb_free_partitions(struct super_block *sb)
304bff943afSJan Kara {
305bff943afSJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
306bff943afSJan Kara 	int i;
307ba2eb866SMarkus Elfring 
308ba2eb866SMarkus Elfring 	if (!sbi->s_partmaps)
3091b1baff6SNamjae Jeon 		return;
310bff943afSJan Kara 	for (i = 0; i < sbi->s_partitions; i++)
311bff943afSJan Kara 		udf_free_partition(&sbi->s_partmaps[i]);
312bff943afSJan Kara 	kfree(sbi->s_partmaps);
313bff943afSJan Kara 	sbi->s_partmaps = NULL;
314bff943afSJan Kara }
315bff943afSJan Kara 
udf_show_options(struct seq_file * seq,struct dentry * root)31634c80b1dSAl Viro static int udf_show_options(struct seq_file *seq, struct dentry *root)
3176da80894SMiklos Szeredi {
31834c80b1dSAl Viro 	struct super_block *sb = root->d_sb;
3196da80894SMiklos Szeredi 	struct udf_sb_info *sbi = UDF_SB(sb);
3206da80894SMiklos Szeredi 
3216da80894SMiklos Szeredi 	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT))
3226da80894SMiklos Szeredi 		seq_puts(seq, ",nostrict");
3231197e4dfSClemens Ladisch 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET))
3246da80894SMiklos Szeredi 		seq_printf(seq, ",bs=%lu", sb->s_blocksize);
3256da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE))
3266da80894SMiklos Szeredi 		seq_puts(seq, ",unhide");
3276da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE))
3286da80894SMiklos Szeredi 		seq_puts(seq, ",undelete");
3296da80894SMiklos Szeredi 	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_USE_AD_IN_ICB))
3306da80894SMiklos Szeredi 		seq_puts(seq, ",noadinicb");
3316da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_USE_SHORT_AD))
3326da80894SMiklos Szeredi 		seq_puts(seq, ",shortad");
3336da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_FORGET))
3346da80894SMiklos Szeredi 		seq_puts(seq, ",uid=forget");
3356da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_FORGET))
3366da80894SMiklos Szeredi 		seq_puts(seq, ",gid=forget");
3376da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET))
338c2ba138aSEric W. Biederman 		seq_printf(seq, ",uid=%u", from_kuid(&init_user_ns, sbi->s_uid));
3396da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
340c2ba138aSEric W. Biederman 		seq_printf(seq, ",gid=%u", from_kgid(&init_user_ns, sbi->s_gid));
3416da80894SMiklos Szeredi 	if (sbi->s_umask != 0)
342faa17292SAl Viro 		seq_printf(seq, ",umask=%ho", sbi->s_umask);
34387bc730cSMarcin Slusarz 	if (sbi->s_fmode != UDF_INVALID_MODE)
344faa17292SAl Viro 		seq_printf(seq, ",mode=%ho", sbi->s_fmode);
34587bc730cSMarcin Slusarz 	if (sbi->s_dmode != UDF_INVALID_MODE)
346faa17292SAl Viro 		seq_printf(seq, ",dmode=%ho", sbi->s_dmode);
3476da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
348fcbf7637SSteve Magnani 		seq_printf(seq, ",session=%d", sbi->s_session);
3496da80894SMiklos Szeredi 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
3506da80894SMiklos Szeredi 		seq_printf(seq, ",lastblock=%u", sbi->s_last_block);
35140346005SJan Kara 	if (sbi->s_anchor != 0)
35240346005SJan Kara 		seq_printf(seq, ",anchor=%u", sbi->s_anchor);
353b6453334SPali Rohár 	if (sbi->s_nls_map)
3546da80894SMiklos Szeredi 		seq_printf(seq, ",iocharset=%s", sbi->s_nls_map->charset);
355b6453334SPali Rohár 	else
356b6453334SPali Rohár 		seq_puts(seq, ",iocharset=utf8");
3576da80894SMiklos Szeredi 
3586da80894SMiklos Szeredi 	return 0;
3596da80894SMiklos Szeredi }
3606da80894SMiklos Szeredi 
3611da177e4SLinus Torvalds /*
3621da177e4SLinus Torvalds  * udf_parse_options
3631da177e4SLinus Torvalds  *
3641da177e4SLinus Torvalds  * PURPOSE
3651da177e4SLinus Torvalds  *	Parse mount options.
3661da177e4SLinus Torvalds  *
3671da177e4SLinus Torvalds  * DESCRIPTION
3681da177e4SLinus Torvalds  *	The following mount options are supported:
3691da177e4SLinus Torvalds  *
3701da177e4SLinus Torvalds  *	gid=		Set the default group.
3711da177e4SLinus Torvalds  *	umask=		Set the default umask.
3727ac9bcd5SMarcin Slusarz  *	mode=		Set the default file permissions.
3737ac9bcd5SMarcin Slusarz  *	dmode=		Set the default directory permissions.
3741da177e4SLinus Torvalds  *	uid=		Set the default user.
3751da177e4SLinus Torvalds  *	bs=		Set the block size.
3761da177e4SLinus Torvalds  *	unhide		Show otherwise hidden files.
3771da177e4SLinus Torvalds  *	undelete	Show deleted files in lists.
3781da177e4SLinus Torvalds  *	adinicb		Embed data in the inode (default)
3791da177e4SLinus Torvalds  *	noadinicb	Don't embed data in the inode
3801da177e4SLinus Torvalds  *	shortad		Use short ad's
3811da177e4SLinus Torvalds  *	longad		Use long ad's (default)
3821da177e4SLinus Torvalds  *	nostrict	Unset strict conformance
3831da177e4SLinus Torvalds  *	iocharset=	Set the NLS character set
3841da177e4SLinus Torvalds  *
3851da177e4SLinus Torvalds  *	The remaining are for debugging and disaster recovery:
3861da177e4SLinus Torvalds  *
3871da177e4SLinus Torvalds  *	novrs		Skip volume sequence recognition
3881da177e4SLinus Torvalds  *
3891da177e4SLinus Torvalds  *	The following expect a offset from 0.
3901da177e4SLinus Torvalds  *
3911da177e4SLinus Torvalds  *	session=	Set the CDROM session (default= last session)
3921da177e4SLinus Torvalds  *	anchor=		Override standard anchor location. (default= 256)
3931da177e4SLinus Torvalds  *	volume=		Override the VolumeDesc location. (unused)
3941da177e4SLinus Torvalds  *	partition=	Override the PartitionDesc location. (unused)
3951da177e4SLinus Torvalds  *	lastblock=	Set the last block of the filesystem/
3961da177e4SLinus Torvalds  *
3971da177e4SLinus Torvalds  *	The following expect a offset from the partition root.
3981da177e4SLinus Torvalds  *
3991da177e4SLinus Torvalds  *	fileset=	Override the fileset block location. (unused)
4001da177e4SLinus Torvalds  *	rootdir=	Override the root directory location. (unused)
4011da177e4SLinus Torvalds  *		WARNING: overriding the rootdir to a non-directory may
4021da177e4SLinus Torvalds  *		yield highly unpredictable results.
4031da177e4SLinus Torvalds  *
4041da177e4SLinus Torvalds  * PRE-CONDITIONS
4051da177e4SLinus Torvalds  *	options		Pointer to mount options string.
4061da177e4SLinus Torvalds  *	uopts		Pointer to mount options variable.
4071da177e4SLinus Torvalds  *
4081da177e4SLinus Torvalds  * POST-CONDITIONS
4091da177e4SLinus Torvalds  *	<return>	1	Mount options parsed okay.
4101da177e4SLinus Torvalds  *	<return>	0	Error parsing mount options.
4111da177e4SLinus Torvalds  *
4121da177e4SLinus Torvalds  * HISTORY
4131da177e4SLinus Torvalds  *	July 1, 1997 - Andrew E. Mileski
4141da177e4SLinus Torvalds  *	Written, tested, and released.
4151da177e4SLinus Torvalds  */
41628de7948SCyrill Gorcunov 
4171da177e4SLinus Torvalds enum {
4181da177e4SLinus Torvalds 	Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
4191da177e4SLinus Torvalds 	Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
4201da177e4SLinus Torvalds 	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
4211da177e4SLinus Torvalds 	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
4221da177e4SLinus Torvalds 	Opt_rootdir, Opt_utf8, Opt_iocharset,
4237ac9bcd5SMarcin Slusarz 	Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore,
4247ac9bcd5SMarcin Slusarz 	Opt_fmode, Opt_dmode
4251da177e4SLinus Torvalds };
4261da177e4SLinus Torvalds 
427a447c093SSteven Whitehouse static const match_table_t tokens = {
4281da177e4SLinus Torvalds 	{Opt_novrs,	"novrs"},
4291da177e4SLinus Torvalds 	{Opt_nostrict,	"nostrict"},
4301da177e4SLinus Torvalds 	{Opt_bs,	"bs=%u"},
4311da177e4SLinus Torvalds 	{Opt_unhide,	"unhide"},
4321da177e4SLinus Torvalds 	{Opt_undelete,	"undelete"},
4331da177e4SLinus Torvalds 	{Opt_noadinicb,	"noadinicb"},
4341da177e4SLinus Torvalds 	{Opt_adinicb,	"adinicb"},
4351da177e4SLinus Torvalds 	{Opt_shortad,	"shortad"},
4361da177e4SLinus Torvalds 	{Opt_longad,	"longad"},
4374d6660ebSPhillip Susi 	{Opt_uforget,	"uid=forget"},
4384d6660ebSPhillip Susi 	{Opt_uignore,	"uid=ignore"},
4394d6660ebSPhillip Susi 	{Opt_gforget,	"gid=forget"},
4404d6660ebSPhillip Susi 	{Opt_gignore,	"gid=ignore"},
4411da177e4SLinus Torvalds 	{Opt_gid,	"gid=%u"},
4421da177e4SLinus Torvalds 	{Opt_uid,	"uid=%u"},
4431da177e4SLinus Torvalds 	{Opt_umask,	"umask=%o"},
4441da177e4SLinus Torvalds 	{Opt_session,	"session=%u"},
4451da177e4SLinus Torvalds 	{Opt_lastblock,	"lastblock=%u"},
4461da177e4SLinus Torvalds 	{Opt_anchor,	"anchor=%u"},
4471da177e4SLinus Torvalds 	{Opt_volume,	"volume=%u"},
4481da177e4SLinus Torvalds 	{Opt_partition,	"partition=%u"},
4491da177e4SLinus Torvalds 	{Opt_fileset,	"fileset=%u"},
4501da177e4SLinus Torvalds 	{Opt_rootdir,	"rootdir=%u"},
4511da177e4SLinus Torvalds 	{Opt_utf8,	"utf8"},
4521da177e4SLinus Torvalds 	{Opt_iocharset,	"iocharset=%s"},
4537ac9bcd5SMarcin Slusarz 	{Opt_fmode,     "mode=%o"},
4547ac9bcd5SMarcin Slusarz 	{Opt_dmode,     "dmode=%o"},
4551da177e4SLinus Torvalds 	{Opt_err,	NULL}
4561da177e4SLinus Torvalds };
4571da177e4SLinus Torvalds 
udf_parse_options(char * options,struct udf_options * uopt,bool remount)4586da80894SMiklos Szeredi static int udf_parse_options(char *options, struct udf_options *uopt,
4596da80894SMiklos Szeredi 			     bool remount)
4601da177e4SLinus Torvalds {
4611da177e4SLinus Torvalds 	char *p;
4621da177e4SLinus Torvalds 	int option;
4633a9a3aa8SBingJing Chang 	unsigned int uv;
4641da177e4SLinus Torvalds 
4651da177e4SLinus Torvalds 	uopt->novrs = 0;
4661da177e4SLinus Torvalds 	uopt->session = 0xFFFFFFFF;
4671da177e4SLinus Torvalds 	uopt->lastblock = 0;
4681da177e4SLinus Torvalds 	uopt->anchor = 0;
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds 	if (!options)
4711da177e4SLinus Torvalds 		return 1;
4721da177e4SLinus Torvalds 
473cb00ea35SCyrill Gorcunov 	while ((p = strsep(&options, ",")) != NULL) {
4741da177e4SLinus Torvalds 		substring_t args[MAX_OPT_ARGS];
4751da177e4SLinus Torvalds 		int token;
4768c6915aeSFabian Frederick 		unsigned n;
4771da177e4SLinus Torvalds 		if (!*p)
4781da177e4SLinus Torvalds 			continue;
4791da177e4SLinus Torvalds 
4801da177e4SLinus Torvalds 		token = match_token(p, tokens, args);
481cb00ea35SCyrill Gorcunov 		switch (token) {
4821da177e4SLinus Torvalds 		case Opt_novrs:
4831da177e4SLinus Torvalds 			uopt->novrs = 1;
4844136801aSClemens Ladisch 			break;
4851da177e4SLinus Torvalds 		case Opt_bs:
4861da177e4SLinus Torvalds 			if (match_int(&args[0], &option))
4871da177e4SLinus Torvalds 				return 0;
4888c6915aeSFabian Frederick 			n = option;
4898c6915aeSFabian Frederick 			if (n != 512 && n != 1024 && n != 2048 && n != 4096)
4908c6915aeSFabian Frederick 				return 0;
4918c6915aeSFabian Frederick 			uopt->blocksize = n;
4921197e4dfSClemens Ladisch 			uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET);
4931da177e4SLinus Torvalds 			break;
4941da177e4SLinus Torvalds 		case Opt_unhide:
4951da177e4SLinus Torvalds 			uopt->flags |= (1 << UDF_FLAG_UNHIDE);
4961da177e4SLinus Torvalds 			break;
4971da177e4SLinus Torvalds 		case Opt_undelete:
4981da177e4SLinus Torvalds 			uopt->flags |= (1 << UDF_FLAG_UNDELETE);
4991da177e4SLinus Torvalds 			break;
5001da177e4SLinus Torvalds 		case Opt_noadinicb:
5011da177e4SLinus Torvalds 			uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
5021da177e4SLinus Torvalds 			break;
5031da177e4SLinus Torvalds 		case Opt_adinicb:
5041da177e4SLinus Torvalds 			uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
5051da177e4SLinus Torvalds 			break;
5061da177e4SLinus Torvalds 		case Opt_shortad:
5071da177e4SLinus Torvalds 			uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
5081da177e4SLinus Torvalds 			break;
5091da177e4SLinus Torvalds 		case Opt_longad:
5101da177e4SLinus Torvalds 			uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
5111da177e4SLinus Torvalds 			break;
5121da177e4SLinus Torvalds 		case Opt_gid:
5133a9a3aa8SBingJing Chang 			if (match_uint(args, &uv))
5141da177e4SLinus Torvalds 				return 0;
5153a9a3aa8SBingJing Chang 			uopt->gid = make_kgid(current_user_ns(), uv);
516c2ba138aSEric W. Biederman 			if (!gid_valid(uopt->gid))
517c2ba138aSEric W. Biederman 				return 0;
518ca76d2d8SCyrill Gorcunov 			uopt->flags |= (1 << UDF_FLAG_GID_SET);
5191da177e4SLinus Torvalds 			break;
5201da177e4SLinus Torvalds 		case Opt_uid:
5213a9a3aa8SBingJing Chang 			if (match_uint(args, &uv))
5221da177e4SLinus Torvalds 				return 0;
5233a9a3aa8SBingJing Chang 			uopt->uid = make_kuid(current_user_ns(), uv);
524c2ba138aSEric W. Biederman 			if (!uid_valid(uopt->uid))
525c2ba138aSEric W. Biederman 				return 0;
526ca76d2d8SCyrill Gorcunov 			uopt->flags |= (1 << UDF_FLAG_UID_SET);
5271da177e4SLinus Torvalds 			break;
5281da177e4SLinus Torvalds 		case Opt_umask:
5291da177e4SLinus Torvalds 			if (match_octal(args, &option))
5301da177e4SLinus Torvalds 				return 0;
5311da177e4SLinus Torvalds 			uopt->umask = option;
5321da177e4SLinus Torvalds 			break;
5331da177e4SLinus Torvalds 		case Opt_nostrict:
5341da177e4SLinus Torvalds 			uopt->flags &= ~(1 << UDF_FLAG_STRICT);
5351da177e4SLinus Torvalds 			break;
5361da177e4SLinus Torvalds 		case Opt_session:
5371da177e4SLinus Torvalds 			if (match_int(args, &option))
5381da177e4SLinus Torvalds 				return 0;
5391da177e4SLinus Torvalds 			uopt->session = option;
5406da80894SMiklos Szeredi 			if (!remount)
5416da80894SMiklos Szeredi 				uopt->flags |= (1 << UDF_FLAG_SESSION_SET);
5421da177e4SLinus Torvalds 			break;
5431da177e4SLinus Torvalds 		case Opt_lastblock:
5441da177e4SLinus Torvalds 			if (match_int(args, &option))
5451da177e4SLinus Torvalds 				return 0;
5461da177e4SLinus Torvalds 			uopt->lastblock = option;
5476da80894SMiklos Szeredi 			if (!remount)
5486da80894SMiklos Szeredi 				uopt->flags |= (1 << UDF_FLAG_LASTBLOCK_SET);
5491da177e4SLinus Torvalds 			break;
5501da177e4SLinus Torvalds 		case Opt_anchor:
5511da177e4SLinus Torvalds 			if (match_int(args, &option))
5521da177e4SLinus Torvalds 				return 0;
5531da177e4SLinus Torvalds 			uopt->anchor = option;
5541da177e4SLinus Torvalds 			break;
5551da177e4SLinus Torvalds 		case Opt_volume:
5561da177e4SLinus Torvalds 		case Opt_partition:
5571da177e4SLinus Torvalds 		case Opt_fileset:
5581da177e4SLinus Torvalds 		case Opt_rootdir:
559f0c4a817SJan Kara 			/* Ignored (never implemented properly) */
5601da177e4SLinus Torvalds 			break;
5611da177e4SLinus Torvalds 		case Opt_utf8:
562b6453334SPali Rohár 			if (!remount) {
563b6453334SPali Rohár 				unload_nls(uopt->nls_map);
564b6453334SPali Rohár 				uopt->nls_map = NULL;
565b6453334SPali Rohár 			}
5661da177e4SLinus Torvalds 			break;
5671da177e4SLinus Torvalds 		case Opt_iocharset:
568785dffe1SChengguang Xu 			if (!remount) {
569785dffe1SChengguang Xu 				unload_nls(uopt->nls_map);
570b6453334SPali Rohár 				uopt->nls_map = NULL;
571b6453334SPali Rohár 			}
572b6453334SPali Rohár 			/* When nls_map is not loaded then UTF-8 is used */
573b6453334SPali Rohár 			if (!remount && strcmp(args[0].from, "utf8") != 0) {
5741da177e4SLinus Torvalds 				uopt->nls_map = load_nls(args[0].from);
575b6453334SPali Rohár 				if (!uopt->nls_map) {
576b6453334SPali Rohár 					pr_err("iocharset %s not found\n",
577b6453334SPali Rohár 						args[0].from);
578b6453334SPali Rohár 					return 0;
579b6453334SPali Rohár 				}
580785dffe1SChengguang Xu 			}
5811da177e4SLinus Torvalds 			break;
5824d6660ebSPhillip Susi 		case Opt_uforget:
5834d6660ebSPhillip Susi 			uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
5844d6660ebSPhillip Susi 			break;
58570260e44SJan Kara 		case Opt_uignore:
5864d6660ebSPhillip Susi 		case Opt_gignore:
58770260e44SJan Kara 			/* These options are superseeded by uid=<number> */
5884d6660ebSPhillip Susi 			break;
5894d6660ebSPhillip Susi 		case Opt_gforget:
5904d6660ebSPhillip Susi 			uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
5914d6660ebSPhillip Susi 			break;
5927ac9bcd5SMarcin Slusarz 		case Opt_fmode:
5937ac9bcd5SMarcin Slusarz 			if (match_octal(args, &option))
5947ac9bcd5SMarcin Slusarz 				return 0;
5957ac9bcd5SMarcin Slusarz 			uopt->fmode = option & 0777;
5967ac9bcd5SMarcin Slusarz 			break;
5977ac9bcd5SMarcin Slusarz 		case Opt_dmode:
5987ac9bcd5SMarcin Slusarz 			if (match_octal(args, &option))
5997ac9bcd5SMarcin Slusarz 				return 0;
6007ac9bcd5SMarcin Slusarz 			uopt->dmode = option & 0777;
6017ac9bcd5SMarcin Slusarz 			break;
6021da177e4SLinus Torvalds 		default:
60378ace70cSJoe Perches 			pr_err("bad mount option \"%s\" or missing value\n", p);
6041da177e4SLinus Torvalds 			return 0;
6051da177e4SLinus Torvalds 		}
6061da177e4SLinus Torvalds 	}
6071da177e4SLinus Torvalds 	return 1;
6081da177e4SLinus Torvalds }
6091da177e4SLinus Torvalds 
udf_remount_fs(struct super_block * sb,int * flags,char * options)610cb00ea35SCyrill Gorcunov static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
6111da177e4SLinus Torvalds {
6121da177e4SLinus Torvalds 	struct udf_options uopt;
6136c79e987SMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
614c79d967dSChristoph Hellwig 	int error = 0;
615a9ad01bcSJan Kara 
616a9ad01bcSJan Kara 	if (!(*flags & SB_RDONLY) && UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
617a9ad01bcSJan Kara 		return -EACCES;
6181da177e4SLinus Torvalds 
61902b9984dSTheodore Ts'o 	sync_filesystem(sb);
620e729eac6SJan Kara 
6216c79e987SMarcin Slusarz 	uopt.flags = sbi->s_flags;
6226c79e987SMarcin Slusarz 	uopt.uid   = sbi->s_uid;
6236c79e987SMarcin Slusarz 	uopt.gid   = sbi->s_gid;
6246c79e987SMarcin Slusarz 	uopt.umask = sbi->s_umask;
6257ac9bcd5SMarcin Slusarz 	uopt.fmode = sbi->s_fmode;
6267ac9bcd5SMarcin Slusarz 	uopt.dmode = sbi->s_dmode;
627785dffe1SChengguang Xu 	uopt.nls_map = NULL;
6281da177e4SLinus Torvalds 
6296da80894SMiklos Szeredi 	if (!udf_parse_options(options, &uopt, true))
6301da177e4SLinus Torvalds 		return -EINVAL;
6311da177e4SLinus Torvalds 
632c03cad24SJan Kara 	write_lock(&sbi->s_cred_lock);
6336c79e987SMarcin Slusarz 	sbi->s_flags = uopt.flags;
6346c79e987SMarcin Slusarz 	sbi->s_uid   = uopt.uid;
6356c79e987SMarcin Slusarz 	sbi->s_gid   = uopt.gid;
6366c79e987SMarcin Slusarz 	sbi->s_umask = uopt.umask;
6377ac9bcd5SMarcin Slusarz 	sbi->s_fmode = uopt.fmode;
6387ac9bcd5SMarcin Slusarz 	sbi->s_dmode = uopt.dmode;
639c03cad24SJan Kara 	write_unlock(&sbi->s_cred_lock);
6401da177e4SLinus Torvalds 
6411751e8a6SLinus Torvalds 	if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
642c79d967dSChristoph Hellwig 		goto out_unlock;
643c79d967dSChristoph Hellwig 
6441751e8a6SLinus Torvalds 	if (*flags & SB_RDONLY)
6451da177e4SLinus Torvalds 		udf_close_lvid(sb);
64636350462SJan Kara 	else
6471da177e4SLinus Torvalds 		udf_open_lvid(sb);
6481da177e4SLinus Torvalds 
649c79d967dSChristoph Hellwig out_unlock:
650c79d967dSChristoph Hellwig 	return error;
6511da177e4SLinus Torvalds }
6521da177e4SLinus Torvalds 
653ba54aef0SSteven J. Magnani /*
654ba54aef0SSteven J. Magnani  * Check VSD descriptor. Returns -1 in case we are at the end of volume
655ba54aef0SSteven J. Magnani  * recognition area, 0 if the descriptor is valid but non-interesting, 1 if
656ba54aef0SSteven J. Magnani  * we found one of NSR descriptors we are looking for.
657ba54aef0SSteven J. Magnani  */
identify_vsd(const struct volStructDesc * vsd)658ba54aef0SSteven J. Magnani static int identify_vsd(const struct volStructDesc *vsd)
659ba54aef0SSteven J. Magnani {
660ba54aef0SSteven J. Magnani 	int ret = 0;
661ba54aef0SSteven J. Magnani 
662ba54aef0SSteven J. Magnani 	if (!memcmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {
663ba54aef0SSteven J. Magnani 		switch (vsd->structType) {
664ba54aef0SSteven J. Magnani 		case 0:
665ba54aef0SSteven J. Magnani 			udf_debug("ISO9660 Boot Record found\n");
666ba54aef0SSteven J. Magnani 			break;
667ba54aef0SSteven J. Magnani 		case 1:
668ba54aef0SSteven J. Magnani 			udf_debug("ISO9660 Primary Volume Descriptor found\n");
669ba54aef0SSteven J. Magnani 			break;
670ba54aef0SSteven J. Magnani 		case 2:
671ba54aef0SSteven J. Magnani 			udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
672ba54aef0SSteven J. Magnani 			break;
673ba54aef0SSteven J. Magnani 		case 3:
674ba54aef0SSteven J. Magnani 			udf_debug("ISO9660 Volume Partition Descriptor found\n");
675ba54aef0SSteven J. Magnani 			break;
676ba54aef0SSteven J. Magnani 		case 255:
677ba54aef0SSteven J. Magnani 			udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
678ba54aef0SSteven J. Magnani 			break;
679ba54aef0SSteven J. Magnani 		default:
680ba54aef0SSteven J. Magnani 			udf_debug("ISO9660 VRS (%u) found\n", vsd->structType);
681ba54aef0SSteven J. Magnani 			break;
682ba54aef0SSteven J. Magnani 		}
683ba54aef0SSteven J. Magnani 	} else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
684ba54aef0SSteven J. Magnani 		; /* ret = 0 */
685ba54aef0SSteven J. Magnani 	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
686ba54aef0SSteven J. Magnani 		ret = 1;
687ba54aef0SSteven J. Magnani 	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
688ba54aef0SSteven J. Magnani 		ret = 1;
689ba54aef0SSteven J. Magnani 	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BOOT2, VSD_STD_ID_LEN))
690ba54aef0SSteven J. Magnani 		; /* ret = 0 */
691ba54aef0SSteven J. Magnani 	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_CDW02, VSD_STD_ID_LEN))
692ba54aef0SSteven J. Magnani 		; /* ret = 0 */
693ba54aef0SSteven J. Magnani 	else {
694ba54aef0SSteven J. Magnani 		/* TEA01 or invalid id : end of volume recognition area */
695ba54aef0SSteven J. Magnani 		ret = -1;
696ba54aef0SSteven J. Magnani 	}
697ba54aef0SSteven J. Magnani 
698ba54aef0SSteven J. Magnani 	return ret;
699ba54aef0SSteven J. Magnani }
700ba54aef0SSteven J. Magnani 
701ba54aef0SSteven J. Magnani /*
702ba54aef0SSteven J. Magnani  * Check Volume Structure Descriptors (ECMA 167 2/9.1)
703ba54aef0SSteven J. Magnani  * We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1)
704ba54aef0SSteven J. Magnani  * @return   1 if NSR02 or NSR03 found,
705ba54aef0SSteven J. Magnani  *	    -1 if first sector read error, 0 otherwise
706ba54aef0SSteven J. Magnani  */
udf_check_vsd(struct super_block * sb)707ba54aef0SSteven J. Magnani static int udf_check_vsd(struct super_block *sb)
7081da177e4SLinus Torvalds {
7091da177e4SLinus Torvalds 	struct volStructDesc *vsd = NULL;
71044499602SPeter A. Felvegi 	loff_t sector = VSD_FIRST_SECTOR_OFFSET;
7111da177e4SLinus Torvalds 	int sectorsize;
7121da177e4SLinus Torvalds 	struct buffer_head *bh = NULL;
713ba54aef0SSteven J. Magnani 	int nsr = 0;
7146c79e987SMarcin Slusarz 	struct udf_sb_info *sbi;
7155cdc4a69Slianzhi chang 	loff_t session_offset;
7161da177e4SLinus Torvalds 
7176c79e987SMarcin Slusarz 	sbi = UDF_SB(sb);
7181da177e4SLinus Torvalds 	if (sb->s_blocksize < sizeof(struct volStructDesc))
7191da177e4SLinus Torvalds 		sectorsize = sizeof(struct volStructDesc);
7201da177e4SLinus Torvalds 	else
7211da177e4SLinus Torvalds 		sectorsize = sb->s_blocksize;
7221da177e4SLinus Torvalds 
7235cdc4a69Slianzhi chang 	session_offset = (loff_t)sbi->s_session << sb->s_blocksize_bits;
7245cdc4a69Slianzhi chang 	sector += session_offset;
7251da177e4SLinus Torvalds 
726fcbf7637SSteve Magnani 	udf_debug("Starting at sector %u (%lu byte sectors)\n",
727706047a7SSebastian Manciulea 		  (unsigned int)(sector >> sb->s_blocksize_bits),
728706047a7SSebastian Manciulea 		  sb->s_blocksize);
72944499602SPeter A. Felvegi 	/* Process the sequence (if applicable). The hard limit on the sector
73044499602SPeter A. Felvegi 	 * offset is arbitrary, hopefully large enough so that all valid UDF
73144499602SPeter A. Felvegi 	 * filesystems will be recognised. There is no mention of an upper
73244499602SPeter A. Felvegi 	 * bound to the size of the volume recognition area in the standard.
73344499602SPeter A. Felvegi 	 *  The limit will prevent the code to read all the sectors of a
73444499602SPeter A. Felvegi 	 * specially crafted image (like a bluray disc full of CD001 sectors),
73544499602SPeter A. Felvegi 	 * potentially causing minutes or even hours of uninterruptible I/O
73644499602SPeter A. Felvegi 	 * activity. This actually happened with uninitialised SSD partitions
73744499602SPeter A. Felvegi 	 * (all 0xFF) before the check for the limit and all valid IDs were
73844499602SPeter A. Felvegi 	 * added */
739ba54aef0SSteven J. Magnani 	for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) {
7401da177e4SLinus Torvalds 		/* Read a block */
741101ee137SJan Kara 		bh = sb_bread(sb, sector >> sb->s_blocksize_bits);
7421da177e4SLinus Torvalds 		if (!bh)
7431da177e4SLinus Torvalds 			break;
7441da177e4SLinus Torvalds 
7451da177e4SLinus Torvalds 		vsd = (struct volStructDesc *)(bh->b_data +
74628de7948SCyrill Gorcunov 					      (sector & (sb->s_blocksize - 1)));
747ba54aef0SSteven J. Magnani 		nsr = identify_vsd(vsd);
7486fbacb85SSteven J. Magnani 		/* Found NSR or end? */
7496fbacb85SSteven J. Magnani 		if (nsr) {
7506fbacb85SSteven J. Magnani 			brelse(bh);
7516fbacb85SSteven J. Magnani 			break;
7526fbacb85SSteven J. Magnani 		}
7536fbacb85SSteven J. Magnani 		/*
7546fbacb85SSteven J. Magnani 		 * Special handling for improperly formatted VRS (e.g., Win10)
7556fbacb85SSteven J. Magnani 		 * where components are separated by 2048 bytes even though
7566fbacb85SSteven J. Magnani 		 * sectors are 4K
7576fbacb85SSteven J. Magnani 		 */
7586fbacb85SSteven J. Magnani 		if (sb->s_blocksize == 4096) {
7596fbacb85SSteven J. Magnani 			nsr = identify_vsd(vsd + 1);
7606fbacb85SSteven J. Magnani 			/* Ignore unknown IDs... */
7616fbacb85SSteven J. Magnani 			if (nsr < 0)
7626fbacb85SSteven J. Magnani 				nsr = 0;
7636fbacb85SSteven J. Magnani 		}
7643bf25cb4SJan Kara 		brelse(bh);
7651da177e4SLinus Torvalds 	}
7661da177e4SLinus Torvalds 
767ba54aef0SSteven J. Magnani 	if (nsr > 0)
768ba54aef0SSteven J. Magnani 		return 1;
7695cdc4a69Slianzhi chang 	else if (!bh && sector - session_offset == VSD_FIRST_SECTOR_OFFSET)
7701da177e4SLinus Torvalds 		return -1;
7711da177e4SLinus Torvalds 	else
7721da177e4SLinus Torvalds 		return 0;
7731da177e4SLinus Torvalds }
7741da177e4SLinus Torvalds 
udf_verify_domain_identifier(struct super_block * sb,struct regid * ident,char * dname)7758b47ea6cSJan Kara static int udf_verify_domain_identifier(struct super_block *sb,
7768b47ea6cSJan Kara 					struct regid *ident, char *dname)
7778b47ea6cSJan Kara {
778871b9b14SPali Rohár 	struct domainIdentSuffix *suffix;
7798b47ea6cSJan Kara 
7808b47ea6cSJan Kara 	if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) {
7818b47ea6cSJan Kara 		udf_warn(sb, "Not OSTA UDF compliant %s descriptor.\n", dname);
7828b47ea6cSJan Kara 		goto force_ro;
7838b47ea6cSJan Kara 	}
78449be68c4SPali Rohár 	if (ident->flags & ENTITYID_FLAGS_DIRTY) {
7858b47ea6cSJan Kara 		udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor.\n",
7868b47ea6cSJan Kara 			 dname);
7878b47ea6cSJan Kara 		goto force_ro;
7888b47ea6cSJan Kara 	}
789871b9b14SPali Rohár 	suffix = (struct domainIdentSuffix *)ident->identSuffix;
790871b9b14SPali Rohár 	if ((suffix->domainFlags & DOMAIN_FLAGS_HARD_WRITE_PROTECT) ||
791871b9b14SPali Rohár 	    (suffix->domainFlags & DOMAIN_FLAGS_SOFT_WRITE_PROTECT)) {
7928b47ea6cSJan Kara 		if (!sb_rdonly(sb)) {
7938b47ea6cSJan Kara 			udf_warn(sb, "Descriptor for %s marked write protected."
7948b47ea6cSJan Kara 				 " Forcing read only mount.\n", dname);
7958b47ea6cSJan Kara 		}
7968b47ea6cSJan Kara 		goto force_ro;
7978b47ea6cSJan Kara 	}
7988b47ea6cSJan Kara 	return 0;
7998b47ea6cSJan Kara 
8008b47ea6cSJan Kara force_ro:
8018b47ea6cSJan Kara 	if (!sb_rdonly(sb))
8028b47ea6cSJan Kara 		return -EACCES;
8038b47ea6cSJan Kara 	UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
8048b47ea6cSJan Kara 	return 0;
8058b47ea6cSJan Kara }
8068b47ea6cSJan Kara 
udf_load_fileset(struct super_block * sb,struct fileSetDesc * fset,struct kernel_lb_addr * root)8078b47ea6cSJan Kara static int udf_load_fileset(struct super_block *sb, struct fileSetDesc *fset,
8088b47ea6cSJan Kara 			    struct kernel_lb_addr *root)
8098b47ea6cSJan Kara {
8108b47ea6cSJan Kara 	int ret;
8118b47ea6cSJan Kara 
8128b47ea6cSJan Kara 	ret = udf_verify_domain_identifier(sb, &fset->domainIdent, "file set");
8138b47ea6cSJan Kara 	if (ret < 0)
8148b47ea6cSJan Kara 		return ret;
8158b47ea6cSJan Kara 
8168b47ea6cSJan Kara 	*root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
8178b47ea6cSJan Kara 	UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum);
8188b47ea6cSJan Kara 
8198b47ea6cSJan Kara 	udf_debug("Rootdir at block=%u, partition=%u\n",
8208b47ea6cSJan Kara 		  root->logicalBlockNum, root->partitionReferenceNum);
8218b47ea6cSJan Kara 	return 0;
8228b47ea6cSJan Kara }
8238b47ea6cSJan Kara 
udf_find_fileset(struct super_block * sb,struct kernel_lb_addr * fileset,struct kernel_lb_addr * root)8243a71fc5dSMarcin Slusarz static int udf_find_fileset(struct super_block *sb,
8255ca4e4beSPekka Enberg 			    struct kernel_lb_addr *fileset,
8265ca4e4beSPekka Enberg 			    struct kernel_lb_addr *root)
8271da177e4SLinus Torvalds {
8280dafb7e6SLi zeming 	struct buffer_head *bh;
8291da177e4SLinus Torvalds 	uint16_t ident;
8302dee5aacSJan Kara 	int ret;
8311da177e4SLinus Torvalds 
8322dee5aacSJan Kara 	if (fileset->logicalBlockNum == 0xFFFFFFFF &&
8332dee5aacSJan Kara 	    fileset->partitionReferenceNum == 0xFFFF)
8342dee5aacSJan Kara 		return -EINVAL;
8352dee5aacSJan Kara 
83697e961fdSPekka Enberg 	bh = udf_read_ptagged(sb, fileset, 0, &ident);
8372dee5aacSJan Kara 	if (!bh)
8382dee5aacSJan Kara 		return -EIO;
8392dee5aacSJan Kara 	if (ident != TAG_IDENT_FSD) {
8403bf25cb4SJan Kara 		brelse(bh);
8412dee5aacSJan Kara 		return -EINVAL;
8421da177e4SLinus Torvalds 	}
8431da177e4SLinus Torvalds 
844fcbf7637SSteve Magnani 	udf_debug("Fileset at block=%u, partition=%u\n",
8452dee5aacSJan Kara 		  fileset->logicalBlockNum, fileset->partitionReferenceNum);
8461da177e4SLinus Torvalds 
84782c82ab6SJan Kara 	UDF_SB(sb)->s_partition = fileset->partitionReferenceNum;
8482dee5aacSJan Kara 	ret = udf_load_fileset(sb, (struct fileSetDesc *)bh->b_data, root);
8493bf25cb4SJan Kara 	brelse(bh);
8502dee5aacSJan Kara 	return ret;
8511da177e4SLinus Torvalds }
8521da177e4SLinus Torvalds 
853d759bfa4SJan Kara /*
854d759bfa4SJan Kara  * Load primary Volume Descriptor Sequence
855d759bfa4SJan Kara  *
856d759bfa4SJan Kara  * Return <0 on error, 0 on success. -EAGAIN is special meaning next sequence
857d759bfa4SJan Kara  * should be tried.
858d759bfa4SJan Kara  */
udf_load_pvoldesc(struct super_block * sb,sector_t block)859c0eb31edSJan Kara static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
8601da177e4SLinus Torvalds {
8611da177e4SLinus Torvalds 	struct primaryVolDesc *pvoldesc;
8629293fcfbSAndrew Gabbasov 	uint8_t *outstr;
863c0eb31edSJan Kara 	struct buffer_head *bh;
864c0eb31edSJan Kara 	uint16_t ident;
865aa9f6661SJing Xiangfeng 	int ret;
8660220eddaSDeepa Dinamani 	struct timestamp *ts;
867ba9aadd8SMarcin Slusarz 
8689293fcfbSAndrew Gabbasov 	outstr = kmalloc(128, GFP_NOFS);
869ba9aadd8SMarcin Slusarz 	if (!outstr)
8709293fcfbSAndrew Gabbasov 		return -ENOMEM;
871c0eb31edSJan Kara 
872c0eb31edSJan Kara 	bh = udf_read_tagged(sb, block, block, &ident);
873d759bfa4SJan Kara 	if (!bh) {
874d759bfa4SJan Kara 		ret = -EAGAIN;
875ba9aadd8SMarcin Slusarz 		goto out2;
876d759bfa4SJan Kara 	}
877ba9aadd8SMarcin Slusarz 
878d759bfa4SJan Kara 	if (ident != TAG_IDENT_PVD) {
879d759bfa4SJan Kara 		ret = -EIO;
880d759bfa4SJan Kara 		goto out_bh;
881d759bfa4SJan Kara 	}
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds 	pvoldesc = (struct primaryVolDesc *)bh->b_data;
8841da177e4SLinus Torvalds 
8850220eddaSDeepa Dinamani 	udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
8860220eddaSDeepa Dinamani 			      pvoldesc->recordingDateAndTime);
8870220eddaSDeepa Dinamani 	ts = &pvoldesc->recordingDateAndTime;
888a983f368SJoe Perches 	udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n",
889af15a298SMarcin Slusarz 		  le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
890af15a298SMarcin Slusarz 		  ts->minute, le16_to_cpu(ts->typeAndTimezone));
8911da177e4SLinus Torvalds 
892e966fc8dSJan Kara 	ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32);
893b54e41f5SJan Kara 	if (ret < 0) {
894b54e41f5SJan Kara 		strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName");
895b54e41f5SJan Kara 		pr_warn("incorrect volume identification, setting to "
896b54e41f5SJan Kara 			"'InvalidName'\n");
897b54e41f5SJan Kara 	} else {
8989293fcfbSAndrew Gabbasov 		strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
899b54e41f5SJan Kara 	}
900e9d4cf41SFabian Frederick 	udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
9011da177e4SLinus Torvalds 
902e966fc8dSJan Kara 	ret = udf_dstrCS0toChar(sb, outstr, 127, pvoldesc->volSetIdent, 128);
903b54e41f5SJan Kara 	if (ret < 0) {
904b54e41f5SJan Kara 		ret = 0;
905e9d4cf41SFabian Frederick 		goto out_bh;
906b54e41f5SJan Kara 	}
9079293fcfbSAndrew Gabbasov 	outstr[ret] = 0;
9089293fcfbSAndrew Gabbasov 	udf_debug("volSetIdent[] = '%s'\n", outstr);
909c0eb31edSJan Kara 
910ba9aadd8SMarcin Slusarz 	ret = 0;
911d759bfa4SJan Kara out_bh:
912d759bfa4SJan Kara 	brelse(bh);
913ba9aadd8SMarcin Slusarz out2:
914ba9aadd8SMarcin Slusarz 	kfree(outstr);
915ba9aadd8SMarcin Slusarz 	return ret;
9161da177e4SLinus Torvalds }
9171da177e4SLinus Torvalds 
udf_find_metadata_inode_efe(struct super_block * sb,u32 meta_file_loc,u32 partition_ref)9183080a74eSNamjae Jeon struct inode *udf_find_metadata_inode_efe(struct super_block *sb,
9197888824bSAlden Tondettar 					u32 meta_file_loc, u32 partition_ref)
9203080a74eSNamjae Jeon {
9213080a74eSNamjae Jeon 	struct kernel_lb_addr addr;
9223080a74eSNamjae Jeon 	struct inode *metadata_fe;
9233080a74eSNamjae Jeon 
9243080a74eSNamjae Jeon 	addr.logicalBlockNum = meta_file_loc;
9257888824bSAlden Tondettar 	addr.partitionReferenceNum = partition_ref;
9263080a74eSNamjae Jeon 
9276174c2ebSJan Kara 	metadata_fe = udf_iget_special(sb, &addr);
9283080a74eSNamjae Jeon 
9296d3d5e86SJan Kara 	if (IS_ERR(metadata_fe)) {
9303080a74eSNamjae Jeon 		udf_warn(sb, "metadata inode efe not found\n");
9316d3d5e86SJan Kara 		return metadata_fe;
9326d3d5e86SJan Kara 	}
9336d3d5e86SJan Kara 	if (UDF_I(metadata_fe)->i_alloc_type != ICBTAG_FLAG_AD_SHORT) {
9343080a74eSNamjae Jeon 		udf_warn(sb, "metadata inode efe does not have short allocation descriptors!\n");
9353080a74eSNamjae Jeon 		iput(metadata_fe);
9366d3d5e86SJan Kara 		return ERR_PTR(-EIO);
9373080a74eSNamjae Jeon 	}
9383080a74eSNamjae Jeon 
9393080a74eSNamjae Jeon 	return metadata_fe;
9403080a74eSNamjae Jeon }
9413080a74eSNamjae Jeon 
udf_load_metadata_files(struct super_block * sb,int partition,int type1_index)9427888824bSAlden Tondettar static int udf_load_metadata_files(struct super_block *sb, int partition,
9437888824bSAlden Tondettar 				   int type1_index)
944bfb257a5SJan Kara {
945bfb257a5SJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
946bfb257a5SJan Kara 	struct udf_part_map *map;
947bfb257a5SJan Kara 	struct udf_meta_data *mdata;
9485ca4e4beSPekka Enberg 	struct kernel_lb_addr addr;
9496d3d5e86SJan Kara 	struct inode *fe;
950bfb257a5SJan Kara 
951bfb257a5SJan Kara 	map = &sbi->s_partmaps[partition];
952bfb257a5SJan Kara 	mdata = &map->s_type_specific.s_metadata;
9537888824bSAlden Tondettar 	mdata->s_phys_partition_ref = type1_index;
954bfb257a5SJan Kara 
955bfb257a5SJan Kara 	/* metadata address */
956fcbf7637SSteve Magnani 	udf_debug("Metadata file location: block = %u part = %u\n",
9577888824bSAlden Tondettar 		  mdata->s_meta_file_loc, mdata->s_phys_partition_ref);
958bfb257a5SJan Kara 
9596d3d5e86SJan Kara 	fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc,
9607888824bSAlden Tondettar 					 mdata->s_phys_partition_ref);
9616d3d5e86SJan Kara 	if (IS_ERR(fe)) {
962bfb257a5SJan Kara 		/* mirror file entry */
963fcbf7637SSteve Magnani 		udf_debug("Mirror metadata file location: block = %u part = %u\n",
9647888824bSAlden Tondettar 			  mdata->s_mirror_file_loc, mdata->s_phys_partition_ref);
965bfb257a5SJan Kara 
9666d3d5e86SJan Kara 		fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc,
9677888824bSAlden Tondettar 						 mdata->s_phys_partition_ref);
968bfb257a5SJan Kara 
9696d3d5e86SJan Kara 		if (IS_ERR(fe)) {
9703080a74eSNamjae Jeon 			udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n");
9716d3d5e86SJan Kara 			return PTR_ERR(fe);
9723080a74eSNamjae Jeon 		}
9736d3d5e86SJan Kara 		mdata->s_mirror_fe = fe;
9746d3d5e86SJan Kara 	} else
9756d3d5e86SJan Kara 		mdata->s_metadata_fe = fe;
9766d3d5e86SJan Kara 
977bfb257a5SJan Kara 
978bfb257a5SJan Kara 	/*
979bfb257a5SJan Kara 	 * bitmap file entry
980bfb257a5SJan Kara 	 * Note:
981bfb257a5SJan Kara 	 * Load only if bitmap file location differs from 0xFFFFFFFF (DCN-5102)
982bfb257a5SJan Kara 	*/
983bfb257a5SJan Kara 	if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) {
984bfb257a5SJan Kara 		addr.logicalBlockNum = mdata->s_bitmap_file_loc;
9857888824bSAlden Tondettar 		addr.partitionReferenceNum = mdata->s_phys_partition_ref;
986bfb257a5SJan Kara 
987fcbf7637SSteve Magnani 		udf_debug("Bitmap file location: block = %u part = %u\n",
988bfb257a5SJan Kara 			  addr.logicalBlockNum, addr.partitionReferenceNum);
989bfb257a5SJan Kara 
9906174c2ebSJan Kara 		fe = udf_iget_special(sb, &addr);
9916d3d5e86SJan Kara 		if (IS_ERR(fe)) {
992bc98a42cSDavid Howells 			if (sb_rdonly(sb))
993a40ecd7bSJoe Perches 				udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only\n");
994bfb257a5SJan Kara 			else {
9958076c363SJoe Perches 				udf_err(sb, "bitmap inode efe not found and attempted read-write mount\n");
9966d3d5e86SJan Kara 				return PTR_ERR(fe);
997bfb257a5SJan Kara 			}
9986d3d5e86SJan Kara 		} else
9996d3d5e86SJan Kara 			mdata->s_bitmap_fe = fe;
1000bfb257a5SJan Kara 	}
1001bfb257a5SJan Kara 
1002bfb257a5SJan Kara 	udf_debug("udf_load_metadata_files Ok\n");
1003bfb257a5SJan Kara 	return 0;
1004bfb257a5SJan Kara }
1005bfb257a5SJan Kara 
udf_compute_nr_groups(struct super_block * sb,u32 partition)1006883cb9d1SMarcin Slusarz int udf_compute_nr_groups(struct super_block *sb, u32 partition)
1007883cb9d1SMarcin Slusarz {
1008883cb9d1SMarcin Slusarz 	struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
10098dee00bbSJulia Lawall 	return DIV_ROUND_UP(map->s_partition_len +
10108dee00bbSJulia Lawall 			    (sizeof(struct spaceBitmapDesc) << 3),
10118dee00bbSJulia Lawall 			    sb->s_blocksize * 8);
1012883cb9d1SMarcin Slusarz }
1013883cb9d1SMarcin Slusarz 
udf_sb_alloc_bitmap(struct super_block * sb,u32 index)101466e1da3fSMarcin Slusarz static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
101566e1da3fSMarcin Slusarz {
101666e1da3fSMarcin Slusarz 	struct udf_bitmap *bitmap;
1017256ccb9bSDenis Efremov 	int nr_groups = udf_compute_nr_groups(sb, index);
101866e1da3fSMarcin Slusarz 
1019256ccb9bSDenis Efremov 	bitmap = kvzalloc(struct_size(bitmap, s_block_bitmap, nr_groups),
1020256ccb9bSDenis Efremov 			  GFP_KERNEL);
1021ba2eb866SMarkus Elfring 	if (!bitmap)
102266e1da3fSMarcin Slusarz 		return NULL;
102366e1da3fSMarcin Slusarz 
102466e1da3fSMarcin Slusarz 	bitmap->s_nr_groups = nr_groups;
102566e1da3fSMarcin Slusarz 	return bitmap;
102666e1da3fSMarcin Slusarz }
102766e1da3fSMarcin Slusarz 
check_partition_desc(struct super_block * sb,struct partitionDesc * p,struct udf_part_map * map)1028b085fbe2SJan Kara static int check_partition_desc(struct super_block *sb,
1029b085fbe2SJan Kara 				struct partitionDesc *p,
1030b085fbe2SJan Kara 				struct udf_part_map *map)
1031b085fbe2SJan Kara {
1032b085fbe2SJan Kara 	bool umap, utable, fmap, ftable;
1033b085fbe2SJan Kara 	struct partitionHeaderDesc *phd;
1034b085fbe2SJan Kara 
1035b085fbe2SJan Kara 	switch (le32_to_cpu(p->accessType)) {
1036b085fbe2SJan Kara 	case PD_ACCESS_TYPE_READ_ONLY:
1037b085fbe2SJan Kara 	case PD_ACCESS_TYPE_WRITE_ONCE:
1038b085fbe2SJan Kara 	case PD_ACCESS_TYPE_NONE:
1039b085fbe2SJan Kara 		goto force_ro;
1040b085fbe2SJan Kara 	}
1041b085fbe2SJan Kara 
1042b085fbe2SJan Kara 	/* No Partition Header Descriptor? */
1043b085fbe2SJan Kara 	if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) &&
1044b085fbe2SJan Kara 	    strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
1045b085fbe2SJan Kara 		goto force_ro;
1046b085fbe2SJan Kara 
1047b085fbe2SJan Kara 	phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
1048b085fbe2SJan Kara 	utable = phd->unallocSpaceTable.extLength;
1049b085fbe2SJan Kara 	umap = phd->unallocSpaceBitmap.extLength;
1050b085fbe2SJan Kara 	ftable = phd->freedSpaceTable.extLength;
1051b085fbe2SJan Kara 	fmap = phd->freedSpaceBitmap.extLength;
1052b085fbe2SJan Kara 
1053b085fbe2SJan Kara 	/* No allocation info? */
1054b085fbe2SJan Kara 	if (!utable && !umap && !ftable && !fmap)
1055b085fbe2SJan Kara 		goto force_ro;
1056b085fbe2SJan Kara 
1057b085fbe2SJan Kara 	/* We don't support blocks that require erasing before overwrite */
1058b085fbe2SJan Kara 	if (ftable || fmap)
1059b085fbe2SJan Kara 		goto force_ro;
1060b085fbe2SJan Kara 	/* UDF 2.60: 2.3.3 - no mixing of tables & bitmaps, no VAT. */
1061b085fbe2SJan Kara 	if (utable && umap)
1062b085fbe2SJan Kara 		goto force_ro;
1063b085fbe2SJan Kara 
1064b085fbe2SJan Kara 	if (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
106557debb81SPali Rohár 	    map->s_partition_type == UDF_VIRTUAL_MAP20 ||
106657debb81SPali Rohár 	    map->s_partition_type == UDF_METADATA_MAP25)
1067b085fbe2SJan Kara 		goto force_ro;
1068b085fbe2SJan Kara 
1069b085fbe2SJan Kara 	return 0;
1070b085fbe2SJan Kara force_ro:
1071b085fbe2SJan Kara 	if (!sb_rdonly(sb))
1072b085fbe2SJan Kara 		return -EACCES;
1073b085fbe2SJan Kara 	UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
1074b085fbe2SJan Kara 	return 0;
1075b085fbe2SJan Kara }
1076b085fbe2SJan Kara 
udf_fill_partdesc_info(struct super_block * sb,struct partitionDesc * p,int p_index)10773fb38dfaSJan Kara static int udf_fill_partdesc_info(struct super_block *sb,
10783fb38dfaSJan Kara 		struct partitionDesc *p, int p_index)
10793fb38dfaSJan Kara {
10803fb38dfaSJan Kara 	struct udf_part_map *map;
10813fb38dfaSJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
10823fb38dfaSJan Kara 	struct partitionHeaderDesc *phd;
1083a5633076SJan Kara 	u32 sum;
1084b085fbe2SJan Kara 	int err;
10853fb38dfaSJan Kara 
10863fb38dfaSJan Kara 	map = &sbi->s_partmaps[p_index];
10873fb38dfaSJan Kara 
10883fb38dfaSJan Kara 	map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */
10893fb38dfaSJan Kara 	map->s_partition_root = le32_to_cpu(p->partitionStartingLocation);
1090a5633076SJan Kara 	if (check_add_overflow(map->s_partition_root, map->s_partition_len,
1091a5633076SJan Kara 			       &sum)) {
1092a5633076SJan Kara 		udf_err(sb, "Partition %d has invalid location %u + %u\n",
1093a5633076SJan Kara 			p_index, map->s_partition_root, map->s_partition_len);
1094a5633076SJan Kara 		return -EFSCORRUPTED;
1095a5633076SJan Kara 	}
10963fb38dfaSJan Kara 
10973fb38dfaSJan Kara 	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY))
10983fb38dfaSJan Kara 		map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY;
10993fb38dfaSJan Kara 	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE))
11003fb38dfaSJan Kara 		map->s_partition_flags |= UDF_PART_FLAG_WRITE_ONCE;
11013fb38dfaSJan Kara 	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE))
11023fb38dfaSJan Kara 		map->s_partition_flags |= UDF_PART_FLAG_REWRITABLE;
11033fb38dfaSJan Kara 	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE))
11043fb38dfaSJan Kara 		map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE;
11053fb38dfaSJan Kara 
1106fcbf7637SSteve Magnani 	udf_debug("Partition (%d type %x) starts at physical %u, block length %u\n",
1107a983f368SJoe Perches 		  p_index, map->s_partition_type,
1108a983f368SJoe Perches 		  map->s_partition_root, map->s_partition_len);
11093fb38dfaSJan Kara 
1110b085fbe2SJan Kara 	err = check_partition_desc(sb, p, map);
1111b085fbe2SJan Kara 	if (err)
1112b085fbe2SJan Kara 		return err;
1113b085fbe2SJan Kara 
1114b085fbe2SJan Kara 	/*
1115b085fbe2SJan Kara 	 * Skip loading allocation info it we cannot ever write to the fs.
1116b085fbe2SJan Kara 	 * This is a correctness thing as we may have decided to force ro mount
1117b085fbe2SJan Kara 	 * to avoid allocation info we don't support.
1118b085fbe2SJan Kara 	 */
1119b085fbe2SJan Kara 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
11203fb38dfaSJan Kara 		return 0;
11213fb38dfaSJan Kara 
11223fb38dfaSJan Kara 	phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
11233fb38dfaSJan Kara 	if (phd->unallocSpaceTable.extLength) {
11245ca4e4beSPekka Enberg 		struct kernel_lb_addr loc = {
11253fb38dfaSJan Kara 			.logicalBlockNum = le32_to_cpu(
11263fb38dfaSJan Kara 				phd->unallocSpaceTable.extPosition),
11273fb38dfaSJan Kara 			.partitionReferenceNum = p_index,
11283fb38dfaSJan Kara 		};
11296d3d5e86SJan Kara 		struct inode *inode;
11303fb38dfaSJan Kara 
11316174c2ebSJan Kara 		inode = udf_iget_special(sb, &loc);
11326d3d5e86SJan Kara 		if (IS_ERR(inode)) {
11333fb38dfaSJan Kara 			udf_debug("cannot load unallocSpaceTable (part %d)\n",
11343fb38dfaSJan Kara 				  p_index);
11356d3d5e86SJan Kara 			return PTR_ERR(inode);
11363fb38dfaSJan Kara 		}
11376d3d5e86SJan Kara 		map->s_uspace.s_table = inode;
11383fb38dfaSJan Kara 		map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE;
1139fcbf7637SSteve Magnani 		udf_debug("unallocSpaceTable (part %d) @ %lu\n",
11403fb38dfaSJan Kara 			  p_index, map->s_uspace.s_table->i_ino);
11413fb38dfaSJan Kara 	}
11423fb38dfaSJan Kara 
11433fb38dfaSJan Kara 	if (phd->unallocSpaceBitmap.extLength) {
11443fb38dfaSJan Kara 		struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
11453fb38dfaSJan Kara 		if (!bitmap)
1146d759bfa4SJan Kara 			return -ENOMEM;
11473fb38dfaSJan Kara 		map->s_uspace.s_bitmap = bitmap;
11483fb38dfaSJan Kara 		bitmap->s_extPosition = le32_to_cpu(
11493fb38dfaSJan Kara 				phd->unallocSpaceBitmap.extPosition);
11503fb38dfaSJan Kara 		map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
1151a5633076SJan Kara 		/* Check whether math over bitmap won't overflow. */
1152a5633076SJan Kara 		if (check_add_overflow(map->s_partition_len,
1153a5633076SJan Kara 				       sizeof(struct spaceBitmapDesc) << 3,
1154a5633076SJan Kara 				       &sum)) {
1155a5633076SJan Kara 			udf_err(sb, "Partition %d is too long (%u)\n", p_index,
1156a5633076SJan Kara 				map->s_partition_len);
1157a5633076SJan Kara 			return -EFSCORRUPTED;
1158a5633076SJan Kara 		}
1159fcbf7637SSteve Magnani 		udf_debug("unallocSpaceBitmap (part %d) @ %u\n",
1160a983f368SJoe Perches 			  p_index, bitmap->s_extPosition);
11613fb38dfaSJan Kara 	}
11623fb38dfaSJan Kara 
11633fb38dfaSJan Kara 	return 0;
11643fb38dfaSJan Kara }
11653fb38dfaSJan Kara 
udf_find_vat_block(struct super_block * sb,int p_index,int type1_index,sector_t start_block)1166e971b0b9SJan Kara static void udf_find_vat_block(struct super_block *sb, int p_index,
1167e971b0b9SJan Kara 			       int type1_index, sector_t start_block)
1168e971b0b9SJan Kara {
1169e971b0b9SJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
1170e971b0b9SJan Kara 	struct udf_part_map *map = &sbi->s_partmaps[p_index];
1171e971b0b9SJan Kara 	sector_t vat_block;
1172e971b0b9SJan Kara 	struct kernel_lb_addr ino;
11736d3d5e86SJan Kara 	struct inode *inode;
1174e971b0b9SJan Kara 
1175e971b0b9SJan Kara 	/*
1176e971b0b9SJan Kara 	 * VAT file entry is in the last recorded block. Some broken disks have
1177e971b0b9SJan Kara 	 * it a few blocks before so try a bit harder...
1178e971b0b9SJan Kara 	 */
1179e971b0b9SJan Kara 	ino.partitionReferenceNum = type1_index;
1180e971b0b9SJan Kara 	for (vat_block = start_block;
1181e971b0b9SJan Kara 	     vat_block >= map->s_partition_root &&
11826d3d5e86SJan Kara 	     vat_block >= start_block - 3; vat_block--) {
1183e971b0b9SJan Kara 		ino.logicalBlockNum = vat_block - map->s_partition_root;
11846174c2ebSJan Kara 		inode = udf_iget_special(sb, &ino);
11856d3d5e86SJan Kara 		if (!IS_ERR(inode)) {
11866d3d5e86SJan Kara 			sbi->s_vat_inode = inode;
11876d3d5e86SJan Kara 			break;
11886d3d5e86SJan Kara 		}
1189e971b0b9SJan Kara 	}
1190e971b0b9SJan Kara }
1191e971b0b9SJan Kara 
udf_load_vat(struct super_block * sb,int p_index,int type1_index)119238b74a53SJan Kara static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
119338b74a53SJan Kara {
119438b74a53SJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
119538b74a53SJan Kara 	struct udf_part_map *map = &sbi->s_partmaps[p_index];
1196fa5e0815SJan Kara 	struct buffer_head *bh = NULL;
1197fa5e0815SJan Kara 	struct udf_inode_info *vati;
1198fa5e0815SJan Kara 	struct virtualAllocationTable20 *vat20;
1199e4ae4735SChristoph Hellwig 	sector_t blocks = sb_bdev_nr_blocks(sb);
120038b74a53SJan Kara 
1201e971b0b9SJan Kara 	udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
12024bf17af0SJan Kara 	if (!sbi->s_vat_inode &&
12034bf17af0SJan Kara 	    sbi->s_last_block != blocks - 1) {
120478ace70cSJoe Perches 		pr_notice("Failed to read VAT inode from the last recorded block (%lu), retrying with the last block of the device (%lu).\n",
12054bf17af0SJan Kara 			  (unsigned long)sbi->s_last_block,
12064bf17af0SJan Kara 			  (unsigned long)blocks - 1);
1207e971b0b9SJan Kara 		udf_find_vat_block(sb, p_index, type1_index, blocks - 1);
12084bf17af0SJan Kara 	}
120938b74a53SJan Kara 	if (!sbi->s_vat_inode)
1210d759bfa4SJan Kara 		return -EIO;
121138b74a53SJan Kara 
121238b74a53SJan Kara 	if (map->s_partition_type == UDF_VIRTUAL_MAP15) {
121347c9358aSSebastian Manciulea 		map->s_type_specific.s_virtual.s_start_offset = 0;
121438b74a53SJan Kara 		map->s_type_specific.s_virtual.s_num_entries =
121538b74a53SJan Kara 			(sbi->s_vat_inode->i_size - 36) >> 2;
121638b74a53SJan Kara 	} else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
1217fa5e0815SJan Kara 		vati = UDF_I(sbi->s_vat_inode);
1218fa5e0815SJan Kara 		if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
121908931b78SJan Kara 			int err = 0;
122008931b78SJan Kara 
122108931b78SJan Kara 			bh = udf_bread(sbi->s_vat_inode, 0, 0, &err);
122208931b78SJan Kara 			if (!bh) {
122308931b78SJan Kara 				if (!err)
122408931b78SJan Kara 					err = -EFSCORRUPTED;
122508931b78SJan Kara 				return err;
122608931b78SJan Kara 			}
1227fa5e0815SJan Kara 			vat20 = (struct virtualAllocationTable20 *)bh->b_data;
1228fa5e0815SJan Kara 		} else {
1229fa5e0815SJan Kara 			vat20 = (struct virtualAllocationTable20 *)
1230382a2287SJan Kara 							vati->i_data;
1231fa5e0815SJan Kara 		}
1232fa5e0815SJan Kara 
123338b74a53SJan Kara 		map->s_type_specific.s_virtual.s_start_offset =
123447c9358aSSebastian Manciulea 			le16_to_cpu(vat20->lengthHeader);
123538b74a53SJan Kara 		map->s_type_specific.s_virtual.s_num_entries =
123638b74a53SJan Kara 			(sbi->s_vat_inode->i_size -
123738b74a53SJan Kara 				map->s_type_specific.s_virtual.
123838b74a53SJan Kara 					s_start_offset) >> 2;
123938b74a53SJan Kara 		brelse(bh);
124038b74a53SJan Kara 	}
124138b74a53SJan Kara 	return 0;
124238b74a53SJan Kara }
124338b74a53SJan Kara 
1244d759bfa4SJan Kara /*
1245d759bfa4SJan Kara  * Load partition descriptor block
1246d759bfa4SJan Kara  *
1247d759bfa4SJan Kara  * Returns <0 on error, 0 on success, -EAGAIN is special - try next descriptor
1248d759bfa4SJan Kara  * sequence.
1249d759bfa4SJan Kara  */
udf_load_partdesc(struct super_block * sb,sector_t block)1250c0eb31edSJan Kara static int udf_load_partdesc(struct super_block *sb, sector_t block)
12511da177e4SLinus Torvalds {
1252c0eb31edSJan Kara 	struct buffer_head *bh;
1253c0eb31edSJan Kara 	struct partitionDesc *p;
12546c79e987SMarcin Slusarz 	struct udf_part_map *map;
1255165923faSMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
125638b74a53SJan Kara 	int i, type1_idx;
1257c0eb31edSJan Kara 	uint16_t partitionNumber;
1258c0eb31edSJan Kara 	uint16_t ident;
1259d759bfa4SJan Kara 	int ret;
12601da177e4SLinus Torvalds 
1261c0eb31edSJan Kara 	bh = udf_read_tagged(sb, block, block, &ident);
1262c0eb31edSJan Kara 	if (!bh)
1263d759bfa4SJan Kara 		return -EAGAIN;
1264d759bfa4SJan Kara 	if (ident != TAG_IDENT_PD) {
1265d759bfa4SJan Kara 		ret = 0;
1266c0eb31edSJan Kara 		goto out_bh;
1267d759bfa4SJan Kara 	}
1268c0eb31edSJan Kara 
1269c0eb31edSJan Kara 	p = (struct partitionDesc *)bh->b_data;
1270c0eb31edSJan Kara 	partitionNumber = le16_to_cpu(p->partitionNumber);
127138b74a53SJan Kara 
12727888824bSAlden Tondettar 	/* First scan for TYPE1 and SPARABLE partitions */
12736c79e987SMarcin Slusarz 	for (i = 0; i < sbi->s_partitions; i++) {
12746c79e987SMarcin Slusarz 		map = &sbi->s_partmaps[i];
1275fcbf7637SSteve Magnani 		udf_debug("Searching map: (%u == %u)\n",
1276165923faSMarcin Slusarz 			  map->s_partition_num, partitionNumber);
127738b74a53SJan Kara 		if (map->s_partition_num == partitionNumber &&
127838b74a53SJan Kara 		    (map->s_partition_type == UDF_TYPE1_MAP15 ||
127938b74a53SJan Kara 		     map->s_partition_type == UDF_SPARABLE_MAP15))
1280165923faSMarcin Slusarz 			break;
1281165923faSMarcin Slusarz 	}
12821da177e4SLinus Torvalds 
128338b74a53SJan Kara 	if (i >= sbi->s_partitions) {
1284fcbf7637SSteve Magnani 		udf_debug("Partition (%u) not found in partition map\n",
1285165923faSMarcin Slusarz 			  partitionNumber);
1286d759bfa4SJan Kara 		ret = 0;
1287c0eb31edSJan Kara 		goto out_bh;
1288165923faSMarcin Slusarz 	}
12891da177e4SLinus Torvalds 
12903fb38dfaSJan Kara 	ret = udf_fill_partdesc_info(sb, p, i);
1291d759bfa4SJan Kara 	if (ret < 0)
1292d759bfa4SJan Kara 		goto out_bh;
129338b74a53SJan Kara 
129438b74a53SJan Kara 	/*
1295bfb257a5SJan Kara 	 * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and
1296bfb257a5SJan Kara 	 * PHYSICAL partitions are already set up
129738b74a53SJan Kara 	 */
129838b74a53SJan Kara 	type1_idx = i;
129944499602SPeter A. Felvegi 	map = NULL; /* supress 'maybe used uninitialized' warning */
130038b74a53SJan Kara 	for (i = 0; i < sbi->s_partitions; i++) {
130138b74a53SJan Kara 		map = &sbi->s_partmaps[i];
130238b74a53SJan Kara 
130338b74a53SJan Kara 		if (map->s_partition_num == partitionNumber &&
130438b74a53SJan Kara 		    (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
1305bfb257a5SJan Kara 		     map->s_partition_type == UDF_VIRTUAL_MAP20 ||
1306bfb257a5SJan Kara 		     map->s_partition_type == UDF_METADATA_MAP25))
130738b74a53SJan Kara 			break;
130838b74a53SJan Kara 	}
130938b74a53SJan Kara 
1310d759bfa4SJan Kara 	if (i >= sbi->s_partitions) {
1311d759bfa4SJan Kara 		ret = 0;
131238b74a53SJan Kara 		goto out_bh;
1313d759bfa4SJan Kara 	}
131438b74a53SJan Kara 
131538b74a53SJan Kara 	ret = udf_fill_partdesc_info(sb, p, i);
1316d759bfa4SJan Kara 	if (ret < 0)
131738b74a53SJan Kara 		goto out_bh;
1318bfb257a5SJan Kara 
1319bfb257a5SJan Kara 	if (map->s_partition_type == UDF_METADATA_MAP25) {
13207888824bSAlden Tondettar 		ret = udf_load_metadata_files(sb, i, type1_idx);
1321d759bfa4SJan Kara 		if (ret < 0) {
132278ace70cSJoe Perches 			udf_err(sb, "error loading MetaData partition map %d\n",
132378ace70cSJoe Perches 				i);
1324bfb257a5SJan Kara 			goto out_bh;
1325bfb257a5SJan Kara 		}
1326bfb257a5SJan Kara 	} else {
1327e729eac6SJan Kara 		/*
1328e729eac6SJan Kara 		 * If we have a partition with virtual map, we don't handle
1329e729eac6SJan Kara 		 * writing to it (we overwrite blocks instead of relocating
1330e729eac6SJan Kara 		 * them).
1331e729eac6SJan Kara 		 */
1332bc98a42cSDavid Howells 		if (!sb_rdonly(sb)) {
1333e729eac6SJan Kara 			ret = -EACCES;
1334e729eac6SJan Kara 			goto out_bh;
1335e729eac6SJan Kara 		}
1336a9ad01bcSJan Kara 		UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
1337bfb257a5SJan Kara 		ret = udf_load_vat(sb, i, type1_idx);
1338d759bfa4SJan Kara 		if (ret < 0)
1339bfb257a5SJan Kara 			goto out_bh;
1340bfb257a5SJan Kara 	}
1341d759bfa4SJan Kara 	ret = 0;
1342c0eb31edSJan Kara out_bh:
13432e0838fdSJan Kara 	/* In case loading failed, we handle cleanup in udf_fill_super */
1344c0eb31edSJan Kara 	brelse(bh);
1345c0eb31edSJan Kara 	return ret;
13461da177e4SLinus Torvalds }
13471da177e4SLinus Torvalds 
udf_load_sparable_map(struct super_block * sb,struct udf_part_map * map,struct sparablePartitionMap * spm)13481df2ae31SJan Kara static int udf_load_sparable_map(struct super_block *sb,
13491df2ae31SJan Kara 				 struct udf_part_map *map,
13501df2ae31SJan Kara 				 struct sparablePartitionMap *spm)
13511df2ae31SJan Kara {
13521df2ae31SJan Kara 	uint32_t loc;
13531df2ae31SJan Kara 	uint16_t ident;
13541df2ae31SJan Kara 	struct sparingTable *st;
13551df2ae31SJan Kara 	struct udf_sparing_data *sdata = &map->s_type_specific.s_sparing;
13561df2ae31SJan Kara 	int i;
13571df2ae31SJan Kara 	struct buffer_head *bh;
13581df2ae31SJan Kara 
13591df2ae31SJan Kara 	map->s_partition_type = UDF_SPARABLE_MAP15;
13601df2ae31SJan Kara 	sdata->s_packet_len = le16_to_cpu(spm->packetLength);
13611df2ae31SJan Kara 	if (!is_power_of_2(sdata->s_packet_len)) {
13621df2ae31SJan Kara 		udf_err(sb, "error loading logical volume descriptor: "
13631df2ae31SJan Kara 			"Invalid packet length %u\n",
13641df2ae31SJan Kara 			(unsigned)sdata->s_packet_len);
13651df2ae31SJan Kara 		return -EIO;
13661df2ae31SJan Kara 	}
13671df2ae31SJan Kara 	if (spm->numSparingTables > 4) {
13681df2ae31SJan Kara 		udf_err(sb, "error loading logical volume descriptor: "
13691df2ae31SJan Kara 			"Too many sparing tables (%d)\n",
13701df2ae31SJan Kara 			(int)spm->numSparingTables);
13711df2ae31SJan Kara 		return -EIO;
13721df2ae31SJan Kara 	}
137344ac6b82SJan Kara 	if (le32_to_cpu(spm->sizeSparingTable) > sb->s_blocksize) {
137444ac6b82SJan Kara 		udf_err(sb, "error loading logical volume descriptor: "
137544ac6b82SJan Kara 			"Too big sparing table size (%u)\n",
137644ac6b82SJan Kara 			le32_to_cpu(spm->sizeSparingTable));
137744ac6b82SJan Kara 		return -EIO;
137844ac6b82SJan Kara 	}
13791df2ae31SJan Kara 
13801df2ae31SJan Kara 	for (i = 0; i < spm->numSparingTables; i++) {
13811df2ae31SJan Kara 		loc = le32_to_cpu(spm->locSparingTable[i]);
13821df2ae31SJan Kara 		bh = udf_read_tagged(sb, loc, loc, &ident);
13831df2ae31SJan Kara 		if (!bh)
13841df2ae31SJan Kara 			continue;
13851df2ae31SJan Kara 
13861df2ae31SJan Kara 		st = (struct sparingTable *)bh->b_data;
13871df2ae31SJan Kara 		if (ident != 0 ||
13881df2ae31SJan Kara 		    strncmp(st->sparingIdent.ident, UDF_ID_SPARING,
13891df2ae31SJan Kara 			    strlen(UDF_ID_SPARING)) ||
13901df2ae31SJan Kara 		    sizeof(*st) + le16_to_cpu(st->reallocationTableLen) >
13911df2ae31SJan Kara 							sb->s_blocksize) {
13921df2ae31SJan Kara 			brelse(bh);
13931df2ae31SJan Kara 			continue;
13941df2ae31SJan Kara 		}
13951df2ae31SJan Kara 
13961df2ae31SJan Kara 		sdata->s_spar_map[i] = bh;
13971df2ae31SJan Kara 	}
13981df2ae31SJan Kara 	map->s_partition_func = udf_get_pblock_spar15;
13991df2ae31SJan Kara 	return 0;
14001df2ae31SJan Kara }
14011df2ae31SJan Kara 
udf_load_logicalvol(struct super_block * sb,sector_t block,struct kernel_lb_addr * fileset)1402c0eb31edSJan Kara static int udf_load_logicalvol(struct super_block *sb, sector_t block,
14035ca4e4beSPekka Enberg 			       struct kernel_lb_addr *fileset)
14041da177e4SLinus Torvalds {
14051da177e4SLinus Torvalds 	struct logicalVolDesc *lvd;
14061df2ae31SJan Kara 	int i, offset;
14071da177e4SLinus Torvalds 	uint8_t type;
14086c79e987SMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
14094b11111aSMarcin Slusarz 	struct genericPartitionMap *gpm;
1410c0eb31edSJan Kara 	uint16_t ident;
1411c0eb31edSJan Kara 	struct buffer_head *bh;
1412adee11b2SJan Kara 	unsigned int table_len;
1413d759bfa4SJan Kara 	int ret;
14141da177e4SLinus Torvalds 
1415c0eb31edSJan Kara 	bh = udf_read_tagged(sb, block, block, &ident);
1416c0eb31edSJan Kara 	if (!bh)
1417d759bfa4SJan Kara 		return -EAGAIN;
1418c0eb31edSJan Kara 	BUG_ON(ident != TAG_IDENT_LVD);
14191da177e4SLinus Torvalds 	lvd = (struct logicalVolDesc *)bh->b_data;
1420adee11b2SJan Kara 	table_len = le32_to_cpu(lvd->mapTableLength);
142157b9655dSJan Kara 	if (table_len > sb->s_blocksize - sizeof(*lvd)) {
1422adee11b2SJan Kara 		udf_err(sb, "error loading logical volume descriptor: "
1423adee11b2SJan Kara 			"Partition table too long (%u > %lu)\n", table_len,
1424adee11b2SJan Kara 			sb->s_blocksize - sizeof(*lvd));
1425d759bfa4SJan Kara 		ret = -EIO;
1426adee11b2SJan Kara 		goto out_bh;
1427adee11b2SJan Kara 	}
14281da177e4SLinus Torvalds 
14292dee5aacSJan Kara 	ret = udf_verify_domain_identifier(sb, &lvd->domainIdent,
14302dee5aacSJan Kara 					   "logical volume");
14312dee5aacSJan Kara 	if (ret)
14322dee5aacSJan Kara 		goto out_bh;
1433cb14d340SJan Kara 	ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
1434cb14d340SJan Kara 	if (ret)
1435c0eb31edSJan Kara 		goto out_bh;
14361da177e4SLinus Torvalds 
14371da177e4SLinus Torvalds 	for (i = 0, offset = 0;
1438adee11b2SJan Kara 	     i < sbi->s_partitions && offset < table_len;
14394b11111aSMarcin Slusarz 	     i++, offset += gpm->partitionMapLength) {
14406c79e987SMarcin Slusarz 		struct udf_part_map *map = &sbi->s_partmaps[i];
14414b11111aSMarcin Slusarz 		gpm = (struct genericPartitionMap *)
14424b11111aSMarcin Slusarz 				&(lvd->partitionMaps[offset]);
14434b11111aSMarcin Slusarz 		type = gpm->partitionMapType;
1444cb00ea35SCyrill Gorcunov 		if (type == 1) {
14454b11111aSMarcin Slusarz 			struct genericPartitionMap1 *gpm1 =
14464b11111aSMarcin Slusarz 				(struct genericPartitionMap1 *)gpm;
14476c79e987SMarcin Slusarz 			map->s_partition_type = UDF_TYPE1_MAP15;
14486c79e987SMarcin Slusarz 			map->s_volumeseqnum = le16_to_cpu(gpm1->volSeqNum);
14496c79e987SMarcin Slusarz 			map->s_partition_num = le16_to_cpu(gpm1->partitionNum);
14506c79e987SMarcin Slusarz 			map->s_partition_func = NULL;
1451cb00ea35SCyrill Gorcunov 		} else if (type == 2) {
14524b11111aSMarcin Slusarz 			struct udfPartitionMap2 *upm2 =
14534b11111aSMarcin Slusarz 						(struct udfPartitionMap2 *)gpm;
14544b11111aSMarcin Slusarz 			if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL,
14554b11111aSMarcin Slusarz 						strlen(UDF_ID_VIRTUAL))) {
14564b11111aSMarcin Slusarz 				u16 suf =
14574b11111aSMarcin Slusarz 					le16_to_cpu(((__le16 *)upm2->partIdent.
14584b11111aSMarcin Slusarz 							identSuffix)[0]);
1459c82a1275SJan Kara 				if (suf < 0x0200) {
14604b11111aSMarcin Slusarz 					map->s_partition_type =
14614b11111aSMarcin Slusarz 							UDF_VIRTUAL_MAP15;
14624b11111aSMarcin Slusarz 					map->s_partition_func =
14634b11111aSMarcin Slusarz 							udf_get_pblock_virt15;
1464c82a1275SJan Kara 				} else {
14654b11111aSMarcin Slusarz 					map->s_partition_type =
14664b11111aSMarcin Slusarz 							UDF_VIRTUAL_MAP20;
14674b11111aSMarcin Slusarz 					map->s_partition_func =
14684b11111aSMarcin Slusarz 							udf_get_pblock_virt20;
14691da177e4SLinus Torvalds 				}
14704b11111aSMarcin Slusarz 			} else if (!strncmp(upm2->partIdent.ident,
14714b11111aSMarcin Slusarz 						UDF_ID_SPARABLE,
14724b11111aSMarcin Slusarz 						strlen(UDF_ID_SPARABLE))) {
1473d759bfa4SJan Kara 				ret = udf_load_sparable_map(sb, map,
1474d759bfa4SJan Kara 					(struct sparablePartitionMap *)gpm);
1475d759bfa4SJan Kara 				if (ret < 0)
14761df2ae31SJan Kara 					goto out_bh;
1477bfb257a5SJan Kara 			} else if (!strncmp(upm2->partIdent.ident,
1478bfb257a5SJan Kara 						UDF_ID_METADATA,
1479bfb257a5SJan Kara 						strlen(UDF_ID_METADATA))) {
1480bfb257a5SJan Kara 				struct udf_meta_data *mdata =
1481bfb257a5SJan Kara 					&map->s_type_specific.s_metadata;
1482bfb257a5SJan Kara 				struct metadataPartitionMap *mdm =
1483bfb257a5SJan Kara 						(struct metadataPartitionMap *)
1484bfb257a5SJan Kara 						&(lvd->partitionMaps[offset]);
1485fcbf7637SSteve Magnani 				udf_debug("Parsing Logical vol part %d type %u  id=%s\n",
1486a983f368SJoe Perches 					  i, type, UDF_ID_METADATA);
1487bfb257a5SJan Kara 
1488bfb257a5SJan Kara 				map->s_partition_type = UDF_METADATA_MAP25;
1489bfb257a5SJan Kara 				map->s_partition_func = udf_get_pblock_meta25;
1490bfb257a5SJan Kara 
1491bfb257a5SJan Kara 				mdata->s_meta_file_loc   =
1492bfb257a5SJan Kara 					le32_to_cpu(mdm->metadataFileLoc);
1493bfb257a5SJan Kara 				mdata->s_mirror_file_loc =
1494bfb257a5SJan Kara 					le32_to_cpu(mdm->metadataMirrorFileLoc);
1495bfb257a5SJan Kara 				mdata->s_bitmap_file_loc =
1496bfb257a5SJan Kara 					le32_to_cpu(mdm->metadataBitmapFileLoc);
1497bfb257a5SJan Kara 				mdata->s_alloc_unit_size =
1498bfb257a5SJan Kara 					le32_to_cpu(mdm->allocUnitSize);
1499bfb257a5SJan Kara 				mdata->s_align_unit_size =
1500bfb257a5SJan Kara 					le16_to_cpu(mdm->alignUnitSize);
1501ed47a7d0SJan Kara 				if (mdm->flags & 0x01)
1502ed47a7d0SJan Kara 					mdata->s_flags |= MF_DUPLICATE_MD;
1503bfb257a5SJan Kara 
1504bfb257a5SJan Kara 				udf_debug("Metadata Ident suffix=0x%x\n",
1505a983f368SJoe Perches 					  le16_to_cpu(*(__le16 *)
1506a983f368SJoe Perches 						      mdm->partIdent.identSuffix));
1507fcbf7637SSteve Magnani 				udf_debug("Metadata part num=%u\n",
1508bfb257a5SJan Kara 					  le16_to_cpu(mdm->partitionNum));
1509fcbf7637SSteve Magnani 				udf_debug("Metadata part alloc unit size=%u\n",
1510bfb257a5SJan Kara 					  le32_to_cpu(mdm->allocUnitSize));
1511fcbf7637SSteve Magnani 				udf_debug("Metadata file loc=%u\n",
1512bfb257a5SJan Kara 					  le32_to_cpu(mdm->metadataFileLoc));
1513fcbf7637SSteve Magnani 				udf_debug("Mirror file loc=%u\n",
1514bfb257a5SJan Kara 					  le32_to_cpu(mdm->metadataMirrorFileLoc));
1515fcbf7637SSteve Magnani 				udf_debug("Bitmap file loc=%u\n",
1516bfb257a5SJan Kara 					  le32_to_cpu(mdm->metadataBitmapFileLoc));
1517fcbf7637SSteve Magnani 				udf_debug("Flags: %d %u\n",
1518ed47a7d0SJan Kara 					  mdata->s_flags, mdm->flags);
1519cb00ea35SCyrill Gorcunov 			} else {
15203a71fc5dSMarcin Slusarz 				udf_debug("Unknown ident: %s\n",
15213a71fc5dSMarcin Slusarz 					  upm2->partIdent.ident);
15221da177e4SLinus Torvalds 				continue;
15231da177e4SLinus Torvalds 			}
15246c79e987SMarcin Slusarz 			map->s_volumeseqnum = le16_to_cpu(upm2->volSeqNum);
15256c79e987SMarcin Slusarz 			map->s_partition_num = le16_to_cpu(upm2->partitionNum);
15261da177e4SLinus Torvalds 		}
1527fcbf7637SSteve Magnani 		udf_debug("Partition (%d:%u) type %u on volume %u\n",
1528a983f368SJoe Perches 			  i, map->s_partition_num, type, map->s_volumeseqnum);
15291da177e4SLinus Torvalds 	}
15301da177e4SLinus Torvalds 
1531cb00ea35SCyrill Gorcunov 	if (fileset) {
15325ca4e4beSPekka Enberg 		struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]);
15331da177e4SLinus Torvalds 
15341da177e4SLinus Torvalds 		*fileset = lelb_to_cpu(la->extLocation);
1535fcbf7637SSteve Magnani 		udf_debug("FileSet found in LogicalVolDesc at block=%u, partition=%u\n",
1536a983f368SJoe Perches 			  fileset->logicalBlockNum,
153728de7948SCyrill Gorcunov 			  fileset->partitionReferenceNum);
15381da177e4SLinus Torvalds 	}
15391da177e4SLinus Torvalds 	if (lvd->integritySeqExt.extLength)
15401da177e4SLinus Torvalds 		udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
1541d759bfa4SJan Kara 	ret = 0;
15424f5edd82SSteve Magnani 
15434f5edd82SSteve Magnani 	if (!sbi->s_lvid_bh) {
15444f5edd82SSteve Magnani 		/* We can't generate unique IDs without a valid LVID */
15454f5edd82SSteve Magnani 		if (sb_rdonly(sb)) {
15464f5edd82SSteve Magnani 			UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
15474f5edd82SSteve Magnani 		} else {
15484f5edd82SSteve Magnani 			udf_warn(sb, "Damaged or missing LVID, forcing "
15494f5edd82SSteve Magnani 				     "readonly mount\n");
15504f5edd82SSteve Magnani 			ret = -EACCES;
15514f5edd82SSteve Magnani 		}
15524f5edd82SSteve Magnani 	}
1553c0eb31edSJan Kara out_bh:
1554c0eb31edSJan Kara 	brelse(bh);
1555c0eb31edSJan Kara 	return ret;
15561da177e4SLinus Torvalds }
15571da177e4SLinus Torvalds 
15581da177e4SLinus Torvalds /*
1559a47241cdSAlden Tondettar  * Find the prevailing Logical Volume Integrity Descriptor.
15601da177e4SLinus Torvalds  */
udf_load_logicalvolint(struct super_block * sb,struct kernel_extent_ad loc)15615ca4e4beSPekka Enberg static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc)
15621da177e4SLinus Torvalds {
1563a47241cdSAlden Tondettar 	struct buffer_head *bh, *final_bh;
15641da177e4SLinus Torvalds 	uint16_t ident;
15656c79e987SMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
15666c79e987SMarcin Slusarz 	struct logicalVolIntegrityDesc *lvid;
1567a47241cdSAlden Tondettar 	int indirections = 0;
1568781d2a9aSJan Kara 	u32 parts, impuselen;
15691da177e4SLinus Torvalds 
1570a47241cdSAlden Tondettar 	while (++indirections <= UDF_MAX_LVID_NESTING) {
1571a47241cdSAlden Tondettar 		final_bh = NULL;
15721da177e4SLinus Torvalds 		while (loc.extLength > 0 &&
15731da177e4SLinus Torvalds 			(bh = udf_read_tagged(sb, loc.extLocation,
1574a47241cdSAlden Tondettar 					loc.extLocation, &ident))) {
1575a47241cdSAlden Tondettar 			if (ident != TAG_IDENT_LVID) {
15763bf25cb4SJan Kara 				brelse(bh);
1577a47241cdSAlden Tondettar 				break;
1578a47241cdSAlden Tondettar 			}
1579a47241cdSAlden Tondettar 
1580a47241cdSAlden Tondettar 			brelse(final_bh);
1581a47241cdSAlden Tondettar 			final_bh = bh;
1582a47241cdSAlden Tondettar 
15831da177e4SLinus Torvalds 			loc.extLength -= sb->s_blocksize;
15841da177e4SLinus Torvalds 			loc.extLocation++;
15851da177e4SLinus Torvalds 		}
1586a47241cdSAlden Tondettar 
1587a47241cdSAlden Tondettar 		if (!final_bh)
1588a47241cdSAlden Tondettar 			return;
1589a47241cdSAlden Tondettar 
1590a47241cdSAlden Tondettar 		brelse(sbi->s_lvid_bh);
1591a47241cdSAlden Tondettar 		sbi->s_lvid_bh = final_bh;
1592a47241cdSAlden Tondettar 
1593a47241cdSAlden Tondettar 		lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data;
1594a47241cdSAlden Tondettar 		if (lvid->nextIntegrityExt.extLength == 0)
1595781d2a9aSJan Kara 			goto check;
1596a47241cdSAlden Tondettar 
1597a47241cdSAlden Tondettar 		loc = leea_to_cpu(lvid->nextIntegrityExt);
15981da177e4SLinus Torvalds 	}
15991da177e4SLinus Torvalds 
1600a47241cdSAlden Tondettar 	udf_warn(sb, "Too many LVID indirections (max %u), ignoring.\n",
1601a47241cdSAlden Tondettar 		UDF_MAX_LVID_NESTING);
1602781d2a9aSJan Kara out_err:
1603a47241cdSAlden Tondettar 	brelse(sbi->s_lvid_bh);
1604a47241cdSAlden Tondettar 	sbi->s_lvid_bh = NULL;
1605781d2a9aSJan Kara 	return;
1606781d2a9aSJan Kara check:
1607781d2a9aSJan Kara 	parts = le32_to_cpu(lvid->numOfPartitions);
1608781d2a9aSJan Kara 	impuselen = le32_to_cpu(lvid->lengthOfImpUse);
1609781d2a9aSJan Kara 	if (parts >= sb->s_blocksize || impuselen >= sb->s_blocksize ||
1610781d2a9aSJan Kara 	    sizeof(struct logicalVolIntegrityDesc) + impuselen +
1611781d2a9aSJan Kara 	    2 * parts * sizeof(u32) > sb->s_blocksize) {
1612781d2a9aSJan Kara 		udf_warn(sb, "Corrupted LVID (parts=%u, impuselen=%u), "
1613781d2a9aSJan Kara 			 "ignoring.\n", parts, impuselen);
1614781d2a9aSJan Kara 		goto out_err;
1615781d2a9aSJan Kara 	}
1616a47241cdSAlden Tondettar }
1617a47241cdSAlden Tondettar 
16187b78fd02SJan Kara /*
16197b78fd02SJan Kara  * Step for reallocation of table of partition descriptor sequence numbers.
16207b78fd02SJan Kara  * Must be power of 2.
16217b78fd02SJan Kara  */
16227b78fd02SJan Kara #define PART_DESC_ALLOC_STEP 32
16237b78fd02SJan Kara 
1624ee4af50cSJan Kara struct part_desc_seq_scan_data {
1625ee4af50cSJan Kara 	struct udf_vds_record rec;
1626ee4af50cSJan Kara 	u32 partnum;
1627ee4af50cSJan Kara };
1628ee4af50cSJan Kara 
16297b78fd02SJan Kara struct desc_seq_scan_data {
16307b78fd02SJan Kara 	struct udf_vds_record vds[VDS_POS_LENGTH];
16317b78fd02SJan Kara 	unsigned int size_part_descs;
1632ee4af50cSJan Kara 	unsigned int num_part_descs;
1633ee4af50cSJan Kara 	struct part_desc_seq_scan_data *part_descs_loc;
16347b78fd02SJan Kara };
16357b78fd02SJan Kara 
handle_partition_descriptor(struct buffer_head * bh,struct desc_seq_scan_data * data)16367b78fd02SJan Kara static struct udf_vds_record *handle_partition_descriptor(
16377b78fd02SJan Kara 				struct buffer_head *bh,
16387b78fd02SJan Kara 				struct desc_seq_scan_data *data)
16397b78fd02SJan Kara {
16407b78fd02SJan Kara 	struct partitionDesc *desc = (struct partitionDesc *)bh->b_data;
16417b78fd02SJan Kara 	int partnum;
1642ee4af50cSJan Kara 	int i;
16437b78fd02SJan Kara 
16447b78fd02SJan Kara 	partnum = le16_to_cpu(desc->partitionNumber);
1645ee4af50cSJan Kara 	for (i = 0; i < data->num_part_descs; i++)
1646ee4af50cSJan Kara 		if (partnum == data->part_descs_loc[i].partnum)
1647ee4af50cSJan Kara 			return &(data->part_descs_loc[i].rec);
1648ee4af50cSJan Kara 	if (data->num_part_descs >= data->size_part_descs) {
1649ee4af50cSJan Kara 		struct part_desc_seq_scan_data *new_loc;
16507b78fd02SJan Kara 		unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
16517b78fd02SJan Kara 
16526396bb22SKees Cook 		new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
16537b78fd02SJan Kara 		if (!new_loc)
16547b78fd02SJan Kara 			return ERR_PTR(-ENOMEM);
16557b78fd02SJan Kara 		memcpy(new_loc, data->part_descs_loc,
16567b78fd02SJan Kara 		       data->size_part_descs * sizeof(*new_loc));
16577b78fd02SJan Kara 		kfree(data->part_descs_loc);
16587b78fd02SJan Kara 		data->part_descs_loc = new_loc;
16597b78fd02SJan Kara 		data->size_part_descs = new_size;
16607b78fd02SJan Kara 	}
1661ee4af50cSJan Kara 	return &(data->part_descs_loc[data->num_part_descs++].rec);
16627b78fd02SJan Kara }
16637b78fd02SJan Kara 
16647b78fd02SJan Kara 
get_volume_descriptor_record(uint16_t ident,struct buffer_head * bh,struct desc_seq_scan_data * data)16657b78fd02SJan Kara static struct udf_vds_record *get_volume_descriptor_record(uint16_t ident,
16667b78fd02SJan Kara 		struct buffer_head *bh, struct desc_seq_scan_data *data)
166718cf4781SJan Kara {
166818cf4781SJan Kara 	switch (ident) {
166918cf4781SJan Kara 	case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
16707b78fd02SJan Kara 		return &(data->vds[VDS_POS_PRIMARY_VOL_DESC]);
167118cf4781SJan Kara 	case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
16727b78fd02SJan Kara 		return &(data->vds[VDS_POS_IMP_USE_VOL_DESC]);
167318cf4781SJan Kara 	case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
16747b78fd02SJan Kara 		return &(data->vds[VDS_POS_LOGICAL_VOL_DESC]);
167518cf4781SJan Kara 	case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
16767b78fd02SJan Kara 		return &(data->vds[VDS_POS_UNALLOC_SPACE_DESC]);
16777b78fd02SJan Kara 	case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
16787b78fd02SJan Kara 		return handle_partition_descriptor(bh, data);
167918cf4781SJan Kara 	}
168018cf4781SJan Kara 	return NULL;
168118cf4781SJan Kara }
1682e7a4eb86SVegard Nossum 
1683e7a4eb86SVegard Nossum /*
16841da177e4SLinus Torvalds  * Process a main/reserve volume descriptor sequence.
1685d759bfa4SJan Kara  *   @block		First block of first extent of the sequence.
1686d759bfa4SJan Kara  *   @lastblock		Lastblock of first extent of the sequence.
1687d759bfa4SJan Kara  *   @fileset		There we store extent containing root fileset
16881da177e4SLinus Torvalds  *
1689d759bfa4SJan Kara  * Returns <0 on error, 0 on success. -EAGAIN is special - try next descriptor
1690d759bfa4SJan Kara  * sequence
16911da177e4SLinus Torvalds  */
udf_process_sequence(struct super_block * sb,sector_t block,sector_t lastblock,struct kernel_lb_addr * fileset)1692d759bfa4SJan Kara static noinline int udf_process_sequence(
1693d759bfa4SJan Kara 		struct super_block *sb,
1694d759bfa4SJan Kara 		sector_t block, sector_t lastblock,
1695d759bfa4SJan Kara 		struct kernel_lb_addr *fileset)
16961da177e4SLinus Torvalds {
16971da177e4SLinus Torvalds 	struct buffer_head *bh = NULL;
16984b11111aSMarcin Slusarz 	struct udf_vds_record *curr;
16991da177e4SLinus Torvalds 	struct generic_desc *gd;
17001da177e4SLinus Torvalds 	struct volDescPtr *vdp;
17012b8f9421SFabian Frederick 	bool done = false;
17021da177e4SLinus Torvalds 	uint32_t vdsn;
17031da177e4SLinus Torvalds 	uint16_t ident;
1704d759bfa4SJan Kara 	int ret;
1705e7a4eb86SVegard Nossum 	unsigned int indirections = 0;
17067b78fd02SJan Kara 	struct desc_seq_scan_data data;
17077b78fd02SJan Kara 	unsigned int i;
17081da177e4SLinus Torvalds 
17097b78fd02SJan Kara 	memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
17107b78fd02SJan Kara 	data.size_part_descs = PART_DESC_ALLOC_STEP;
1711ee4af50cSJan Kara 	data.num_part_descs = 0;
17126396bb22SKees Cook 	data.part_descs_loc = kcalloc(data.size_part_descs,
17136396bb22SKees Cook 				      sizeof(*data.part_descs_loc),
17146396bb22SKees Cook 				      GFP_KERNEL);
17157b78fd02SJan Kara 	if (!data.part_descs_loc)
17167b78fd02SJan Kara 		return -ENOMEM;
17171da177e4SLinus Torvalds 
1718c0eb31edSJan Kara 	/*
1719c0eb31edSJan Kara 	 * Read the main descriptor sequence and find which descriptors
1720c0eb31edSJan Kara 	 * are in it.
1721c0eb31edSJan Kara 	 */
1722cb00ea35SCyrill Gorcunov 	for (; (!done && block <= lastblock); block++) {
17231da177e4SLinus Torvalds 		bh = udf_read_tagged(sb, block, block, &ident);
172467621675SJan Kara 		if (!bh)
172567621675SJan Kara 			break;
17261da177e4SLinus Torvalds 
17271da177e4SLinus Torvalds 		/* Process each descriptor (ISO 13346 3/8.3-8.4) */
17281da177e4SLinus Torvalds 		gd = (struct generic_desc *)bh->b_data;
17291da177e4SLinus Torvalds 		vdsn = le32_to_cpu(gd->volDescSeqNum);
1730cb00ea35SCyrill Gorcunov 		switch (ident) {
17311da177e4SLinus Torvalds 		case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
17327b568cbaSJan Kara 			if (++indirections > UDF_MAX_TD_NESTING) {
17337b568cbaSJan Kara 				udf_err(sb, "too many Volume Descriptor "
17347b568cbaSJan Kara 					"Pointers (max %u supported)\n",
17357b568cbaSJan Kara 					UDF_MAX_TD_NESTING);
17367b568cbaSJan Kara 				brelse(bh);
1737a7be300dSJan Kara 				ret = -EIO;
1738a7be300dSJan Kara 				goto out;
17397b568cbaSJan Kara 			}
17401da177e4SLinus Torvalds 
17411da177e4SLinus Torvalds 			vdp = (struct volDescPtr *)bh->b_data;
17427b568cbaSJan Kara 			block = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
17437b568cbaSJan Kara 			lastblock = le32_to_cpu(
17447b568cbaSJan Kara 				vdp->nextVolDescSeqExt.extLength) >>
17457b568cbaSJan Kara 				sb->s_blocksize_bits;
17467b568cbaSJan Kara 			lastblock += block - 1;
17477b568cbaSJan Kara 			/* For loop is going to increment 'block' again */
17487b568cbaSJan Kara 			block--;
17491da177e4SLinus Torvalds 			break;
175018cf4781SJan Kara 		case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
17511da177e4SLinus Torvalds 		case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
175218cf4781SJan Kara 		case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
175318cf4781SJan Kara 		case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
17547b78fd02SJan Kara 		case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
17557b78fd02SJan Kara 			curr = get_volume_descriptor_record(ident, bh, &data);
17567b78fd02SJan Kara 			if (IS_ERR(curr)) {
17577b78fd02SJan Kara 				brelse(bh);
1758a7be300dSJan Kara 				ret = PTR_ERR(curr);
1759a7be300dSJan Kara 				goto out;
17607b78fd02SJan Kara 			}
17617b78fd02SJan Kara 			/* Descriptor we don't care about? */
17627b78fd02SJan Kara 			if (!curr)
17637b78fd02SJan Kara 				break;
17644b11111aSMarcin Slusarz 			if (vdsn >= curr->volDescSeqNum) {
17654b11111aSMarcin Slusarz 				curr->volDescSeqNum = vdsn;
17664b11111aSMarcin Slusarz 				curr->block = block;
17671da177e4SLinus Torvalds 			}
17681da177e4SLinus Torvalds 			break;
17691da177e4SLinus Torvalds 		case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
17702b8f9421SFabian Frederick 			done = true;
17711da177e4SLinus Torvalds 			break;
17721da177e4SLinus Torvalds 		}
17733bf25cb4SJan Kara 		brelse(bh);
17741da177e4SLinus Torvalds 	}
1775c0eb31edSJan Kara 	/*
1776c0eb31edSJan Kara 	 * Now read interesting descriptors again and process them
1777c0eb31edSJan Kara 	 * in a suitable order
1778c0eb31edSJan Kara 	 */
17797b78fd02SJan Kara 	if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) {
178078ace70cSJoe Perches 		udf_err(sb, "Primary Volume Descriptor not found!\n");
1781a7be300dSJan Kara 		ret = -EAGAIN;
1782a7be300dSJan Kara 		goto out;
1783c0eb31edSJan Kara 	}
17847b78fd02SJan Kara 	ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block);
1785d759bfa4SJan Kara 	if (ret < 0)
1786a7be300dSJan Kara 		goto out;
1787165923faSMarcin Slusarz 
17887b78fd02SJan Kara 	if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) {
1789d759bfa4SJan Kara 		ret = udf_load_logicalvol(sb,
17907b78fd02SJan Kara 				data.vds[VDS_POS_LOGICAL_VOL_DESC].block,
1791d759bfa4SJan Kara 				fileset);
1792d759bfa4SJan Kara 		if (ret < 0)
1793a7be300dSJan Kara 			goto out;
1794d759bfa4SJan Kara 	}
17951da177e4SLinus Torvalds 
17967b78fd02SJan Kara 	/* Now handle prevailing Partition Descriptors */
1797ee4af50cSJan Kara 	for (i = 0; i < data.num_part_descs; i++) {
1798ee4af50cSJan Kara 		ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block);
1799d759bfa4SJan Kara 		if (ret < 0)
1800a7be300dSJan Kara 			goto out;
1801d759bfa4SJan Kara 	}
1802a7be300dSJan Kara 	ret = 0;
1803a7be300dSJan Kara out:
1804a7be300dSJan Kara 	kfree(data.part_descs_loc);
1805a7be300dSJan Kara 	return ret;
18061da177e4SLinus Torvalds }
18071da177e4SLinus Torvalds 
1808d759bfa4SJan Kara /*
1809d759bfa4SJan Kara  * Load Volume Descriptor Sequence described by anchor in bh
1810d759bfa4SJan Kara  *
1811d759bfa4SJan Kara  * Returns <0 on error, 0 on success
1812d759bfa4SJan Kara  */
udf_load_sequence(struct super_block * sb,struct buffer_head * bh,struct kernel_lb_addr * fileset)181340346005SJan Kara static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
181440346005SJan Kara 			     struct kernel_lb_addr *fileset)
18151da177e4SLinus Torvalds {
18161da177e4SLinus Torvalds 	struct anchorVolDescPtr *anchor;
1817d759bfa4SJan Kara 	sector_t main_s, main_e, reserve_s, reserve_e;
1818d759bfa4SJan Kara 	int ret;
18191da177e4SLinus Torvalds 
18201da177e4SLinus Torvalds 	anchor = (struct anchorVolDescPtr *)bh->b_data;
18211da177e4SLinus Torvalds 
18221da177e4SLinus Torvalds 	/* Locate the main sequence */
182328f7c4d4SMarcin Slusarz 	main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
182428f7c4d4SMarcin Slusarz 	main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
18251da177e4SLinus Torvalds 	main_e = main_e >> sb->s_blocksize_bits;
182691c9c9ecSJan Kara 	main_e += main_s - 1;
18271da177e4SLinus Torvalds 
18281da177e4SLinus Torvalds 	/* Locate the reserve sequence */
182940346005SJan Kara 	reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
183040346005SJan Kara 	reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
18311da177e4SLinus Torvalds 	reserve_e = reserve_e >> sb->s_blocksize_bits;
183291c9c9ecSJan Kara 	reserve_e += reserve_s - 1;
18331da177e4SLinus Torvalds 
18341da177e4SLinus Torvalds 	/* Process the main & reserve sequences */
18351da177e4SLinus Torvalds 	/* responsible for finding the PartitionDesc(s) */
1836d759bfa4SJan Kara 	ret = udf_process_sequence(sb, main_s, main_e, fileset);
1837d759bfa4SJan Kara 	if (ret != -EAGAIN)
1838d759bfa4SJan Kara 		return ret;
1839bff943afSJan Kara 	udf_sb_free_partitions(sb);
1840d759bfa4SJan Kara 	ret = udf_process_sequence(sb, reserve_s, reserve_e, fileset);
1841d759bfa4SJan Kara 	if (ret < 0) {
1842bff943afSJan Kara 		udf_sb_free_partitions(sb);
1843d759bfa4SJan Kara 		/* No sequence was OK, return -EIO */
1844d759bfa4SJan Kara 		if (ret == -EAGAIN)
1845d759bfa4SJan Kara 			ret = -EIO;
1846d759bfa4SJan Kara 	}
1847d759bfa4SJan Kara 	return ret;
18481da177e4SLinus Torvalds }
18491da177e4SLinus Torvalds 
185040346005SJan Kara /*
185140346005SJan Kara  * Check whether there is an anchor block in the given block and
185240346005SJan Kara  * load Volume Descriptor Sequence if so.
1853d759bfa4SJan Kara  *
1854d759bfa4SJan Kara  * Returns <0 on error, 0 on success, -EAGAIN is special - try next anchor
1855d759bfa4SJan Kara  * block
185640346005SJan Kara  */
udf_check_anchor_block(struct super_block * sb,sector_t block,struct kernel_lb_addr * fileset)185740346005SJan Kara static int udf_check_anchor_block(struct super_block *sb, sector_t block,
185840346005SJan Kara 				  struct kernel_lb_addr *fileset)
185940346005SJan Kara {
186040346005SJan Kara 	struct buffer_head *bh;
186140346005SJan Kara 	uint16_t ident;
186240346005SJan Kara 	int ret;
186340346005SJan Kara 
186440346005SJan Kara 	bh = udf_read_tagged(sb, block, block, &ident);
186540346005SJan Kara 	if (!bh)
1866d759bfa4SJan Kara 		return -EAGAIN;
186740346005SJan Kara 	if (ident != TAG_IDENT_AVDP) {
186840346005SJan Kara 		brelse(bh);
1869d759bfa4SJan Kara 		return -EAGAIN;
187040346005SJan Kara 	}
187140346005SJan Kara 	ret = udf_load_sequence(sb, bh, fileset);
187240346005SJan Kara 	brelse(bh);
187340346005SJan Kara 	return ret;
187440346005SJan Kara }
187540346005SJan Kara 
1876d759bfa4SJan Kara /*
1877d759bfa4SJan Kara  * Search for an anchor volume descriptor pointer.
1878d759bfa4SJan Kara  *
1879d759bfa4SJan Kara  * Returns < 0 on error, 0 on success. -EAGAIN is special - try next set
1880d759bfa4SJan Kara  * of anchors.
1881d759bfa4SJan Kara  */
udf_scan_anchors(struct super_block * sb,udf_pblk_t * lastblock,struct kernel_lb_addr * fileset)1882bd904f3cSJan Kara static int udf_scan_anchors(struct super_block *sb, udf_pblk_t *lastblock,
188340346005SJan Kara 			    struct kernel_lb_addr *fileset)
188440346005SJan Kara {
1885bd904f3cSJan Kara 	udf_pblk_t last[6];
188640346005SJan Kara 	int i;
188740346005SJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
188840346005SJan Kara 	int last_count = 0;
1889d759bfa4SJan Kara 	int ret;
189040346005SJan Kara 
189140346005SJan Kara 	/* First try user provided anchor */
189240346005SJan Kara 	if (sbi->s_anchor) {
1893d759bfa4SJan Kara 		ret = udf_check_anchor_block(sb, sbi->s_anchor, fileset);
1894d759bfa4SJan Kara 		if (ret != -EAGAIN)
1895d759bfa4SJan Kara 			return ret;
189640346005SJan Kara 	}
189740346005SJan Kara 	/*
189840346005SJan Kara 	 * according to spec, anchor is in either:
189940346005SJan Kara 	 *     block 256
190040346005SJan Kara 	 *     lastblock-256
190140346005SJan Kara 	 *     lastblock
190240346005SJan Kara 	 *  however, if the disc isn't closed, it could be 512.
190340346005SJan Kara 	 */
1904d759bfa4SJan Kara 	ret = udf_check_anchor_block(sb, sbi->s_session + 256, fileset);
1905d759bfa4SJan Kara 	if (ret != -EAGAIN)
1906d759bfa4SJan Kara 		return ret;
190740346005SJan Kara 	/*
190840346005SJan Kara 	 * The trouble is which block is the last one. Drives often misreport
190940346005SJan Kara 	 * this so we try various possibilities.
191040346005SJan Kara 	 */
1911d759bfa4SJan Kara 	last[last_count++] = *lastblock;
1912d759bfa4SJan Kara 	if (*lastblock >= 1)
1913d759bfa4SJan Kara 		last[last_count++] = *lastblock - 1;
1914d759bfa4SJan Kara 	last[last_count++] = *lastblock + 1;
1915d759bfa4SJan Kara 	if (*lastblock >= 2)
1916d759bfa4SJan Kara 		last[last_count++] = *lastblock - 2;
1917d759bfa4SJan Kara 	if (*lastblock >= 150)
1918d759bfa4SJan Kara 		last[last_count++] = *lastblock - 150;
1919d759bfa4SJan Kara 	if (*lastblock >= 152)
1920d759bfa4SJan Kara 		last[last_count++] = *lastblock - 152;
192140346005SJan Kara 
192240346005SJan Kara 	for (i = 0; i < last_count; i++) {
1923e4ae4735SChristoph Hellwig 		if (last[i] >= sb_bdev_nr_blocks(sb))
192440346005SJan Kara 			continue;
1925d759bfa4SJan Kara 		ret = udf_check_anchor_block(sb, last[i], fileset);
1926d759bfa4SJan Kara 		if (ret != -EAGAIN) {
1927d759bfa4SJan Kara 			if (!ret)
1928d759bfa4SJan Kara 				*lastblock = last[i];
1929d759bfa4SJan Kara 			return ret;
1930d759bfa4SJan Kara 		}
193140346005SJan Kara 		if (last[i] < 256)
193240346005SJan Kara 			continue;
1933d759bfa4SJan Kara 		ret = udf_check_anchor_block(sb, last[i] - 256, fileset);
1934d759bfa4SJan Kara 		if (ret != -EAGAIN) {
1935d759bfa4SJan Kara 			if (!ret)
1936d759bfa4SJan Kara 				*lastblock = last[i];
1937d759bfa4SJan Kara 			return ret;
1938d759bfa4SJan Kara 		}
193940346005SJan Kara 	}
194040346005SJan Kara 
194140346005SJan Kara 	/* Finally try block 512 in case media is open */
1942d759bfa4SJan Kara 	return udf_check_anchor_block(sb, sbi->s_session + 512, fileset);
194340346005SJan Kara }
194440346005SJan Kara 
194540346005SJan Kara /*
194640346005SJan Kara  * Check Volume Structure Descriptor, find Anchor block and load Volume
1947d759bfa4SJan Kara  * Descriptor Sequence.
1948d759bfa4SJan Kara  *
1949d759bfa4SJan Kara  * Returns < 0 on error, 0 on success. -EAGAIN is special meaning anchor
1950d759bfa4SJan Kara  * block was not found.
195140346005SJan Kara  */
udf_load_vrs(struct super_block * sb,struct udf_options * uopt,int silent,struct kernel_lb_addr * fileset)195240346005SJan Kara static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
195340346005SJan Kara 			int silent, struct kernel_lb_addr *fileset)
195440346005SJan Kara {
195540346005SJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
1956ba54aef0SSteven J. Magnani 	int nsr = 0;
1957d759bfa4SJan Kara 	int ret;
195840346005SJan Kara 
195940346005SJan Kara 	if (!sb_set_blocksize(sb, uopt->blocksize)) {
196040346005SJan Kara 		if (!silent)
196178ace70cSJoe Perches 			udf_warn(sb, "Bad block size\n");
1962d759bfa4SJan Kara 		return -EINVAL;
19631da177e4SLinus Torvalds 	}
196440346005SJan Kara 	sbi->s_last_block = uopt->lastblock;
196540346005SJan Kara 	if (!uopt->novrs) {
196640346005SJan Kara 		/* Check that it is NSR02 compliant */
1967ba54aef0SSteven J. Magnani 		nsr = udf_check_vsd(sb);
1968ba54aef0SSteven J. Magnani 		if (!nsr) {
196940346005SJan Kara 			if (!silent)
197078ace70cSJoe Perches 				udf_warn(sb, "No VRS found\n");
197170f16cefSFabian Frederick 			return -EINVAL;
197240346005SJan Kara 		}
1973ba54aef0SSteven J. Magnani 		if (nsr == -1)
197444499602SPeter A. Felvegi 			udf_debug("Failed to read sector at offset %d. "
197544499602SPeter A. Felvegi 				  "Assuming open disc. Skipping validity "
197644499602SPeter A. Felvegi 				  "check\n", VSD_FIRST_SECTOR_OFFSET);
197740346005SJan Kara 		if (!sbi->s_last_block)
197840346005SJan Kara 			sbi->s_last_block = udf_get_last_block(sb);
197940346005SJan Kara 	} else {
198040346005SJan Kara 		udf_debug("Validity check skipped because of novrs option\n");
198140346005SJan Kara 	}
198240346005SJan Kara 
198340346005SJan Kara 	/* Look for anchor block and load Volume Descriptor Sequence */
198440346005SJan Kara 	sbi->s_anchor = uopt->anchor;
1985101ee137SJan Kara 	ret = udf_scan_anchors(sb, &sbi->s_last_block, fileset);
1986d759bfa4SJan Kara 	if (ret < 0) {
1987d759bfa4SJan Kara 		if (!silent && ret == -EAGAIN)
198878ace70cSJoe Perches 			udf_warn(sb, "No anchor found\n");
1989d759bfa4SJan Kara 		return ret;
199040346005SJan Kara 	}
1991d759bfa4SJan Kara 	return 0;
199240346005SJan Kara }
19931da177e4SLinus Torvalds 
udf_finalize_lvid(struct logicalVolIntegrityDesc * lvid)1994ebbd5e99SSteve Magnani static void udf_finalize_lvid(struct logicalVolIntegrityDesc *lvid)
1995ebbd5e99SSteve Magnani {
1996ebbd5e99SSteve Magnani 	struct timespec64 ts;
1997ebbd5e99SSteve Magnani 
1998ebbd5e99SSteve Magnani 	ktime_get_real_ts64(&ts);
1999ebbd5e99SSteve Magnani 	udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts);
2000ebbd5e99SSteve Magnani 	lvid->descTag.descCRC = cpu_to_le16(
2001ebbd5e99SSteve Magnani 		crc_itu_t(0, (char *)lvid + sizeof(struct tag),
2002ebbd5e99SSteve Magnani 			le16_to_cpu(lvid->descTag.descCRCLength)));
2003ebbd5e99SSteve Magnani 	lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
2004ebbd5e99SSteve Magnani }
2005ebbd5e99SSteve Magnani 
udf_open_lvid(struct super_block * sb)20061da177e4SLinus Torvalds static void udf_open_lvid(struct super_block *sb)
20071da177e4SLinus Torvalds {
20086c79e987SMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
20096c79e987SMarcin Slusarz 	struct buffer_head *bh = sbi->s_lvid_bh;
2010165923faSMarcin Slusarz 	struct logicalVolIntegrityDesc *lvid;
2011165923faSMarcin Slusarz 	struct logicalVolIntegrityDescImpUse *lvidiu;
2012146bca72SJan Kara 
2013165923faSMarcin Slusarz 	if (!bh)
2014165923faSMarcin Slusarz 		return;
201569d75671SJan Kara 	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
201669d75671SJan Kara 	lvidiu = udf_sb_lvidiu(sb);
201769d75671SJan Kara 	if (!lvidiu)
201869d75671SJan Kara 		return;
2019949f4a7cSJan Kara 
2020949f4a7cSJan Kara 	mutex_lock(&sbi->s_alloc_mutex);
20216c79e987SMarcin Slusarz 	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
20226c79e987SMarcin Slusarz 	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
2023b72e632cSJan Kara 	if (le32_to_cpu(lvid->integrityType) == LVID_INTEGRITY_TYPE_CLOSE)
2024146bca72SJan Kara 		lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
2025b72e632cSJan Kara 	else
2026b72e632cSJan Kara 		UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT);
20271da177e4SLinus Torvalds 
2028ebbd5e99SSteve Magnani 	udf_finalize_lvid(lvid);
20296c79e987SMarcin Slusarz 	mark_buffer_dirty(bh);
2030146bca72SJan Kara 	sbi->s_lvid_dirty = 0;
2031949f4a7cSJan Kara 	mutex_unlock(&sbi->s_alloc_mutex);
20329734c971SJan Kara 	/* Make opening of filesystem visible on the media immediately */
20339734c971SJan Kara 	sync_dirty_buffer(bh);
20341da177e4SLinus Torvalds }
20351da177e4SLinus Torvalds 
udf_close_lvid(struct super_block * sb)20361da177e4SLinus Torvalds static void udf_close_lvid(struct super_block *sb)
20371da177e4SLinus Torvalds {
20386c79e987SMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
20396c79e987SMarcin Slusarz 	struct buffer_head *bh = sbi->s_lvid_bh;
20406c79e987SMarcin Slusarz 	struct logicalVolIntegrityDesc *lvid;
2041165923faSMarcin Slusarz 	struct logicalVolIntegrityDescImpUse *lvidiu;
204228de7948SCyrill Gorcunov 
20436c79e987SMarcin Slusarz 	if (!bh)
20446c79e987SMarcin Slusarz 		return;
204569d75671SJan Kara 	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
204669d75671SJan Kara 	lvidiu = udf_sb_lvidiu(sb);
204769d75671SJan Kara 	if (!lvidiu)
204869d75671SJan Kara 		return;
20496c79e987SMarcin Slusarz 
2050949f4a7cSJan Kara 	mutex_lock(&sbi->s_alloc_mutex);
20516c79e987SMarcin Slusarz 	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
20526c79e987SMarcin Slusarz 	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
20536c79e987SMarcin Slusarz 	if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev))
2054165923faSMarcin Slusarz 		lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
20556c79e987SMarcin Slusarz 	if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev))
20566c79e987SMarcin Slusarz 		lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev);
20576c79e987SMarcin Slusarz 	if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev))
20586c79e987SMarcin Slusarz 		lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev);
2059b72e632cSJan Kara 	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT))
20606c79e987SMarcin Slusarz 		lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
20611da177e4SLinus Torvalds 
2062853a0c25SJan Kara 	/*
2063853a0c25SJan Kara 	 * We set buffer uptodate unconditionally here to avoid spurious
2064853a0c25SJan Kara 	 * warnings from mark_buffer_dirty() when previous EIO has marked
2065853a0c25SJan Kara 	 * the buffer as !uptodate
2066853a0c25SJan Kara 	 */
2067853a0c25SJan Kara 	set_buffer_uptodate(bh);
2068ebbd5e99SSteve Magnani 	udf_finalize_lvid(lvid);
20696c79e987SMarcin Slusarz 	mark_buffer_dirty(bh);
2070146bca72SJan Kara 	sbi->s_lvid_dirty = 0;
2071949f4a7cSJan Kara 	mutex_unlock(&sbi->s_alloc_mutex);
20729734c971SJan Kara 	/* Make closing of filesystem visible on the media immediately */
20739734c971SJan Kara 	sync_dirty_buffer(bh);
20741da177e4SLinus Torvalds }
20751da177e4SLinus Torvalds 
lvid_get_unique_id(struct super_block * sb)2076d664b6afSJan Kara u64 lvid_get_unique_id(struct super_block *sb)
2077d664b6afSJan Kara {
2078d664b6afSJan Kara 	struct buffer_head *bh;
2079d664b6afSJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
2080d664b6afSJan Kara 	struct logicalVolIntegrityDesc *lvid;
2081d664b6afSJan Kara 	struct logicalVolHeaderDesc *lvhd;
2082d664b6afSJan Kara 	u64 uniqueID;
2083d664b6afSJan Kara 	u64 ret;
2084d664b6afSJan Kara 
2085d664b6afSJan Kara 	bh = sbi->s_lvid_bh;
2086d664b6afSJan Kara 	if (!bh)
2087d664b6afSJan Kara 		return 0;
2088d664b6afSJan Kara 
2089d664b6afSJan Kara 	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
2090d664b6afSJan Kara 	lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse;
2091d664b6afSJan Kara 
2092d664b6afSJan Kara 	mutex_lock(&sbi->s_alloc_mutex);
2093d664b6afSJan Kara 	ret = uniqueID = le64_to_cpu(lvhd->uniqueID);
2094d664b6afSJan Kara 	if (!(++uniqueID & 0xFFFFFFFF))
2095d664b6afSJan Kara 		uniqueID += 16;
2096d664b6afSJan Kara 	lvhd->uniqueID = cpu_to_le64(uniqueID);
2097e8b42747SSteve Magnani 	udf_updated_lvid(sb);
2098d664b6afSJan Kara 	mutex_unlock(&sbi->s_alloc_mutex);
2099d664b6afSJan Kara 
2100d664b6afSJan Kara 	return ret;
21011da177e4SLinus Torvalds }
21021da177e4SLinus Torvalds 
udf_fill_super(struct super_block * sb,void * options,int silent)21031da177e4SLinus Torvalds static int udf_fill_super(struct super_block *sb, void *options, int silent)
21041da177e4SLinus Torvalds {
2105d759bfa4SJan Kara 	int ret = -EINVAL;
21061da177e4SLinus Torvalds 	struct inode *inode = NULL;
21071da177e4SLinus Torvalds 	struct udf_options uopt;
21085ca4e4beSPekka Enberg 	struct kernel_lb_addr rootdir, fileset;
21091da177e4SLinus Torvalds 	struct udf_sb_info *sbi;
21109181f8bfSJan Kara 	bool lvid_open = false;
21111da177e4SLinus Torvalds 
21121da177e4SLinus Torvalds 	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
2113116e5258SJan Kara 	/* By default we'll use overflow[ug]id when UDF inode [ug]id == -1 */
2114116e5258SJan Kara 	uopt.uid = make_kuid(current_user_ns(), overflowuid);
2115116e5258SJan Kara 	uopt.gid = make_kgid(current_user_ns(), overflowgid);
21161da177e4SLinus Torvalds 	uopt.umask = 0;
211787bc730cSMarcin Slusarz 	uopt.fmode = UDF_INVALID_MODE;
211887bc730cSMarcin Slusarz 	uopt.dmode = UDF_INVALID_MODE;
2119785dffe1SChengguang Xu 	uopt.nls_map = NULL;
21201da177e4SLinus Torvalds 
2121033c9da0SMarkus Elfring 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
21229db9f9e3SAlessio Igor Bogani 	if (!sbi)
21231da177e4SLinus Torvalds 		return -ENOMEM;
212428de7948SCyrill Gorcunov 
21251da177e4SLinus Torvalds 	sb->s_fs_info = sbi;
21261da177e4SLinus Torvalds 
21271e7933deSIngo Molnar 	mutex_init(&sbi->s_alloc_mutex);
21281da177e4SLinus Torvalds 
21296da80894SMiklos Szeredi 	if (!udf_parse_options((char *)options, &uopt, false))
2130fdf2657bSMarkus Elfring 		goto parse_options_failure;
21311da177e4SLinus Torvalds 
21321da177e4SLinus Torvalds 	fileset.logicalBlockNum = 0xFFFFFFFF;
21331da177e4SLinus Torvalds 	fileset.partitionReferenceNum = 0xFFFF;
21341da177e4SLinus Torvalds 
21356c79e987SMarcin Slusarz 	sbi->s_flags = uopt.flags;
21366c79e987SMarcin Slusarz 	sbi->s_uid = uopt.uid;
21376c79e987SMarcin Slusarz 	sbi->s_gid = uopt.gid;
21386c79e987SMarcin Slusarz 	sbi->s_umask = uopt.umask;
21397ac9bcd5SMarcin Slusarz 	sbi->s_fmode = uopt.fmode;
21407ac9bcd5SMarcin Slusarz 	sbi->s_dmode = uopt.dmode;
21416c79e987SMarcin Slusarz 	sbi->s_nls_map = uopt.nls_map;
2142c03cad24SJan Kara 	rwlock_init(&sbi->s_cred_lock);
21431da177e4SLinus Torvalds 
21441da177e4SLinus Torvalds 	if (uopt.session == 0xFFFFFFFF)
21456c79e987SMarcin Slusarz 		sbi->s_session = udf_get_last_session(sb);
21461da177e4SLinus Torvalds 	else
21476c79e987SMarcin Slusarz 		sbi->s_session = uopt.session;
21481da177e4SLinus Torvalds 
21496c79e987SMarcin Slusarz 	udf_debug("Multi-session=%d\n", sbi->s_session);
21501da177e4SLinus Torvalds 
21511da177e4SLinus Torvalds 	/* Fill in the rest of the superblock */
21521da177e4SLinus Torvalds 	sb->s_op = &udf_sb_ops;
2153221e583aSRasmus Rohde 	sb->s_export_op = &udf_export_ops;
2154123e9cafSChristoph Hellwig 
21551da177e4SLinus Torvalds 	sb->s_magic = UDF_SUPER_MAGIC;
21561da177e4SLinus Torvalds 	sb->s_time_gran = 1000;
21571da177e4SLinus Torvalds 
215840346005SJan Kara 	if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) {
215940346005SJan Kara 		ret = udf_load_vrs(sb, &uopt, silent, &fileset);
216040346005SJan Kara 	} else {
2161e1defc4fSMartin K. Petersen 		uopt.blocksize = bdev_logical_block_size(sb->s_bdev);
216270f16cefSFabian Frederick 		while (uopt.blocksize <= 4096) {
216340346005SJan Kara 			ret = udf_load_vrs(sb, &uopt, silent, &fileset);
216470f16cefSFabian Frederick 			if (ret < 0) {
216570f16cefSFabian Frederick 				if (!silent && ret != -EACCES) {
2166fcbf7637SSteve Magnani 					pr_notice("Scanning with blocksize %u failed\n",
216770f16cefSFabian Frederick 						  uopt.blocksize);
216870f16cefSFabian Frederick 				}
2169dc141a40SAshish Sangwan 				brelse(sbi->s_lvid_bh);
2170dc141a40SAshish Sangwan 				sbi->s_lvid_bh = NULL;
217170f16cefSFabian Frederick 				/*
217270f16cefSFabian Frederick 				 * EACCES is special - we want to propagate to
217370f16cefSFabian Frederick 				 * upper layers that we cannot handle RW mount.
217470f16cefSFabian Frederick 				 */
217570f16cefSFabian Frederick 				if (ret == -EACCES)
217670f16cefSFabian Frederick 					break;
217770f16cefSFabian Frederick 			} else
217870f16cefSFabian Frederick 				break;
217970f16cefSFabian Frederick 
218070f16cefSFabian Frederick 			uopt.blocksize <<= 1;
218140346005SJan Kara 		}
218240346005SJan Kara 	}
2183d759bfa4SJan Kara 	if (ret < 0) {
2184d759bfa4SJan Kara 		if (ret == -EAGAIN) {
218578ace70cSJoe Perches 			udf_warn(sb, "No partition found (1)\n");
2186d759bfa4SJan Kara 			ret = -EINVAL;
2187d759bfa4SJan Kara 		}
21881da177e4SLinus Torvalds 		goto error_out;
21891da177e4SLinus Torvalds 	}
21901da177e4SLinus Torvalds 
2191fcbf7637SSteve Magnani 	udf_debug("Lastblock=%u\n", sbi->s_last_block);
21921da177e4SLinus Torvalds 
21936c79e987SMarcin Slusarz 	if (sbi->s_lvid_bh) {
21944b11111aSMarcin Slusarz 		struct logicalVolIntegrityDescImpUse *lvidiu =
219569d75671SJan Kara 							udf_sb_lvidiu(sb);
219669d75671SJan Kara 		uint16_t minUDFReadRev;
219769d75671SJan Kara 		uint16_t minUDFWriteRev;
21981da177e4SLinus Torvalds 
219969d75671SJan Kara 		if (!lvidiu) {
220069d75671SJan Kara 			ret = -EINVAL;
220169d75671SJan Kara 			goto error_out;
220269d75671SJan Kara 		}
220369d75671SJan Kara 		minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev);
220469d75671SJan Kara 		minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev);
2205cb00ea35SCyrill Gorcunov 		if (minUDFReadRev > UDF_MAX_READ_VERSION) {
220678ace70cSJoe Perches 			udf_err(sb, "minUDFReadRev=%x (max is %x)\n",
220769d75671SJan Kara 				minUDFReadRev,
22081da177e4SLinus Torvalds 				UDF_MAX_READ_VERSION);
2209d759bfa4SJan Kara 			ret = -EINVAL;
22101da177e4SLinus Torvalds 			goto error_out;
2211a9ad01bcSJan Kara 		} else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) {
2212a9ad01bcSJan Kara 			if (!sb_rdonly(sb)) {
2213e729eac6SJan Kara 				ret = -EACCES;
2214e729eac6SJan Kara 				goto error_out;
2215e729eac6SJan Kara 			}
2216a9ad01bcSJan Kara 			UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
2217a9ad01bcSJan Kara 		}
22181da177e4SLinus Torvalds 
22196c79e987SMarcin Slusarz 		sbi->s_udfrev = minUDFWriteRev;
22201da177e4SLinus Torvalds 
22211da177e4SLinus Torvalds 		if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE)
22221da177e4SLinus Torvalds 			UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE);
22231da177e4SLinus Torvalds 		if (minUDFReadRev >= UDF_VERS_USE_STREAMS)
22241da177e4SLinus Torvalds 			UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS);
22251da177e4SLinus Torvalds 	}
22261da177e4SLinus Torvalds 
22276c79e987SMarcin Slusarz 	if (!sbi->s_partitions) {
222878ace70cSJoe Perches 		udf_warn(sb, "No partition found (2)\n");
2229d759bfa4SJan Kara 		ret = -EINVAL;
22301da177e4SLinus Torvalds 		goto error_out;
22311da177e4SLinus Torvalds 	}
22321da177e4SLinus Torvalds 
22334b11111aSMarcin Slusarz 	if (sbi->s_partmaps[sbi->s_partition].s_partition_flags &
2234a9ad01bcSJan Kara 			UDF_PART_FLAG_READ_ONLY) {
2235a9ad01bcSJan Kara 		if (!sb_rdonly(sb)) {
2236e729eac6SJan Kara 			ret = -EACCES;
2237e729eac6SJan Kara 			goto error_out;
2238c1a26e7dSPeter Osterlund 		}
2239a9ad01bcSJan Kara 		UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
2240a9ad01bcSJan Kara 	}
224139b3f6d6SEric Sandeen 
22422dee5aacSJan Kara 	ret = udf_find_fileset(sb, &fileset, &rootdir);
22432dee5aacSJan Kara 	if (ret < 0) {
224478ace70cSJoe Perches 		udf_warn(sb, "No fileset found\n");
22451da177e4SLinus Torvalds 		goto error_out;
22461da177e4SLinus Torvalds 	}
22471da177e4SLinus Torvalds 
2248cb00ea35SCyrill Gorcunov 	if (!silent) {
22495ca4e4beSPekka Enberg 		struct timestamp ts;
225056774805SMarcin Slusarz 		udf_time_to_disk_stamp(&ts, sbi->s_record_time);
225178ace70cSJoe Perches 		udf_info("Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
225278ace70cSJoe Perches 			 sbi->s_volume_ident,
225378ace70cSJoe Perches 			 le16_to_cpu(ts.year), ts.month, ts.day,
225456774805SMarcin Slusarz 			 ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone));
22551da177e4SLinus Torvalds 	}
2256bc98a42cSDavid Howells 	if (!sb_rdonly(sb)) {
22571da177e4SLinus Torvalds 		udf_open_lvid(sb);
22589181f8bfSJan Kara 		lvid_open = true;
22599181f8bfSJan Kara 	}
22601da177e4SLinus Torvalds 
22611da177e4SLinus Torvalds 	/* Assign the root inode */
22621da177e4SLinus Torvalds 	/* assign inodes by physical block number */
22631da177e4SLinus Torvalds 	/* perhaps it's not extensible enough, but for now ... */
226497e961fdSPekka Enberg 	inode = udf_iget(sb, &rootdir);
22656d3d5e86SJan Kara 	if (IS_ERR(inode)) {
2266fcbf7637SSteve Magnani 		udf_err(sb, "Error in udf_iget, block=%u, partition=%u\n",
22671da177e4SLinus Torvalds 		       rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
22686d3d5e86SJan Kara 		ret = PTR_ERR(inode);
22691da177e4SLinus Torvalds 		goto error_out;
22701da177e4SLinus Torvalds 	}
22711da177e4SLinus Torvalds 
22721da177e4SLinus Torvalds 	/* Allocate a dentry for the root inode */
227348fde701SAl Viro 	sb->s_root = d_make_root(inode);
2274cb00ea35SCyrill Gorcunov 	if (!sb->s_root) {
227578ace70cSJoe Perches 		udf_err(sb, "Couldn't allocate root dentry\n");
2276d759bfa4SJan Kara 		ret = -ENOMEM;
22771da177e4SLinus Torvalds 		goto error_out;
22781da177e4SLinus Torvalds 	}
2279c2efd13aSJan Kara 	sb->s_maxbytes = UDF_MAX_FILESIZE;
22808de52778SAl Viro 	sb->s_max_links = UDF_MAX_LINKS;
22811da177e4SLinus Torvalds 	return 0;
22821da177e4SLinus Torvalds 
22831da177e4SLinus Torvalds error_out:
22846c79e987SMarcin Slusarz 	iput(sbi->s_vat_inode);
2285fdf2657bSMarkus Elfring parse_options_failure:
2286785dffe1SChengguang Xu 	unload_nls(uopt.nls_map);
22879181f8bfSJan Kara 	if (lvid_open)
22881da177e4SLinus Torvalds 		udf_close_lvid(sb);
22896c79e987SMarcin Slusarz 	brelse(sbi->s_lvid_bh);
2290bff943afSJan Kara 	udf_sb_free_partitions(sb);
22911da177e4SLinus Torvalds 	kfree(sbi);
22921da177e4SLinus Torvalds 	sb->s_fs_info = NULL;
229328de7948SCyrill Gorcunov 
2294d759bfa4SJan Kara 	return ret;
22951da177e4SLinus Torvalds }
22961da177e4SLinus Torvalds 
_udf_err(struct super_block * sb,const char * function,const char * fmt,...)22978076c363SJoe Perches void _udf_err(struct super_block *sb, const char *function,
22981da177e4SLinus Torvalds 	      const char *fmt, ...)
22991da177e4SLinus Torvalds {
2300c2bff36cSJoe Perches 	struct va_format vaf;
23011da177e4SLinus Torvalds 	va_list args;
23021da177e4SLinus Torvalds 
23031da177e4SLinus Torvalds 	va_start(args, fmt);
2304c2bff36cSJoe Perches 
2305c2bff36cSJoe Perches 	vaf.fmt = fmt;
2306c2bff36cSJoe Perches 	vaf.va = &args;
2307c2bff36cSJoe Perches 
2308c2bff36cSJoe Perches 	pr_err("error (device %s): %s: %pV", sb->s_id, function, &vaf);
2309c2bff36cSJoe Perches 
23101da177e4SLinus Torvalds 	va_end(args);
23111da177e4SLinus Torvalds }
23121da177e4SLinus Torvalds 
_udf_warn(struct super_block * sb,const char * function,const char * fmt,...)2313a40ecd7bSJoe Perches void _udf_warn(struct super_block *sb, const char *function,
23141da177e4SLinus Torvalds 	       const char *fmt, ...)
23151da177e4SLinus Torvalds {
2316c2bff36cSJoe Perches 	struct va_format vaf;
23171da177e4SLinus Torvalds 	va_list args;
23181da177e4SLinus Torvalds 
23191da177e4SLinus Torvalds 	va_start(args, fmt);
2320c2bff36cSJoe Perches 
2321c2bff36cSJoe Perches 	vaf.fmt = fmt;
2322c2bff36cSJoe Perches 	vaf.va = &args;
2323c2bff36cSJoe Perches 
2324c2bff36cSJoe Perches 	pr_warn("warning (device %s): %s: %pV", sb->s_id, function, &vaf);
2325c2bff36cSJoe Perches 
23261da177e4SLinus Torvalds 	va_end(args);
23271da177e4SLinus Torvalds }
23281da177e4SLinus Torvalds 
udf_put_super(struct super_block * sb)2329cb00ea35SCyrill Gorcunov static void udf_put_super(struct super_block *sb)
23301da177e4SLinus Torvalds {
23316c79e987SMarcin Slusarz 	struct udf_sb_info *sbi;
23321da177e4SLinus Torvalds 
23336c79e987SMarcin Slusarz 	sbi = UDF_SB(sb);
23346cfd0148SChristoph Hellwig 
23356c79e987SMarcin Slusarz 	iput(sbi->s_vat_inode);
23366c79e987SMarcin Slusarz 	unload_nls(sbi->s_nls_map);
2337bc98a42cSDavid Howells 	if (!sb_rdonly(sb))
23381da177e4SLinus Torvalds 		udf_close_lvid(sb);
23396c79e987SMarcin Slusarz 	brelse(sbi->s_lvid_bh);
2340bff943afSJan Kara 	udf_sb_free_partitions(sb);
2341bbe48dd8SFabian Frederick 	mutex_destroy(&sbi->s_alloc_mutex);
23421da177e4SLinus Torvalds 	kfree(sb->s_fs_info);
23431da177e4SLinus Torvalds 	sb->s_fs_info = NULL;
23441da177e4SLinus Torvalds }
23451da177e4SLinus Torvalds 
udf_sync_fs(struct super_block * sb,int wait)2346146bca72SJan Kara static int udf_sync_fs(struct super_block *sb, int wait)
2347146bca72SJan Kara {
2348146bca72SJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
2349146bca72SJan Kara 
2350146bca72SJan Kara 	mutex_lock(&sbi->s_alloc_mutex);
2351146bca72SJan Kara 	if (sbi->s_lvid_dirty) {
2352e8b42747SSteve Magnani 		struct buffer_head *bh = sbi->s_lvid_bh;
2353e8b42747SSteve Magnani 		struct logicalVolIntegrityDesc *lvid;
2354e8b42747SSteve Magnani 
2355e8b42747SSteve Magnani 		lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
2356e8b42747SSteve Magnani 		udf_finalize_lvid(lvid);
2357e8b42747SSteve Magnani 
2358146bca72SJan Kara 		/*
2359146bca72SJan Kara 		 * Blockdevice will be synced later so we don't have to submit
2360146bca72SJan Kara 		 * the buffer for IO
2361146bca72SJan Kara 		 */
2362e8b42747SSteve Magnani 		mark_buffer_dirty(bh);
2363146bca72SJan Kara 		sbi->s_lvid_dirty = 0;
2364146bca72SJan Kara 	}
2365146bca72SJan Kara 	mutex_unlock(&sbi->s_alloc_mutex);
2366146bca72SJan Kara 
2367146bca72SJan Kara 	return 0;
2368146bca72SJan Kara }
2369146bca72SJan Kara 
udf_statfs(struct dentry * dentry,struct kstatfs * buf)2370cb00ea35SCyrill Gorcunov static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
23711da177e4SLinus Torvalds {
2372726c3342SDavid Howells 	struct super_block *sb = dentry->d_sb;
23736c79e987SMarcin Slusarz 	struct udf_sb_info *sbi = UDF_SB(sb);
23746c79e987SMarcin Slusarz 	struct logicalVolIntegrityDescImpUse *lvidiu;
2375557f5a14SColy Li 	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
23766c79e987SMarcin Slusarz 
237769d75671SJan Kara 	lvidiu = udf_sb_lvidiu(sb);
23781da177e4SLinus Torvalds 	buf->f_type = UDF_SUPER_MAGIC;
23791da177e4SLinus Torvalds 	buf->f_bsize = sb->s_blocksize;
23806c79e987SMarcin Slusarz 	buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len;
23811da177e4SLinus Torvalds 	buf->f_bfree = udf_count_free(sb);
23821da177e4SLinus Torvalds 	buf->f_bavail = buf->f_bfree;
2383356557beSJan Kara 	/*
2384356557beSJan Kara 	 * Let's pretend each free block is also a free 'inode' since UDF does
2385356557beSJan Kara 	 * not have separate preallocated table of inodes.
2386356557beSJan Kara 	 */
23876c79e987SMarcin Slusarz 	buf->f_files = (lvidiu != NULL ? (le32_to_cpu(lvidiu->numFiles) +
23886c79e987SMarcin Slusarz 					  le32_to_cpu(lvidiu->numDirs)) : 0)
23896c79e987SMarcin Slusarz 			+ buf->f_bfree;
23901da177e4SLinus Torvalds 	buf->f_ffree = buf->f_bfree;
23919fba7056SAndrew Gabbasov 	buf->f_namelen = UDF_NAME_LEN;
23926d1349c7SAl Viro 	buf->f_fsid = u64_to_fsid(id);
23931da177e4SLinus Torvalds 
23941da177e4SLinus Torvalds 	return 0;
23951da177e4SLinus Torvalds }
23961da177e4SLinus Torvalds 
udf_count_free_bitmap(struct super_block * sb,struct udf_bitmap * bitmap)23974b11111aSMarcin Slusarz static unsigned int udf_count_free_bitmap(struct super_block *sb,
23984b11111aSMarcin Slusarz 					  struct udf_bitmap *bitmap)
23991da177e4SLinus Torvalds {
24001da177e4SLinus Torvalds 	struct buffer_head *bh = NULL;
24011da177e4SLinus Torvalds 	unsigned int accum = 0;
24021da177e4SLinus Torvalds 	int index;
2403b490bdd6SSteve Magnani 	udf_pblk_t block = 0, newblock;
24045ca4e4beSPekka Enberg 	struct kernel_lb_addr loc;
24051da177e4SLinus Torvalds 	uint32_t bytes;
24061da177e4SLinus Torvalds 	uint8_t *ptr;
24071da177e4SLinus Torvalds 	uint16_t ident;
24081da177e4SLinus Torvalds 	struct spaceBitmapDesc *bm;
24091da177e4SLinus Torvalds 
24101da177e4SLinus Torvalds 	loc.logicalBlockNum = bitmap->s_extPosition;
24116c79e987SMarcin Slusarz 	loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
241297e961fdSPekka Enberg 	bh = udf_read_ptagged(sb, &loc, 0, &ident);
24131da177e4SLinus Torvalds 
2414cb00ea35SCyrill Gorcunov 	if (!bh) {
241578ace70cSJoe Perches 		udf_err(sb, "udf_count_free failed\n");
24161da177e4SLinus Torvalds 		goto out;
2417cb00ea35SCyrill Gorcunov 	} else if (ident != TAG_IDENT_SBD) {
24183bf25cb4SJan Kara 		brelse(bh);
241978ace70cSJoe Perches 		udf_err(sb, "udf_count_free failed\n");
24201da177e4SLinus Torvalds 		goto out;
24211da177e4SLinus Torvalds 	}
24221da177e4SLinus Torvalds 
24231da177e4SLinus Torvalds 	bm = (struct spaceBitmapDesc *)bh->b_data;
24241da177e4SLinus Torvalds 	bytes = le32_to_cpu(bm->numOfBytes);
24251da177e4SLinus Torvalds 	index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
24261da177e4SLinus Torvalds 	ptr = (uint8_t *)bh->b_data;
24271da177e4SLinus Torvalds 
2428cb00ea35SCyrill Gorcunov 	while (bytes > 0) {
242901b954a3SMarcin Slusarz 		u32 cur_bytes = min_t(u32, bytes, sb->s_blocksize - index);
243001b954a3SMarcin Slusarz 		accum += bitmap_weight((const unsigned long *)(ptr + index),
243101b954a3SMarcin Slusarz 					cur_bytes * 8);
243201b954a3SMarcin Slusarz 		bytes -= cur_bytes;
2433cb00ea35SCyrill Gorcunov 		if (bytes) {
24343bf25cb4SJan Kara 			brelse(bh);
243597e961fdSPekka Enberg 			newblock = udf_get_lb_pblock(sb, &loc, ++block);
2436101ee137SJan Kara 			bh = sb_bread(sb, newblock);
2437cb00ea35SCyrill Gorcunov 			if (!bh) {
24381da177e4SLinus Torvalds 				udf_debug("read failed\n");
24391da177e4SLinus Torvalds 				goto out;
24401da177e4SLinus Torvalds 			}
24411da177e4SLinus Torvalds 			index = 0;
24421da177e4SLinus Torvalds 			ptr = (uint8_t *)bh->b_data;
24431da177e4SLinus Torvalds 		}
24441da177e4SLinus Torvalds 	}
24453bf25cb4SJan Kara 	brelse(bh);
24461da177e4SLinus Torvalds out:
24471da177e4SLinus Torvalds 	return accum;
24481da177e4SLinus Torvalds }
24491da177e4SLinus Torvalds 
udf_count_free_table(struct super_block * sb,struct inode * table)24504b11111aSMarcin Slusarz static unsigned int udf_count_free_table(struct super_block *sb,
24514b11111aSMarcin Slusarz 					 struct inode *table)
24521da177e4SLinus Torvalds {
24531da177e4SLinus Torvalds 	unsigned int accum = 0;
2454ff116fc8SJan Kara 	uint32_t elen;
24555ca4e4beSPekka Enberg 	struct kernel_lb_addr eloc;
2456ff116fc8SJan Kara 	struct extent_position epos;
2457*5fc8da4dSZhao Mengmeng 	int8_t etype;
24581da177e4SLinus Torvalds 
2459d1668fe3SJan Kara 	mutex_lock(&UDF_SB(sb)->s_alloc_mutex);
2460c0b34438SMarcin Slusarz 	epos.block = UDF_I(table)->i_location;
2461ff116fc8SJan Kara 	epos.offset = sizeof(struct unallocSpaceEntry);
2462ff116fc8SJan Kara 	epos.bh = NULL;
24631da177e4SLinus Torvalds 
2464*5fc8da4dSZhao Mengmeng 	while (udf_next_aext(table, &epos, &eloc, &elen, &etype, 1) > 0)
24651da177e4SLinus Torvalds 		accum += (elen >> table->i_sb->s_blocksize_bits);
24663a71fc5dSMarcin Slusarz 
24673bf25cb4SJan Kara 	brelse(epos.bh);
2468d1668fe3SJan Kara 	mutex_unlock(&UDF_SB(sb)->s_alloc_mutex);
24691da177e4SLinus Torvalds 
24701da177e4SLinus Torvalds 	return accum;
24711da177e4SLinus Torvalds }
24721da177e4SLinus Torvalds 
udf_count_free(struct super_block * sb)2473cb00ea35SCyrill Gorcunov static unsigned int udf_count_free(struct super_block *sb)
24741da177e4SLinus Torvalds {
24751da177e4SLinus Torvalds 	unsigned int accum = 0;
2476a4a8b99eSJan Kara 	struct udf_sb_info *sbi = UDF_SB(sb);
24776c79e987SMarcin Slusarz 	struct udf_part_map *map;
2478a4a8b99eSJan Kara 	unsigned int part = sbi->s_partition;
2479a4a8b99eSJan Kara 	int ptype = sbi->s_partmaps[part].s_partition_type;
24801da177e4SLinus Torvalds 
2481a4a8b99eSJan Kara 	if (ptype == UDF_METADATA_MAP25) {
2482a4a8b99eSJan Kara 		part = sbi->s_partmaps[part].s_type_specific.s_metadata.
2483a4a8b99eSJan Kara 							s_phys_partition_ref;
2484a4a8b99eSJan Kara 	} else if (ptype == UDF_VIRTUAL_MAP15 || ptype == UDF_VIRTUAL_MAP20) {
2485a4a8b99eSJan Kara 		/*
2486a4a8b99eSJan Kara 		 * Filesystems with VAT are append-only and we cannot write to
2487a4a8b99eSJan Kara  		 * them. Let's just report 0 here.
2488a4a8b99eSJan Kara 		 */
2489a4a8b99eSJan Kara 		return 0;
2490a4a8b99eSJan Kara 	}
2491a4a8b99eSJan Kara 
24926c79e987SMarcin Slusarz 	if (sbi->s_lvid_bh) {
24934b11111aSMarcin Slusarz 		struct logicalVolIntegrityDesc *lvid =
24944b11111aSMarcin Slusarz 			(struct logicalVolIntegrityDesc *)
24954b11111aSMarcin Slusarz 			sbi->s_lvid_bh->b_data;
2496a4a8b99eSJan Kara 		if (le32_to_cpu(lvid->numOfPartitions) > part) {
24974b11111aSMarcin Slusarz 			accum = le32_to_cpu(
2498a4a8b99eSJan Kara 					lvid->freeSpaceTable[part]);
24991da177e4SLinus Torvalds 			if (accum == 0xFFFFFFFF)
25001da177e4SLinus Torvalds 				accum = 0;
25011da177e4SLinus Torvalds 		}
25021da177e4SLinus Torvalds 	}
25031da177e4SLinus Torvalds 
25041da177e4SLinus Torvalds 	if (accum)
25051da177e4SLinus Torvalds 		return accum;
25061da177e4SLinus Torvalds 
2507a4a8b99eSJan Kara 	map = &sbi->s_partmaps[part];
25086c79e987SMarcin Slusarz 	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
250928de7948SCyrill Gorcunov 		accum += udf_count_free_bitmap(sb,
25106c79e987SMarcin Slusarz 					       map->s_uspace.s_bitmap);
25111da177e4SLinus Torvalds 	}
25121da177e4SLinus Torvalds 	if (accum)
25131da177e4SLinus Torvalds 		return accum;
25141da177e4SLinus Torvalds 
25156c79e987SMarcin Slusarz 	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
251628de7948SCyrill Gorcunov 		accum += udf_count_free_table(sb,
25176c79e987SMarcin Slusarz 					      map->s_uspace.s_table);
25181da177e4SLinus Torvalds 	}
25191da177e4SLinus Torvalds 	return accum;
25201da177e4SLinus Torvalds }
252154bb60d5SFabian Frederick 
252254bb60d5SFabian Frederick MODULE_AUTHOR("Ben Fennema");
252354bb60d5SFabian Frederick MODULE_DESCRIPTION("Universal Disk Format Filesystem");
252454bb60d5SFabian Frederick MODULE_LICENSE("GPL");
252554bb60d5SFabian Frederick module_init(init_udf_fs)
252654bb60d5SFabian Frederick module_exit(exit_udf_fs)
2527