Blame view

fs/udf/super.c 66.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  /*
   * super.c
   *
   * PURPOSE
   *  Super block routines for the OSTA-UDF(tm) filesystem.
   *
   * DESCRIPTION
   *  OSTA-UDF(tm) = Optical Storage Technology Association
   *  Universal Disk Format.
   *
   *  This code is based on version 2.00 of the UDF specification,
   *  and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
   *    http://www.osta.org/
   *    http://www.ecma.ch/
   *    http://www.iso.org/
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
   * COPYRIGHT
   *  This file is distributed under the terms of the GNU General Public
   *  License (GPL). Copies of the GPL can be obtained from:
   *    ftp://prep.ai.mit.edu/pub/gnu/GPL
   *  Each contributing author retains all rights to their own work.
   *
   *  (C) 1998 Dave Boynton
   *  (C) 1998-2004 Ben Fennema
   *  (C) 2000 Stelias Computing Inc
   *
   * HISTORY
   *
   *  09/24/98 dgb  changed to allow compiling outside of kernel, and
   *                added some debugging.
   *  10/01/98 dgb  updated to allow (some) possibility of compiling w/2.0.34
   *  10/16/98      attempting some multi-session support
   *  10/17/98      added freespace count for "df"
   *  11/11/98 gr   added novrs option
   *  11/26/98 dgb  added fileset,anchor mount options
3a71fc5de   Marcin Slusarz   udf: fix coding s...
36
37
   *  12/06/98 blf  really hosed things royally. vat/sparing support. sequenced
   *                vol descs. rewrote option handling based on isofs
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
   *  12/20/98      find the free space bitmap (if it exists)
   */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
40
  #include "udfdecl.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
43
44
45
46
47
48
49
  #include <linux/blkdev.h>
  #include <linux/slab.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/parser.h>
  #include <linux/stat.h>
  #include <linux/cdrom.h>
  #include <linux/nls.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
  #include <linux/vfs.h>
  #include <linux/vmalloc.h>
dc5d39be6   Marcin Slusarz   udf: convert UDF_...
52
  #include <linux/errno.h>
6da80894c   Miklos Szeredi   mount options: fi...
53
54
  #include <linux/mount.h>
  #include <linux/seq_file.h>
01b954a36   Marcin Slusarz   udf: convert udf_...
55
  #include <linux/bitmap.h>
f845fced9   Bob Copeland   udf: use crc_itu_...
56
  #include <linux/crc-itu-t.h>
1df2ae31c   Jan Kara   udf: Fortify load...
57
  #include <linux/log2.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
  #include <asm/byteorder.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
  #include "udf_sb.h"
  #include "udf_i.h"
  
  #include <linux/init.h>
e973606cc   Fabian Frederick   udf: use linux/ua...
63
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64

4b8d42521   Jan Kara   udf: Convert desc...
65
66
67
68
  enum {
  	VDS_POS_PRIMARY_VOL_DESC,
  	VDS_POS_UNALLOC_SPACE_DESC,
  	VDS_POS_LOGICAL_VOL_DESC,
4b8d42521   Jan Kara   udf: Convert desc...
69
  	VDS_POS_IMP_USE_VOL_DESC,
4b8d42521   Jan Kara   udf: Convert desc...
70
71
  	VDS_POS_LENGTH
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72

444996027   Peter A. Felvegi   udf: fix for path...
73
74
  #define VSD_FIRST_SECTOR_OFFSET		32768
  #define VSD_MAX_SECTOR_OFFSET		0x800000
a47241cde   Alden Tondettar   udf: Prevent stac...
75
76
77
78
79
80
81
82
  /*
   * Maximum number of Terminating Descriptor / Logical Volume Integrity
   * Descriptor redirections. The chosen numbers are arbitrary - just that we
   * hopefully don't limit any real use of rewritten inode on write-once media
   * but avoid looping for too long on corrupted media.
   */
  #define UDF_MAX_TD_NESTING 64
  #define UDF_MAX_LVID_NESTING 1000
8de527787   Al Viro   vfs: check i_nlin...
83
  enum { UDF_MAX_LINKS = 0xffff };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
  /* These are the "meat" - everything else is stuffing */
  static int udf_fill_super(struct super_block *, void *, int);
  static void udf_put_super(struct super_block *);
146bca72c   Jan Kara   udf: Don't write ...
87
  static int udf_sync_fs(struct super_block *, int);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  static int udf_remount_fs(struct super_block *, int *, char *);
5ca4e4be8   Pekka Enberg   Remove struct typ...
89
  static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
91
92
  static void udf_open_lvid(struct super_block *);
  static void udf_close_lvid(struct super_block *);
  static unsigned int udf_count_free(struct super_block *);
726c33422   David Howells   [PATCH] VFS: Perm...
93
  static int udf_statfs(struct dentry *, struct kstatfs *);
34c80b1d9   Al Viro   vfs: switch ->sho...
94
  static int udf_show_options(struct seq_file *, struct dentry *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95

69d75671d   Jan Kara   udf: Fortify LVID...
96
  struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb)
6c79e987d   Marcin Slusarz   udf: remove some ...
97
  {
69d75671d   Jan Kara   udf: Fortify LVID...
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  	struct logicalVolIntegrityDesc *lvid;
  	unsigned int partnum;
  	unsigned int offset;
  
  	if (!UDF_SB(sb)->s_lvid_bh)
  		return NULL;
  	lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data;
  	partnum = le32_to_cpu(lvid->numOfPartitions);
  	if ((sb->s_blocksize - sizeof(struct logicalVolIntegrityDescImpUse) -
  	     offsetof(struct logicalVolIntegrityDesc, impUse)) /
  	     (2 * sizeof(uint32_t)) < partnum) {
  		udf_err(sb, "Logical volume integrity descriptor corrupted "
  			"(numOfPartitions = %u)!
  ", partnum);
  		return NULL;
  	}
  	/* The offset is to skip freeSpaceTable and sizeTable arrays */
  	offset = partnum * 2 * sizeof(uint32_t);
6c79e987d   Marcin Slusarz   udf: remove some ...
116
117
  	return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
  /* UDF filesystem type */
152a08366   Al Viro   new helper: mount...
119
120
  static struct dentry *udf_mount(struct file_system_type *fs_type,
  		      int flags, const char *dev_name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
  {
152a08366   Al Viro   new helper: mount...
122
  	return mount_bdev(fs_type, flags, dev_name, data, udf_fill_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
125
  }
  
  static struct file_system_type udf_fstype = {
28de7948a   Cyrill Gorcunov   UDF: coding style...
126
127
  	.owner		= THIS_MODULE,
  	.name		= "udf",
152a08366   Al Viro   new helper: mount...
128
  	.mount		= udf_mount,
28de7948a   Cyrill Gorcunov   UDF: coding style...
129
130
  	.kill_sb	= kill_block_super,
  	.fs_flags	= FS_REQUIRES_DEV,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  };
3e64fe5b2   Eric W. Biederman   fs: Limit sys_mou...
132
  MODULE_ALIAS_FS("udf");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133

cb00ea352   Cyrill Gorcunov   UDF: coding style...
134
  static struct kmem_cache *udf_inode_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
137
138
  
  static struct inode *udf_alloc_inode(struct super_block *sb)
  {
  	struct udf_inode_info *ei;
3a71fc5de   Marcin Slusarz   udf: fix coding s...
139
  	ei = kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
  	if (!ei)
  		return NULL;
95f8797f4   Dan Bastone   [PATCH] initializ...
142
143
144
  
  	ei->i_unique = 0;
  	ei->i_lenExtents = 0;
ab9a3a737   Steven J. Magnani   udf: reduce leaka...
145
  	ei->i_lenStreams = 0;
95f8797f4   Dan Bastone   [PATCH] initializ...
146
147
148
  	ei->i_next_alloc_block = 0;
  	ei->i_next_alloc_goal = 0;
  	ei->i_strat4096 = 0;
ab9a3a737   Steven J. Magnani   udf: reduce leaka...
149
  	ei->i_streamdir = 0;
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
150
  	init_rwsem(&ei->i_data_sem);
99600051b   Namjae Jeon   udf: add extent c...
151
152
  	ei->cached_extent.lstart = -1;
  	spin_lock_init(&ei->i_extent_cache_lock);
95f8797f4   Dan Bastone   [PATCH] initializ...
153

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
  	return &ei->vfs_inode;
  }
a78bb3838   Al Viro   udf: switch to ->...
156
  static void udf_free_in_core_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
  {
  	kmem_cache_free(udf_inode_cachep, UDF_I(inode));
  }
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
160
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
162
  	struct udf_inode_info *ei = (struct udf_inode_info *)foo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163

a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
164
165
  	ei->i_ext.i_data = NULL;
  	inode_init_once(&ei->vfs_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
  }
53ea18de2   Fabian Frederick   udf: Add __init m...
167
  static int __init init_inodecache(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
  {
  	udf_inode_cachep = kmem_cache_create("udf_inode_cache",
  					     sizeof(struct udf_inode_info),
cb00ea352   Cyrill Gorcunov   UDF: coding style...
171
  					     0, (SLAB_RECLAIM_ACCOUNT |
5d097056c   Vladimir Davydov   kmemcg: account c...
172
173
  						 SLAB_MEM_SPREAD |
  						 SLAB_ACCOUNT),
20c2df83d   Paul Mundt   mm: Remove slab d...
174
  					     init_once);
28de7948a   Cyrill Gorcunov   UDF: coding style...
175
  	if (!udf_inode_cachep)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
178
179
180
181
  		return -ENOMEM;
  	return 0;
  }
  
  static void destroy_inodecache(void)
  {
8c0a85377   Kirill A. Shutemov   fs: push rcu_barr...
182
183
184
185
186
  	/*
  	 * Make sure all delayed rcu free inodes are flushed before we
  	 * destroy cache.
  	 */
  	rcu_barrier();
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
187
  	kmem_cache_destroy(udf_inode_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
  }
  
  /* Superblock operations */
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
191
  static const struct super_operations udf_sb_ops = {
28de7948a   Cyrill Gorcunov   UDF: coding style...
192
  	.alloc_inode	= udf_alloc_inode,
a78bb3838   Al Viro   udf: switch to ->...
193
  	.free_inode	= udf_free_in_core_inode,
28de7948a   Cyrill Gorcunov   UDF: coding style...
194
  	.write_inode	= udf_write_inode,
3aac2b62e   Al Viro   switch udf to ->e...
195
  	.evict_inode	= udf_evict_inode,
28de7948a   Cyrill Gorcunov   UDF: coding style...
196
  	.put_super	= udf_put_super,
146bca72c   Jan Kara   udf: Don't write ...
197
  	.sync_fs	= udf_sync_fs,
28de7948a   Cyrill Gorcunov   UDF: coding style...
198
199
  	.statfs		= udf_statfs,
  	.remount_fs	= udf_remount_fs,
6da80894c   Miklos Szeredi   mount options: fi...
200
  	.show_options	= udf_show_options,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  };
cb00ea352   Cyrill Gorcunov   UDF: coding style...
202
  struct udf_options {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
  	unsigned char novrs;
  	unsigned int blocksize;
  	unsigned int session;
  	unsigned int lastblock;
  	unsigned int anchor;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  	unsigned int flags;
faa17292f   Al Viro   udf: propagate um...
209
  	umode_t umask;
c2ba138a2   Eric W. Biederman   userns: Convert t...
210
211
  	kgid_t gid;
  	kuid_t uid;
faa17292f   Al Viro   udf: propagate um...
212
213
  	umode_t fmode;
  	umode_t dmode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
216
217
218
219
  	struct nls_table *nls_map;
  };
  
  static int __init init_udf_fs(void)
  {
  	int err;
28de7948a   Cyrill Gorcunov   UDF: coding style...
220

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
224
225
226
  	err = init_inodecache();
  	if (err)
  		goto out1;
  	err = register_filesystem(&udf_fstype);
  	if (err)
  		goto out;
28de7948a   Cyrill Gorcunov   UDF: coding style...
227

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
  	return 0;
28de7948a   Cyrill Gorcunov   UDF: coding style...
229
230
  
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  	destroy_inodecache();
28de7948a   Cyrill Gorcunov   UDF: coding style...
232
233
  
  out1:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
237
238
239
240
241
  	return err;
  }
  
  static void __exit exit_udf_fs(void)
  {
  	unregister_filesystem(&udf_fstype);
  	destroy_inodecache();
  }
dc5d39be6   Marcin Slusarz   udf: convert UDF_...
242
243
244
  static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count)
  {
  	struct udf_sb_info *sbi = UDF_SB(sb);
033c9da00   Markus Elfring   fs-udf: Improve s...
245
  	sbi->s_partmaps = kcalloc(count, sizeof(*sbi->s_partmaps), GFP_KERNEL);
dc5d39be6   Marcin Slusarz   udf: convert UDF_...
246
  	if (!sbi->s_partmaps) {
dc5d39be6   Marcin Slusarz   udf: convert UDF_...
247
248
249
250
251
252
253
  		sbi->s_partitions = 0;
  		return -ENOMEM;
  	}
  
  	sbi->s_partitions = count;
  	return 0;
  }
bff943af6   Jan Kara   udf: Fix memory l...
254
255
256
257
  static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
  {
  	int i;
  	int nr_groups = bitmap->s_nr_groups;
bff943af6   Jan Kara   udf: Fix memory l...
258
259
  
  	for (i = 0; i < nr_groups; i++)
4eb09e111   Markus Elfring   fs-udf: Delete an...
260
  		brelse(bitmap->s_block_bitmap[i]);
bff943af6   Jan Kara   udf: Fix memory l...
261

1d5cfdb07   Tetsuo Handa   tree wide: use kv...
262
  	kvfree(bitmap);
bff943af6   Jan Kara   udf: Fix memory l...
263
264
265
266
267
268
269
270
271
  }
  
  static void udf_free_partition(struct udf_part_map *map)
  {
  	int i;
  	struct udf_meta_data *mdata;
  
  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
  		iput(map->s_uspace.s_table);
bff943af6   Jan Kara   udf: Fix memory l...
272
273
  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
  		udf_sb_free_bitmap(map->s_uspace.s_bitmap);
bff943af6   Jan Kara   udf: Fix memory l...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  	if (map->s_partition_type == UDF_SPARABLE_MAP15)
  		for (i = 0; i < 4; i++)
  			brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
  	else if (map->s_partition_type == UDF_METADATA_MAP25) {
  		mdata = &map->s_type_specific.s_metadata;
  		iput(mdata->s_metadata_fe);
  		mdata->s_metadata_fe = NULL;
  
  		iput(mdata->s_mirror_fe);
  		mdata->s_mirror_fe = NULL;
  
  		iput(mdata->s_bitmap_fe);
  		mdata->s_bitmap_fe = NULL;
  	}
  }
  
  static void udf_sb_free_partitions(struct super_block *sb)
  {
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	int i;
ba2eb866a   Markus Elfring   fs-udf: Adjust tw...
294
295
  
  	if (!sbi->s_partmaps)
1b1baff6e   Namjae Jeon   UDF: Fix a null p...
296
  		return;
bff943af6   Jan Kara   udf: Fix memory l...
297
298
299
300
301
  	for (i = 0; i < sbi->s_partitions; i++)
  		udf_free_partition(&sbi->s_partmaps[i]);
  	kfree(sbi->s_partmaps);
  	sbi->s_partmaps = NULL;
  }
34c80b1d9   Al Viro   vfs: switch ->sho...
302
  static int udf_show_options(struct seq_file *seq, struct dentry *root)
6da80894c   Miklos Szeredi   mount options: fi...
303
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
304
  	struct super_block *sb = root->d_sb;
6da80894c   Miklos Szeredi   mount options: fi...
305
306
307
308
  	struct udf_sb_info *sbi = UDF_SB(sb);
  
  	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT))
  		seq_puts(seq, ",nostrict");
1197e4dfc   Clemens Ladisch   udf: use hardware...
309
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET))
6da80894c   Miklos Szeredi   mount options: fi...
310
311
312
313
314
315
316
317
318
319
320
  		seq_printf(seq, ",bs=%lu", sb->s_blocksize);
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE))
  		seq_puts(seq, ",unhide");
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE))
  		seq_puts(seq, ",undelete");
  	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_USE_AD_IN_ICB))
  		seq_puts(seq, ",noadinicb");
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_USE_SHORT_AD))
  		seq_puts(seq, ",shortad");
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_FORGET))
  		seq_puts(seq, ",uid=forget");
6da80894c   Miklos Szeredi   mount options: fi...
321
322
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_FORGET))
  		seq_puts(seq, ",gid=forget");
6da80894c   Miklos Szeredi   mount options: fi...
323
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET))
c2ba138a2   Eric W. Biederman   userns: Convert t...
324
  		seq_printf(seq, ",uid=%u", from_kuid(&init_user_ns, sbi->s_uid));
6da80894c   Miklos Szeredi   mount options: fi...
325
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
c2ba138a2   Eric W. Biederman   userns: Convert t...
326
  		seq_printf(seq, ",gid=%u", from_kgid(&init_user_ns, sbi->s_gid));
6da80894c   Miklos Szeredi   mount options: fi...
327
  	if (sbi->s_umask != 0)
faa17292f   Al Viro   udf: propagate um...
328
  		seq_printf(seq, ",umask=%ho", sbi->s_umask);
87bc730c0   Marcin Slusarz   udf: fix default ...
329
  	if (sbi->s_fmode != UDF_INVALID_MODE)
faa17292f   Al Viro   udf: propagate um...
330
  		seq_printf(seq, ",mode=%ho", sbi->s_fmode);
87bc730c0   Marcin Slusarz   udf: fix default ...
331
  	if (sbi->s_dmode != UDF_INVALID_MODE)
faa17292f   Al Viro   udf: propagate um...
332
  		seq_printf(seq, ",dmode=%ho", sbi->s_dmode);
6da80894c   Miklos Szeredi   mount options: fi...
333
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
fcbf7637e   Steve Magnani   udf: Fix signed/u...
334
  		seq_printf(seq, ",session=%d", sbi->s_session);
6da80894c   Miklos Szeredi   mount options: fi...
335
336
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
  		seq_printf(seq, ",lastblock=%u", sbi->s_last_block);
403460051   Jan Kara   udf: Try anchor i...
337
338
  	if (sbi->s_anchor != 0)
  		seq_printf(seq, ",anchor=%u", sbi->s_anchor);
6da80894c   Miklos Szeredi   mount options: fi...
339
340
341
342
343
344
345
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
  		seq_puts(seq, ",utf8");
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP) && sbi->s_nls_map)
  		seq_printf(seq, ",iocharset=%s", sbi->s_nls_map->charset);
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
347
348
349
350
351
352
353
354
355
356
  /*
   * udf_parse_options
   *
   * PURPOSE
   *	Parse mount options.
   *
   * DESCRIPTION
   *	The following mount options are supported:
   *
   *	gid=		Set the default group.
   *	umask=		Set the default umask.
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
357
358
   *	mode=		Set the default file permissions.
   *	dmode=		Set the default directory permissions.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
360
361
362
363
364
365
366
367
368
369
370
371
   *	uid=		Set the default user.
   *	bs=		Set the block size.
   *	unhide		Show otherwise hidden files.
   *	undelete	Show deleted files in lists.
   *	adinicb		Embed data in the inode (default)
   *	noadinicb	Don't embed data in the inode
   *	shortad		Use short ad's
   *	longad		Use long ad's (default)
   *	nostrict	Unset strict conformance
   *	iocharset=	Set the NLS character set
   *
   *	The remaining are for debugging and disaster recovery:
   *
28de7948a   Cyrill Gorcunov   UDF: coding style...
372
   *	novrs		Skip volume sequence recognition
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
   *
   *	The following expect a offset from 0.
   *
   *	session=	Set the CDROM session (default= last session)
   *	anchor=		Override standard anchor location. (default= 256)
   *	volume=		Override the VolumeDesc location. (unused)
   *	partition=	Override the PartitionDesc location. (unused)
   *	lastblock=	Set the last block of the filesystem/
   *
   *	The following expect a offset from the partition root.
   *
   *	fileset=	Override the fileset block location. (unused)
   *	rootdir=	Override the root directory location. (unused)
   *		WARNING: overriding the rootdir to a non-directory may
   *		yield highly unpredictable results.
   *
   * PRE-CONDITIONS
   *	options		Pointer to mount options string.
   *	uopts		Pointer to mount options variable.
   *
   * POST-CONDITIONS
   *	<return>	1	Mount options parsed okay.
   *	<return>	0	Error parsing mount options.
   *
   * HISTORY
   *	July 1, 1997 - Andrew E. Mileski
   *	Written, tested, and released.
   */
28de7948a   Cyrill Gorcunov   UDF: coding style...
401

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
405
406
407
  enum {
  	Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
  	Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
  	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
  	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
  	Opt_rootdir, Opt_utf8, Opt_iocharset,
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
408
409
  	Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore,
  	Opt_fmode, Opt_dmode
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
  };
a447c0932   Steven Whitehouse   vfs: Use const fo...
411
  static const match_table_t tokens = {
28de7948a   Cyrill Gorcunov   UDF: coding style...
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
  	{Opt_novrs,	"novrs"},
  	{Opt_nostrict,	"nostrict"},
  	{Opt_bs,	"bs=%u"},
  	{Opt_unhide,	"unhide"},
  	{Opt_undelete,	"undelete"},
  	{Opt_noadinicb,	"noadinicb"},
  	{Opt_adinicb,	"adinicb"},
  	{Opt_shortad,	"shortad"},
  	{Opt_longad,	"longad"},
  	{Opt_uforget,	"uid=forget"},
  	{Opt_uignore,	"uid=ignore"},
  	{Opt_gforget,	"gid=forget"},
  	{Opt_gignore,	"gid=ignore"},
  	{Opt_gid,	"gid=%u"},
  	{Opt_uid,	"uid=%u"},
  	{Opt_umask,	"umask=%o"},
  	{Opt_session,	"session=%u"},
  	{Opt_lastblock,	"lastblock=%u"},
  	{Opt_anchor,	"anchor=%u"},
  	{Opt_volume,	"volume=%u"},
  	{Opt_partition,	"partition=%u"},
  	{Opt_fileset,	"fileset=%u"},
  	{Opt_rootdir,	"rootdir=%u"},
  	{Opt_utf8,	"utf8"},
  	{Opt_iocharset,	"iocharset=%s"},
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
437
438
  	{Opt_fmode,     "mode=%o"},
  	{Opt_dmode,     "dmode=%o"},
28de7948a   Cyrill Gorcunov   UDF: coding style...
439
  	{Opt_err,	NULL}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
  };
6da80894c   Miklos Szeredi   mount options: fi...
441
442
  static int udf_parse_options(char *options, struct udf_options *uopt,
  			     bool remount)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
443
444
445
446
447
  {
  	char *p;
  	int option;
  
  	uopt->novrs = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
450
  	uopt->session = 0xFFFFFFFF;
  	uopt->lastblock = 0;
  	uopt->anchor = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
453
  
  	if (!options)
  		return 1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
454
  	while ((p = strsep(&options, ",")) != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
456
  		substring_t args[MAX_OPT_ARGS];
  		int token;
8c6915aef   Fabian Frederick   fs: udf: parse_op...
457
  		unsigned n;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458
459
460
461
  		if (!*p)
  			continue;
  
  		token = match_token(p, tokens, args);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
462
463
464
  		switch (token) {
  		case Opt_novrs:
  			uopt->novrs = 1;
4136801ae   Clemens Ladisch   udf: fix novrs mo...
465
  			break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
466
467
468
  		case Opt_bs:
  			if (match_int(&args[0], &option))
  				return 0;
8c6915aef   Fabian Frederick   fs: udf: parse_op...
469
470
471
472
  			n = option;
  			if (n != 512 && n != 1024 && n != 2048 && n != 4096)
  				return 0;
  			uopt->blocksize = n;
1197e4dfc   Clemens Ladisch   udf: use hardware...
473
  			uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
  			break;
  		case Opt_unhide:
  			uopt->flags |= (1 << UDF_FLAG_UNHIDE);
  			break;
  		case Opt_undelete:
  			uopt->flags |= (1 << UDF_FLAG_UNDELETE);
  			break;
  		case Opt_noadinicb:
  			uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
  			break;
  		case Opt_adinicb:
  			uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
  			break;
  		case Opt_shortad:
  			uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
  			break;
  		case Opt_longad:
  			uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
  			break;
  		case Opt_gid:
  			if (match_int(args, &option))
  				return 0;
c2ba138a2   Eric W. Biederman   userns: Convert t...
496
497
498
  			uopt->gid = make_kgid(current_user_ns(), option);
  			if (!gid_valid(uopt->gid))
  				return 0;
ca76d2d80   Cyrill Gorcunov   UDF: fix UID and ...
499
  			uopt->flags |= (1 << UDF_FLAG_GID_SET);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
500
501
502
503
  			break;
  		case Opt_uid:
  			if (match_int(args, &option))
  				return 0;
c2ba138a2   Eric W. Biederman   userns: Convert t...
504
505
506
  			uopt->uid = make_kuid(current_user_ns(), option);
  			if (!uid_valid(uopt->uid))
  				return 0;
ca76d2d80   Cyrill Gorcunov   UDF: fix UID and ...
507
  			uopt->flags |= (1 << UDF_FLAG_UID_SET);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
508
509
510
511
512
513
514
515
516
517
518
519
520
  			break;
  		case Opt_umask:
  			if (match_octal(args, &option))
  				return 0;
  			uopt->umask = option;
  			break;
  		case Opt_nostrict:
  			uopt->flags &= ~(1 << UDF_FLAG_STRICT);
  			break;
  		case Opt_session:
  			if (match_int(args, &option))
  				return 0;
  			uopt->session = option;
6da80894c   Miklos Szeredi   mount options: fi...
521
522
  			if (!remount)
  				uopt->flags |= (1 << UDF_FLAG_SESSION_SET);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
523
524
525
526
527
  			break;
  		case Opt_lastblock:
  			if (match_int(args, &option))
  				return 0;
  			uopt->lastblock = option;
6da80894c   Miklos Szeredi   mount options: fi...
528
529
  			if (!remount)
  				uopt->flags |= (1 << UDF_FLAG_LASTBLOCK_SET);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
530
531
532
533
534
535
536
  			break;
  		case Opt_anchor:
  			if (match_int(args, &option))
  				return 0;
  			uopt->anchor = option;
  			break;
  		case Opt_volume:
cb00ea352   Cyrill Gorcunov   UDF: coding style...
537
  		case Opt_partition:
cb00ea352   Cyrill Gorcunov   UDF: coding style...
538
  		case Opt_fileset:
cb00ea352   Cyrill Gorcunov   UDF: coding style...
539
  		case Opt_rootdir:
f0c4a8171   Jan Kara   udf: Remove never...
540
  			/* Ignored (never implemented properly) */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
541
542
543
544
  			break;
  		case Opt_utf8:
  			uopt->flags |= (1 << UDF_FLAG_UTF8);
  			break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
545
  		case Opt_iocharset:
785dffe1d   Chengguang Xu   udf: fix potentia...
546
547
548
  			if (!remount) {
  				if (uopt->nls_map)
  					unload_nls(uopt->nls_map);
a768a9abc   Jan Kara   udf: Explain hand...
549
550
551
552
553
  				/*
  				 * load_nls() failure is handled later in
  				 * udf_fill_super() after all options are
  				 * parsed.
  				 */
785dffe1d   Chengguang Xu   udf: fix potentia...
554
555
556
  				uopt->nls_map = load_nls(args[0].from);
  				uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
557
  			break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
558
559
560
  		case Opt_uforget:
  			uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
  			break;
70260e447   Jan Kara   udf: Ignore [ug]i...
561
  		case Opt_uignore:
cb00ea352   Cyrill Gorcunov   UDF: coding style...
562
  		case Opt_gignore:
70260e447   Jan Kara   udf: Ignore [ug]i...
563
  			/* These options are superseeded by uid=<number> */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
564
565
566
567
  			break;
  		case Opt_gforget:
  			uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
  			break;
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
568
569
570
571
572
573
574
575
576
577
  		case Opt_fmode:
  			if (match_octal(args, &option))
  				return 0;
  			uopt->fmode = option & 0777;
  			break;
  		case Opt_dmode:
  			if (match_octal(args, &option))
  				return 0;
  			uopt->dmode = option & 0777;
  			break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
578
  		default:
78ace70c4   Joe Perches   udf: Convert prin...
579
580
  			pr_err("bad mount option \"%s\" or missing value
  ", p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
583
584
585
  			return 0;
  		}
  	}
  	return 1;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
586
  static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
  {
  	struct udf_options uopt;
6c79e987d   Marcin Slusarz   udf: remove some ...
589
  	struct udf_sb_info *sbi = UDF_SB(sb);
c79d967de   Christoph Hellwig   quota: move remou...
590
  	int error = 0;
a9ad01bc7   Jan Kara   udf: Prevent writ...
591
592
593
  
  	if (!(*flags & SB_RDONLY) && UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
  		return -EACCES;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594

02b9984d6   Theodore Ts'o   fs: push sync_fil...
595
  	sync_filesystem(sb);
e729eac6f   Jan Kara   udf: Refuse RW mo...
596

6c79e987d   Marcin Slusarz   udf: remove some ...
597
598
599
600
  	uopt.flags = sbi->s_flags;
  	uopt.uid   = sbi->s_uid;
  	uopt.gid   = sbi->s_gid;
  	uopt.umask = sbi->s_umask;
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
601
602
  	uopt.fmode = sbi->s_fmode;
  	uopt.dmode = sbi->s_dmode;
785dffe1d   Chengguang Xu   udf: fix potentia...
603
  	uopt.nls_map = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604

6da80894c   Miklos Szeredi   mount options: fi...
605
  	if (!udf_parse_options(options, &uopt, true))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
  		return -EINVAL;
c03cad241   Jan Kara   udf: Protect defa...
607
  	write_lock(&sbi->s_cred_lock);
6c79e987d   Marcin Slusarz   udf: remove some ...
608
609
610
611
  	sbi->s_flags = uopt.flags;
  	sbi->s_uid   = uopt.uid;
  	sbi->s_gid   = uopt.gid;
  	sbi->s_umask = uopt.umask;
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
612
613
  	sbi->s_fmode = uopt.fmode;
  	sbi->s_dmode = uopt.dmode;
c03cad241   Jan Kara   udf: Protect defa...
614
  	write_unlock(&sbi->s_cred_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615

1751e8a6c   Linus Torvalds   Rename superblock...
616
  	if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
c79d967de   Christoph Hellwig   quota: move remou...
617
  		goto out_unlock;
1751e8a6c   Linus Torvalds   Rename superblock...
618
  	if (*flags & SB_RDONLY)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
  		udf_close_lvid(sb);
363504628   Jan Kara   udf: Remove dead ...
620
  	else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
621
  		udf_open_lvid(sb);
c79d967de   Christoph Hellwig   quota: move remou...
622
  out_unlock:
c79d967de   Christoph Hellwig   quota: move remou...
623
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
  }
ba54aef03   Steven J. Magnani   udf: refactor VRS...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
  /*
   * Check VSD descriptor. Returns -1 in case we are at the end of volume
   * recognition area, 0 if the descriptor is valid but non-interesting, 1 if
   * we found one of NSR descriptors we are looking for.
   */
  static int identify_vsd(const struct volStructDesc *vsd)
  {
  	int ret = 0;
  
  	if (!memcmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {
  		switch (vsd->structType) {
  		case 0:
  			udf_debug("ISO9660 Boot Record found
  ");
  			break;
  		case 1:
  			udf_debug("ISO9660 Primary Volume Descriptor found
  ");
  			break;
  		case 2:
  			udf_debug("ISO9660 Supplementary Volume Descriptor found
  ");
  			break;
  		case 3:
  			udf_debug("ISO9660 Volume Partition Descriptor found
  ");
  			break;
  		case 255:
  			udf_debug("ISO9660 Volume Descriptor Set Terminator found
  ");
  			break;
  		default:
  			udf_debug("ISO9660 VRS (%u) found
  ", vsd->structType);
  			break;
  		}
  	} else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
  		; /* ret = 0 */
  	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
  		ret = 1;
  	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
  		ret = 1;
  	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BOOT2, VSD_STD_ID_LEN))
  		; /* ret = 0 */
  	else if (!memcmp(vsd->stdIdent, VSD_STD_ID_CDW02, VSD_STD_ID_LEN))
  		; /* ret = 0 */
  	else {
  		/* TEA01 or invalid id : end of volume recognition area */
  		ret = -1;
  	}
  
  	return ret;
  }
  
  /*
   * Check Volume Structure Descriptors (ECMA 167 2/9.1)
   * We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1)
   * @return   1 if NSR02 or NSR03 found,
   *	    -1 if first sector read error, 0 otherwise
   */
  static int udf_check_vsd(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
687
  {
  	struct volStructDesc *vsd = NULL;
444996027   Peter A. Felvegi   udf: fix for path...
688
  	loff_t sector = VSD_FIRST_SECTOR_OFFSET;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689
690
  	int sectorsize;
  	struct buffer_head *bh = NULL;
ba54aef03   Steven J. Magnani   udf: refactor VRS...
691
  	int nsr = 0;
6c79e987d   Marcin Slusarz   udf: remove some ...
692
  	struct udf_sb_info *sbi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
693

6c79e987d   Marcin Slusarz   udf: remove some ...
694
  	sbi = UDF_SB(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
695
696
697
698
  	if (sb->s_blocksize < sizeof(struct volStructDesc))
  		sectorsize = sizeof(struct volStructDesc);
  	else
  		sectorsize = sb->s_blocksize;
abdc0eb06   Jan Kara   udf: Avoid overfl...
699
  	sector += (((loff_t)sbi->s_session) << sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700

fcbf7637e   Steve Magnani   udf: Fix signed/u...
701
702
  	udf_debug("Starting at sector %u (%lu byte sectors)
  ",
706047a79   Sebastian Manciulea   udf: Fix compilat...
703
704
  		  (unsigned int)(sector >> sb->s_blocksize_bits),
  		  sb->s_blocksize);
444996027   Peter A. Felvegi   udf: fix for path...
705
706
707
708
709
710
711
712
713
714
  	/* Process the sequence (if applicable). The hard limit on the sector
  	 * offset is arbitrary, hopefully large enough so that all valid UDF
  	 * filesystems will be recognised. There is no mention of an upper
  	 * bound to the size of the volume recognition area in the standard.
  	 *  The limit will prevent the code to read all the sectors of a
  	 * specially crafted image (like a bluray disc full of CD001 sectors),
  	 * potentially causing minutes or even hours of uninterruptible I/O
  	 * activity. This actually happened with uninitialised SSD partitions
  	 * (all 0xFF) before the check for the limit and all valid IDs were
  	 * added */
ba54aef03   Steven J. Magnani   udf: refactor VRS...
715
  	for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
717
718
719
  		/* Read a block */
  		bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
  		if (!bh)
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
  		vsd = (struct volStructDesc *)(bh->b_data +
3a71fc5de   Marcin Slusarz   udf: fix coding s...
721
  					      (sector & (sb->s_blocksize - 1)));
ba54aef03   Steven J. Magnani   udf: refactor VRS...
722
  		nsr = identify_vsd(vsd);
6fbacb853   Steven J. Magnani   udf: support 2048...
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
  		/* Found NSR or end? */
  		if (nsr) {
  			brelse(bh);
  			break;
  		}
  		/*
  		 * Special handling for improperly formatted VRS (e.g., Win10)
  		 * where components are separated by 2048 bytes even though
  		 * sectors are 4K
  		 */
  		if (sb->s_blocksize == 4096) {
  			nsr = identify_vsd(vsd + 1);
  			/* Ignore unknown IDs... */
  			if (nsr < 0)
  				nsr = 0;
  		}
3bf25cb40   Jan Kara   udf: use get_bh()
739
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
740
  	}
ba54aef03   Steven J. Magnani   udf: refactor VRS...
741
742
  	if (nsr > 0)
  		return 1;
444996027   Peter A. Felvegi   udf: fix for path...
743
744
  	else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) ==
  			VSD_FIRST_SECTOR_OFFSET)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
745
746
747
748
  		return -1;
  	else
  		return 0;
  }
8b47ea6c2   Jan Kara   udf: Drop forward...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
  static int udf_verify_domain_identifier(struct super_block *sb,
  					struct regid *ident, char *dname)
  {
  	struct domainEntityIDSuffix *suffix;
  
  	if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) {
  		udf_warn(sb, "Not OSTA UDF compliant %s descriptor.
  ", dname);
  		goto force_ro;
  	}
  	if (ident->flags & (1 << ENTITYID_FLAGS_DIRTY)) {
  		udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor.
  ",
  			 dname);
  		goto force_ro;
  	}
  	suffix = (struct domainEntityIDSuffix *)ident->identSuffix;
  	if (suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_HARDWRITEPROTECT) ||
  	    suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_SOFTWRITEPROTECT)) {
  		if (!sb_rdonly(sb)) {
  			udf_warn(sb, "Descriptor for %s marked write protected."
  				 " Forcing read only mount.
  ", dname);
  		}
  		goto force_ro;
  	}
  	return 0;
  
  force_ro:
  	if (!sb_rdonly(sb))
  		return -EACCES;
  	UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
  	return 0;
  }
  
  static int udf_load_fileset(struct super_block *sb, struct fileSetDesc *fset,
  			    struct kernel_lb_addr *root)
  {
  	int ret;
  
  	ret = udf_verify_domain_identifier(sb, &fset->domainIdent, "file set");
  	if (ret < 0)
  		return ret;
  
  	*root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
  	UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum);
  
  	udf_debug("Rootdir at block=%u, partition=%u
  ",
  		  root->logicalBlockNum, root->partitionReferenceNum);
  	return 0;
  }
3a71fc5de   Marcin Slusarz   udf: fix coding s...
801
  static int udf_find_fileset(struct super_block *sb,
5ca4e4be8   Pekka Enberg   Remove struct typ...
802
803
  			    struct kernel_lb_addr *fileset,
  			    struct kernel_lb_addr *root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
804
805
  {
  	struct buffer_head *bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
  	uint16_t ident;
2dee5aac0   Jan Kara   udf: Verify domai...
807
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808

2dee5aac0   Jan Kara   udf: Verify domai...
809
810
811
  	if (fileset->logicalBlockNum == 0xFFFFFFFF &&
  	    fileset->partitionReferenceNum == 0xFFFF)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812

2dee5aac0   Jan Kara   udf: Verify domai...
813
814
815
816
  	bh = udf_read_ptagged(sb, fileset, 0, &ident);
  	if (!bh)
  		return -EIO;
  	if (ident != TAG_IDENT_FSD) {
3bf25cb40   Jan Kara   udf: use get_bh()
817
  		brelse(bh);
2dee5aac0   Jan Kara   udf: Verify domai...
818
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
  	}
2dee5aac0   Jan Kara   udf: Verify domai...
820
821
822
823
824
825
826
827
828
  
  	udf_debug("Fileset at block=%u, partition=%u
  ",
  		  fileset->logicalBlockNum, fileset->partitionReferenceNum);
  
  	UDF_SB(sb)->s_partition = fileset->partitionReferenceNum;
  	ret = udf_load_fileset(sb, (struct fileSetDesc *)bh->b_data, root);
  	brelse(bh);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
  }
d759bfa4e   Jan Kara   udf: Standardize ...
830
831
832
833
834
835
  /*
   * Load primary Volume Descriptor Sequence
   *
   * Return <0 on error, 0 on success. -EAGAIN is special meaning next sequence
   * should be tried.
   */
c0eb31ed1   Jan Kara   udf: Cleanup volu...
836
  static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837
838
  {
  	struct primaryVolDesc *pvoldesc;
9293fcfbc   Andrew Gabbasov   udf: Remove struc...
839
  	uint8_t *outstr;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
840
841
  	struct buffer_head *bh;
  	uint16_t ident;
d759bfa4e   Jan Kara   udf: Standardize ...
842
  	int ret = -ENOMEM;
0220eddac   Deepa Dinamani   udf: Simplify cal...
843
  	struct timestamp *ts;
ba9aadd80   Marcin Slusarz   udf: reduce stack...
844

9293fcfbc   Andrew Gabbasov   udf: Remove struc...
845
  	outstr = kmalloc(128, GFP_NOFS);
ba9aadd80   Marcin Slusarz   udf: reduce stack...
846
  	if (!outstr)
9293fcfbc   Andrew Gabbasov   udf: Remove struc...
847
  		return -ENOMEM;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
848
849
  
  	bh = udf_read_tagged(sb, block, block, &ident);
d759bfa4e   Jan Kara   udf: Standardize ...
850
851
  	if (!bh) {
  		ret = -EAGAIN;
ba9aadd80   Marcin Slusarz   udf: reduce stack...
852
  		goto out2;
d759bfa4e   Jan Kara   udf: Standardize ...
853
  	}
ba9aadd80   Marcin Slusarz   udf: reduce stack...
854

d759bfa4e   Jan Kara   udf: Standardize ...
855
856
857
858
  	if (ident != TAG_IDENT_PVD) {
  		ret = -EIO;
  		goto out_bh;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859
860
  
  	pvoldesc = (struct primaryVolDesc *)bh->b_data;
0220eddac   Deepa Dinamani   udf: Simplify cal...
861
862
  	udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
  			      pvoldesc->recordingDateAndTime);
0220eddac   Deepa Dinamani   udf: Simplify cal...
863
864
865
866
867
  	ts = &pvoldesc->recordingDateAndTime;
  	udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)
  ",
  		  le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
  		  ts->minute, le16_to_cpu(ts->typeAndTimezone));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868

e966fc8d9   Jan Kara   udf: Convert iden...
869
  	ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32);
b54e41f5e   Jan Kara   udf: Allow mounti...
870
871
872
873
874
875
876
877
  	if (ret < 0) {
  		strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName");
  		pr_warn("incorrect volume identification, setting to "
  			"'InvalidName'
  ");
  	} else {
  		strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
  	}
9293fcfbc   Andrew Gabbasov   udf: Remove struc...
878
879
  	udf_debug("volIdent[] = '%s'
  ", UDF_SB(sb)->s_volume_ident);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880

e966fc8d9   Jan Kara   udf: Convert iden...
881
  	ret = udf_dstrCS0toChar(sb, outstr, 127, pvoldesc->volSetIdent, 128);
b54e41f5e   Jan Kara   udf: Allow mounti...
882
883
  	if (ret < 0) {
  		ret = 0;
9293fcfbc   Andrew Gabbasov   udf: Remove struc...
884
  		goto out_bh;
b54e41f5e   Jan Kara   udf: Allow mounti...
885
  	}
9293fcfbc   Andrew Gabbasov   udf: Remove struc...
886
887
888
  	outstr[ret] = 0;
  	udf_debug("volSetIdent[] = '%s'
  ", outstr);
c0eb31ed1   Jan Kara   udf: Cleanup volu...
889

ba9aadd80   Marcin Slusarz   udf: reduce stack...
890
  	ret = 0;
d759bfa4e   Jan Kara   udf: Standardize ...
891
892
  out_bh:
  	brelse(bh);
ba9aadd80   Marcin Slusarz   udf: reduce stack...
893
894
  out2:
  	kfree(outstr);
ba9aadd80   Marcin Slusarz   udf: reduce stack...
895
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
896
  }
3080a74ea   Namjae Jeon   udf: Skip mirror ...
897
  struct inode *udf_find_metadata_inode_efe(struct super_block *sb,
7888824b0   Alden Tondettar   udf: Use correct ...
898
  					u32 meta_file_loc, u32 partition_ref)
3080a74ea   Namjae Jeon   udf: Skip mirror ...
899
900
901
902
903
  {
  	struct kernel_lb_addr addr;
  	struct inode *metadata_fe;
  
  	addr.logicalBlockNum = meta_file_loc;
7888824b0   Alden Tondettar   udf: Use correct ...
904
  	addr.partitionReferenceNum = partition_ref;
3080a74ea   Namjae Jeon   udf: Skip mirror ...
905

6174c2eb8   Jan Kara   udf: Fix loading ...
906
  	metadata_fe = udf_iget_special(sb, &addr);
3080a74ea   Namjae Jeon   udf: Skip mirror ...
907

6d3d5e860   Jan Kara   udf: Make udf_rea...
908
  	if (IS_ERR(metadata_fe)) {
3080a74ea   Namjae Jeon   udf: Skip mirror ...
909
910
  		udf_warn(sb, "metadata inode efe not found
  ");
6d3d5e860   Jan Kara   udf: Make udf_rea...
911
912
913
  		return metadata_fe;
  	}
  	if (UDF_I(metadata_fe)->i_alloc_type != ICBTAG_FLAG_AD_SHORT) {
3080a74ea   Namjae Jeon   udf: Skip mirror ...
914
915
916
  		udf_warn(sb, "metadata inode efe does not have short allocation descriptors!
  ");
  		iput(metadata_fe);
6d3d5e860   Jan Kara   udf: Make udf_rea...
917
  		return ERR_PTR(-EIO);
3080a74ea   Namjae Jeon   udf: Skip mirror ...
918
919
920
921
  	}
  
  	return metadata_fe;
  }
7888824b0   Alden Tondettar   udf: Use correct ...
922
923
  static int udf_load_metadata_files(struct super_block *sb, int partition,
  				   int type1_index)
bfb257a59   Jan Kara   udf: Add read-onl...
924
925
926
927
  {
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct udf_part_map *map;
  	struct udf_meta_data *mdata;
5ca4e4be8   Pekka Enberg   Remove struct typ...
928
  	struct kernel_lb_addr addr;
6d3d5e860   Jan Kara   udf: Make udf_rea...
929
  	struct inode *fe;
bfb257a59   Jan Kara   udf: Add read-onl...
930
931
932
  
  	map = &sbi->s_partmaps[partition];
  	mdata = &map->s_type_specific.s_metadata;
7888824b0   Alden Tondettar   udf: Use correct ...
933
  	mdata->s_phys_partition_ref = type1_index;
bfb257a59   Jan Kara   udf: Add read-onl...
934
935
  
  	/* metadata address */
fcbf7637e   Steve Magnani   udf: Fix signed/u...
936
937
  	udf_debug("Metadata file location: block = %u part = %u
  ",
7888824b0   Alden Tondettar   udf: Use correct ...
938
  		  mdata->s_meta_file_loc, mdata->s_phys_partition_ref);
bfb257a59   Jan Kara   udf: Add read-onl...
939

6d3d5e860   Jan Kara   udf: Make udf_rea...
940
  	fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc,
7888824b0   Alden Tondettar   udf: Use correct ...
941
  					 mdata->s_phys_partition_ref);
6d3d5e860   Jan Kara   udf: Make udf_rea...
942
  	if (IS_ERR(fe)) {
3080a74ea   Namjae Jeon   udf: Skip mirror ...
943
  		/* mirror file entry */
fcbf7637e   Steve Magnani   udf: Fix signed/u...
944
945
  		udf_debug("Mirror metadata file location: block = %u part = %u
  ",
7888824b0   Alden Tondettar   udf: Use correct ...
946
  			  mdata->s_mirror_file_loc, mdata->s_phys_partition_ref);
bfb257a59   Jan Kara   udf: Add read-onl...
947

6d3d5e860   Jan Kara   udf: Make udf_rea...
948
  		fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc,
7888824b0   Alden Tondettar   udf: Use correct ...
949
  						 mdata->s_phys_partition_ref);
bfb257a59   Jan Kara   udf: Add read-onl...
950

6d3d5e860   Jan Kara   udf: Make udf_rea...
951
  		if (IS_ERR(fe)) {
3080a74ea   Namjae Jeon   udf: Skip mirror ...
952
953
  			udf_err(sb, "Both metadata and mirror metadata inode efe can not found
  ");
6d3d5e860   Jan Kara   udf: Make udf_rea...
954
  			return PTR_ERR(fe);
3080a74ea   Namjae Jeon   udf: Skip mirror ...
955
  		}
6d3d5e860   Jan Kara   udf: Make udf_rea...
956
957
958
  		mdata->s_mirror_fe = fe;
  	} else
  		mdata->s_metadata_fe = fe;
bfb257a59   Jan Kara   udf: Add read-onl...
959
960
961
962
963
964
965
966
  
  	/*
  	 * bitmap file entry
  	 * Note:
  	 * Load only if bitmap file location differs from 0xFFFFFFFF (DCN-5102)
  	*/
  	if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) {
  		addr.logicalBlockNum = mdata->s_bitmap_file_loc;
7888824b0   Alden Tondettar   udf: Use correct ...
967
  		addr.partitionReferenceNum = mdata->s_phys_partition_ref;
bfb257a59   Jan Kara   udf: Add read-onl...
968

fcbf7637e   Steve Magnani   udf: Fix signed/u...
969
970
  		udf_debug("Bitmap file location: block = %u part = %u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
971
  			  addr.logicalBlockNum, addr.partitionReferenceNum);
bfb257a59   Jan Kara   udf: Add read-onl...
972

6174c2eb8   Jan Kara   udf: Fix loading ...
973
  		fe = udf_iget_special(sb, &addr);
6d3d5e860   Jan Kara   udf: Make udf_rea...
974
  		if (IS_ERR(fe)) {
bc98a42c1   David Howells   VFS: Convert sb->...
975
  			if (sb_rdonly(sb))
a40ecd7b3   Joe Perches   udf: Rename udf_w...
976
977
  				udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only
  ");
bfb257a59   Jan Kara   udf: Add read-onl...
978
  			else {
8076c363d   Joe Perches   udf: Rename udf_e...
979
980
  				udf_err(sb, "bitmap inode efe not found and attempted read-write mount
  ");
6d3d5e860   Jan Kara   udf: Make udf_rea...
981
  				return PTR_ERR(fe);
bfb257a59   Jan Kara   udf: Add read-onl...
982
  			}
6d3d5e860   Jan Kara   udf: Make udf_rea...
983
984
  		} else
  			mdata->s_bitmap_fe = fe;
bfb257a59   Jan Kara   udf: Add read-onl...
985
986
987
988
  	}
  
  	udf_debug("udf_load_metadata_files Ok
  ");
bfb257a59   Jan Kara   udf: Add read-onl...
989
  	return 0;
bfb257a59   Jan Kara   udf: Add read-onl...
990
  }
883cb9d18   Marcin Slusarz   udf: move calcula...
991
992
993
  int udf_compute_nr_groups(struct super_block *sb, u32 partition)
  {
  	struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
8dee00bb7   Julia Lawall   fs/udf: Use DIV_R...
994
995
996
  	return DIV_ROUND_UP(map->s_partition_len +
  			    (sizeof(struct spaceBitmapDesc) << 3),
  			    sb->s_blocksize * 8);
883cb9d18   Marcin Slusarz   udf: move calcula...
997
  }
66e1da3f4   Marcin Slusarz   udf: convert macr...
998
999
  static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
  {
66e1da3f4   Marcin Slusarz   udf: convert macr...
1000
1001
1002
  	struct udf_bitmap *bitmap;
  	int nr_groups;
  	int size;
883cb9d18   Marcin Slusarz   udf: move calcula...
1003
  	nr_groups = udf_compute_nr_groups(sb, index);
66e1da3f4   Marcin Slusarz   udf: convert macr...
1004
1005
1006
1007
  	size = sizeof(struct udf_bitmap) +
  		(sizeof(struct buffer_head *) * nr_groups);
  
  	if (size <= PAGE_SIZE)
ed2ae6f69   Joe Perches   fs/udf: Use vzalloc
1008
  		bitmap = kzalloc(size, GFP_KERNEL);
66e1da3f4   Marcin Slusarz   udf: convert macr...
1009
  	else
ed2ae6f69   Joe Perches   fs/udf: Use vzalloc
1010
  		bitmap = vzalloc(size); /* TODO: get rid of vzalloc */
66e1da3f4   Marcin Slusarz   udf: convert macr...
1011

ba2eb866a   Markus Elfring   fs-udf: Adjust tw...
1012
  	if (!bitmap)
66e1da3f4   Marcin Slusarz   udf: convert macr...
1013
  		return NULL;
66e1da3f4   Marcin Slusarz   udf: convert macr...
1014

66e1da3f4   Marcin Slusarz   udf: convert macr...
1015
1016
1017
  	bitmap->s_nr_groups = nr_groups;
  	return bitmap;
  }
b085fbe2e   Jan Kara   udf: Fix crash du...
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
  static int check_partition_desc(struct super_block *sb,
  				struct partitionDesc *p,
  				struct udf_part_map *map)
  {
  	bool umap, utable, fmap, ftable;
  	struct partitionHeaderDesc *phd;
  
  	switch (le32_to_cpu(p->accessType)) {
  	case PD_ACCESS_TYPE_READ_ONLY:
  	case PD_ACCESS_TYPE_WRITE_ONCE:
  	case PD_ACCESS_TYPE_REWRITABLE:
  	case PD_ACCESS_TYPE_NONE:
  		goto force_ro;
  	}
  
  	/* No Partition Header Descriptor? */
  	if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) &&
  	    strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
  		goto force_ro;
  
  	phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
  	utable = phd->unallocSpaceTable.extLength;
  	umap = phd->unallocSpaceBitmap.extLength;
  	ftable = phd->freedSpaceTable.extLength;
  	fmap = phd->freedSpaceBitmap.extLength;
  
  	/* No allocation info? */
  	if (!utable && !umap && !ftable && !fmap)
  		goto force_ro;
  
  	/* We don't support blocks that require erasing before overwrite */
  	if (ftable || fmap)
  		goto force_ro;
  	/* UDF 2.60: 2.3.3 - no mixing of tables & bitmaps, no VAT. */
  	if (utable && umap)
  		goto force_ro;
  
  	if (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
  	    map->s_partition_type == UDF_VIRTUAL_MAP20)
  		goto force_ro;
  
  	return 0;
  force_ro:
  	if (!sb_rdonly(sb))
  		return -EACCES;
  	UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
  	return 0;
  }
3fb38dfa0   Jan Kara   udf: Move filling...
1066
1067
  static int udf_fill_partdesc_info(struct super_block *sb,
  		struct partitionDesc *p, int p_index)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1068
  {
6c79e987d   Marcin Slusarz   udf: remove some ...
1069
  	struct udf_part_map *map;
165923fa4   Marcin Slusarz   udf: super.c reor...
1070
  	struct udf_sb_info *sbi = UDF_SB(sb);
3fb38dfa0   Jan Kara   udf: Move filling...
1071
  	struct partitionHeaderDesc *phd;
b085fbe2e   Jan Kara   udf: Fix crash du...
1072
  	int err;
165923fa4   Marcin Slusarz   udf: super.c reor...
1073

3fb38dfa0   Jan Kara   udf: Move filling...
1074
  	map = &sbi->s_partmaps[p_index];
165923fa4   Marcin Slusarz   udf: super.c reor...
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
  
  	map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */
  	map->s_partition_root = le32_to_cpu(p->partitionStartingLocation);
  
  	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY))
  		map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY;
  	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE))
  		map->s_partition_flags |= UDF_PART_FLAG_WRITE_ONCE;
  	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE))
  		map->s_partition_flags |= UDF_PART_FLAG_REWRITABLE;
  	if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE))
  		map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE;
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1087
1088
  	udf_debug("Partition (%d type %x) starts at physical %u, block length %u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1089
1090
  		  p_index, map->s_partition_type,
  		  map->s_partition_root, map->s_partition_len);
165923fa4   Marcin Slusarz   udf: super.c reor...
1091

b085fbe2e   Jan Kara   udf: Fix crash du...
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
  	err = check_partition_desc(sb, p, map);
  	if (err)
  		return err;
  
  	/*
  	 * Skip loading allocation info it we cannot ever write to the fs.
  	 * This is a correctness thing as we may have decided to force ro mount
  	 * to avoid allocation info we don't support.
  	 */
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
3fb38dfa0   Jan Kara   udf: Move filling...
1102
  		return 0;
165923fa4   Marcin Slusarz   udf: super.c reor...
1103
1104
1105
  
  	phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
  	if (phd->unallocSpaceTable.extLength) {
5ca4e4be8   Pekka Enberg   Remove struct typ...
1106
  		struct kernel_lb_addr loc = {
165923fa4   Marcin Slusarz   udf: super.c reor...
1107
1108
  			.logicalBlockNum = le32_to_cpu(
  				phd->unallocSpaceTable.extPosition),
3fb38dfa0   Jan Kara   udf: Move filling...
1109
  			.partitionReferenceNum = p_index,
165923fa4   Marcin Slusarz   udf: super.c reor...
1110
  		};
6d3d5e860   Jan Kara   udf: Make udf_rea...
1111
  		struct inode *inode;
165923fa4   Marcin Slusarz   udf: super.c reor...
1112

6174c2eb8   Jan Kara   udf: Fix loading ...
1113
  		inode = udf_iget_special(sb, &loc);
6d3d5e860   Jan Kara   udf: Make udf_rea...
1114
  		if (IS_ERR(inode)) {
165923fa4   Marcin Slusarz   udf: super.c reor...
1115
1116
  			udf_debug("cannot load unallocSpaceTable (part %d)
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1117
  				  p_index);
6d3d5e860   Jan Kara   udf: Make udf_rea...
1118
  			return PTR_ERR(inode);
165923fa4   Marcin Slusarz   udf: super.c reor...
1119
  		}
6d3d5e860   Jan Kara   udf: Make udf_rea...
1120
  		map->s_uspace.s_table = inode;
165923fa4   Marcin Slusarz   udf: super.c reor...
1121
  		map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE;
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1122
1123
  		udf_debug("unallocSpaceTable (part %d) @ %lu
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1124
  			  p_index, map->s_uspace.s_table->i_ino);
165923fa4   Marcin Slusarz   udf: super.c reor...
1125
1126
1127
  	}
  
  	if (phd->unallocSpaceBitmap.extLength) {
3fb38dfa0   Jan Kara   udf: Move filling...
1128
1129
  		struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
  		if (!bitmap)
d759bfa4e   Jan Kara   udf: Standardize ...
1130
  			return -ENOMEM;
165923fa4   Marcin Slusarz   udf: super.c reor...
1131
  		map->s_uspace.s_bitmap = bitmap;
2e0838fd0   Jan Kara   udf: Improve erro...
1132
  		bitmap->s_extPosition = le32_to_cpu(
165923fa4   Marcin Slusarz   udf: super.c reor...
1133
  				phd->unallocSpaceBitmap.extPosition);
2e0838fd0   Jan Kara   udf: Improve erro...
1134
  		map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1135
1136
  		udf_debug("unallocSpaceBitmap (part %d) @ %u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1137
  			  p_index, bitmap->s_extPosition);
165923fa4   Marcin Slusarz   udf: super.c reor...
1138
  	}
3fb38dfa0   Jan Kara   udf: Move filling...
1139
1140
  	return 0;
  }
e971b0b9e   Jan Kara   udf: Try harder w...
1141
1142
  static void udf_find_vat_block(struct super_block *sb, int p_index,
  			       int type1_index, sector_t start_block)
38b74a53e   Jan Kara   udf: Move process...
1143
1144
1145
  {
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct udf_part_map *map = &sbi->s_partmaps[p_index];
e971b0b9e   Jan Kara   udf: Try harder w...
1146
  	sector_t vat_block;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1147
  	struct kernel_lb_addr ino;
6d3d5e860   Jan Kara   udf: Make udf_rea...
1148
  	struct inode *inode;
e971b0b9e   Jan Kara   udf: Try harder w...
1149
1150
1151
1152
1153
1154
1155
1156
  
  	/*
  	 * VAT file entry is in the last recorded block. Some broken disks have
  	 * it a few blocks before so try a bit harder...
  	 */
  	ino.partitionReferenceNum = type1_index;
  	for (vat_block = start_block;
  	     vat_block >= map->s_partition_root &&
6d3d5e860   Jan Kara   udf: Make udf_rea...
1157
  	     vat_block >= start_block - 3; vat_block--) {
e971b0b9e   Jan Kara   udf: Try harder w...
1158
  		ino.logicalBlockNum = vat_block - map->s_partition_root;
6174c2eb8   Jan Kara   udf: Fix loading ...
1159
  		inode = udf_iget_special(sb, &ino);
6d3d5e860   Jan Kara   udf: Make udf_rea...
1160
1161
1162
1163
  		if (!IS_ERR(inode)) {
  			sbi->s_vat_inode = inode;
  			break;
  		}
e971b0b9e   Jan Kara   udf: Try harder w...
1164
1165
1166
1167
1168
1169
1170
  	}
  }
  
  static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
  {
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct udf_part_map *map = &sbi->s_partmaps[p_index];
fa5e08156   Jan Kara   udf: Handle VAT p...
1171
1172
1173
1174
  	struct buffer_head *bh = NULL;
  	struct udf_inode_info *vati;
  	uint32_t pos;
  	struct virtualAllocationTable20 *vat20;
23bcda112   Fabian Frederick   udf: atomically r...
1175
1176
  	sector_t blocks = i_size_read(sb->s_bdev->bd_inode) >>
  			  sb->s_blocksize_bits;
38b74a53e   Jan Kara   udf: Move process...
1177

e971b0b9e   Jan Kara   udf: Try harder w...
1178
  	udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
4bf17af0d   Jan Kara   udf: Fix loading ...
1179
1180
  	if (!sbi->s_vat_inode &&
  	    sbi->s_last_block != blocks - 1) {
78ace70c4   Joe Perches   udf: Convert prin...
1181
1182
1183
1184
  		pr_notice("Failed to read VAT inode from the last recorded block (%lu), retrying with the last block of the device (%lu).
  ",
  			  (unsigned long)sbi->s_last_block,
  			  (unsigned long)blocks - 1);
e971b0b9e   Jan Kara   udf: Try harder w...
1185
  		udf_find_vat_block(sb, p_index, type1_index, blocks - 1);
4bf17af0d   Jan Kara   udf: Fix loading ...
1186
  	}
38b74a53e   Jan Kara   udf: Move process...
1187
  	if (!sbi->s_vat_inode)
d759bfa4e   Jan Kara   udf: Standardize ...
1188
  		return -EIO;
38b74a53e   Jan Kara   udf: Move process...
1189
1190
  
  	if (map->s_partition_type == UDF_VIRTUAL_MAP15) {
47c9358a0   Sebastian Manciulea   udf: Fix bug in V...
1191
  		map->s_type_specific.s_virtual.s_start_offset = 0;
38b74a53e   Jan Kara   udf: Move process...
1192
1193
1194
  		map->s_type_specific.s_virtual.s_num_entries =
  			(sbi->s_vat_inode->i_size - 36) >> 2;
  	} else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
fa5e08156   Jan Kara   udf: Handle VAT p...
1195
1196
1197
1198
1199
  		vati = UDF_I(sbi->s_vat_inode);
  		if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
  			pos = udf_block_map(sbi->s_vat_inode, 0);
  			bh = sb_bread(sb, pos);
  			if (!bh)
d759bfa4e   Jan Kara   udf: Standardize ...
1200
  				return -EIO;
fa5e08156   Jan Kara   udf: Handle VAT p...
1201
1202
1203
1204
1205
  			vat20 = (struct virtualAllocationTable20 *)bh->b_data;
  		} else {
  			vat20 = (struct virtualAllocationTable20 *)
  							vati->i_ext.i_data;
  		}
38b74a53e   Jan Kara   udf: Move process...
1206

38b74a53e   Jan Kara   udf: Move process...
1207
  		map->s_type_specific.s_virtual.s_start_offset =
47c9358a0   Sebastian Manciulea   udf: Fix bug in V...
1208
  			le16_to_cpu(vat20->lengthHeader);
38b74a53e   Jan Kara   udf: Move process...
1209
1210
1211
1212
1213
1214
1215
1216
  		map->s_type_specific.s_virtual.s_num_entries =
  			(sbi->s_vat_inode->i_size -
  				map->s_type_specific.s_virtual.
  					s_start_offset) >> 2;
  		brelse(bh);
  	}
  	return 0;
  }
d759bfa4e   Jan Kara   udf: Standardize ...
1217
1218
1219
1220
1221
1222
  /*
   * Load partition descriptor block
   *
   * Returns <0 on error, 0 on success, -EAGAIN is special - try next descriptor
   * sequence.
   */
3fb38dfa0   Jan Kara   udf: Move filling...
1223
1224
1225
1226
1227
1228
  static int udf_load_partdesc(struct super_block *sb, sector_t block)
  {
  	struct buffer_head *bh;
  	struct partitionDesc *p;
  	struct udf_part_map *map;
  	struct udf_sb_info *sbi = UDF_SB(sb);
38b74a53e   Jan Kara   udf: Move process...
1229
  	int i, type1_idx;
3fb38dfa0   Jan Kara   udf: Move filling...
1230
1231
  	uint16_t partitionNumber;
  	uint16_t ident;
d759bfa4e   Jan Kara   udf: Standardize ...
1232
  	int ret;
3fb38dfa0   Jan Kara   udf: Move filling...
1233
1234
1235
  
  	bh = udf_read_tagged(sb, block, block, &ident);
  	if (!bh)
d759bfa4e   Jan Kara   udf: Standardize ...
1236
1237
1238
  		return -EAGAIN;
  	if (ident != TAG_IDENT_PD) {
  		ret = 0;
3fb38dfa0   Jan Kara   udf: Move filling...
1239
  		goto out_bh;
d759bfa4e   Jan Kara   udf: Standardize ...
1240
  	}
3fb38dfa0   Jan Kara   udf: Move filling...
1241
1242
1243
  
  	p = (struct partitionDesc *)bh->b_data;
  	partitionNumber = le16_to_cpu(p->partitionNumber);
38b74a53e   Jan Kara   udf: Move process...
1244

7888824b0   Alden Tondettar   udf: Use correct ...
1245
  	/* First scan for TYPE1 and SPARABLE partitions */
3fb38dfa0   Jan Kara   udf: Move filling...
1246
1247
  	for (i = 0; i < sbi->s_partitions; i++) {
  		map = &sbi->s_partmaps[i];
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1248
1249
  		udf_debug("Searching map: (%u == %u)
  ",
3fb38dfa0   Jan Kara   udf: Move filling...
1250
  			  map->s_partition_num, partitionNumber);
38b74a53e   Jan Kara   udf: Move process...
1251
1252
1253
  		if (map->s_partition_num == partitionNumber &&
  		    (map->s_partition_type == UDF_TYPE1_MAP15 ||
  		     map->s_partition_type == UDF_SPARABLE_MAP15))
3fb38dfa0   Jan Kara   udf: Move filling...
1254
1255
  			break;
  	}
38b74a53e   Jan Kara   udf: Move process...
1256
  	if (i >= sbi->s_partitions) {
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1257
1258
  		udf_debug("Partition (%u) not found in partition map
  ",
3fb38dfa0   Jan Kara   udf: Move filling...
1259
  			  partitionNumber);
d759bfa4e   Jan Kara   udf: Standardize ...
1260
  		ret = 0;
3fb38dfa0   Jan Kara   udf: Move filling...
1261
1262
  		goto out_bh;
  	}
165923fa4   Marcin Slusarz   udf: super.c reor...
1263

3fb38dfa0   Jan Kara   udf: Move filling...
1264
  	ret = udf_fill_partdesc_info(sb, p, i);
d759bfa4e   Jan Kara   udf: Standardize ...
1265
1266
  	if (ret < 0)
  		goto out_bh;
38b74a53e   Jan Kara   udf: Move process...
1267
1268
  
  	/*
bfb257a59   Jan Kara   udf: Add read-onl...
1269
1270
  	 * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and
  	 * PHYSICAL partitions are already set up
38b74a53e   Jan Kara   udf: Move process...
1271
1272
  	 */
  	type1_idx = i;
444996027   Peter A. Felvegi   udf: fix for path...
1273
  	map = NULL; /* supress 'maybe used uninitialized' warning */
38b74a53e   Jan Kara   udf: Move process...
1274
1275
1276
1277
1278
  	for (i = 0; i < sbi->s_partitions; i++) {
  		map = &sbi->s_partmaps[i];
  
  		if (map->s_partition_num == partitionNumber &&
  		    (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
bfb257a59   Jan Kara   udf: Add read-onl...
1279
1280
  		     map->s_partition_type == UDF_VIRTUAL_MAP20 ||
  		     map->s_partition_type == UDF_METADATA_MAP25))
38b74a53e   Jan Kara   udf: Move process...
1281
1282
  			break;
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
1283
1284
  	if (i >= sbi->s_partitions) {
  		ret = 0;
38b74a53e   Jan Kara   udf: Move process...
1285
  		goto out_bh;
d759bfa4e   Jan Kara   udf: Standardize ...
1286
  	}
38b74a53e   Jan Kara   udf: Move process...
1287
1288
  
  	ret = udf_fill_partdesc_info(sb, p, i);
d759bfa4e   Jan Kara   udf: Standardize ...
1289
  	if (ret < 0)
38b74a53e   Jan Kara   udf: Move process...
1290
  		goto out_bh;
bfb257a59   Jan Kara   udf: Add read-onl...
1291
  	if (map->s_partition_type == UDF_METADATA_MAP25) {
7888824b0   Alden Tondettar   udf: Use correct ...
1292
  		ret = udf_load_metadata_files(sb, i, type1_idx);
d759bfa4e   Jan Kara   udf: Standardize ...
1293
  		if (ret < 0) {
78ace70c4   Joe Perches   udf: Convert prin...
1294
1295
1296
  			udf_err(sb, "error loading MetaData partition map %d
  ",
  				i);
bfb257a59   Jan Kara   udf: Add read-onl...
1297
1298
1299
  			goto out_bh;
  		}
  	} else {
e729eac6f   Jan Kara   udf: Refuse RW mo...
1300
1301
1302
1303
1304
  		/*
  		 * If we have a partition with virtual map, we don't handle
  		 * writing to it (we overwrite blocks instead of relocating
  		 * them).
  		 */
bc98a42c1   David Howells   VFS: Convert sb->...
1305
  		if (!sb_rdonly(sb)) {
e729eac6f   Jan Kara   udf: Refuse RW mo...
1306
1307
1308
  			ret = -EACCES;
  			goto out_bh;
  		}
a9ad01bc7   Jan Kara   udf: Prevent writ...
1309
  		UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
bfb257a59   Jan Kara   udf: Add read-onl...
1310
  		ret = udf_load_vat(sb, i, type1_idx);
d759bfa4e   Jan Kara   udf: Standardize ...
1311
  		if (ret < 0)
bfb257a59   Jan Kara   udf: Add read-onl...
1312
  			goto out_bh;
bfb257a59   Jan Kara   udf: Add read-onl...
1313
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
1314
  	ret = 0;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1315
  out_bh:
2e0838fd0   Jan Kara   udf: Improve erro...
1316
  	/* In case loading failed, we handle cleanup in udf_fill_super */
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1317
1318
  	brelse(bh);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1319
  }
1df2ae31c   Jan Kara   udf: Fortify load...
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
  static int udf_load_sparable_map(struct super_block *sb,
  				 struct udf_part_map *map,
  				 struct sparablePartitionMap *spm)
  {
  	uint32_t loc;
  	uint16_t ident;
  	struct sparingTable *st;
  	struct udf_sparing_data *sdata = &map->s_type_specific.s_sparing;
  	int i;
  	struct buffer_head *bh;
  
  	map->s_partition_type = UDF_SPARABLE_MAP15;
  	sdata->s_packet_len = le16_to_cpu(spm->packetLength);
  	if (!is_power_of_2(sdata->s_packet_len)) {
  		udf_err(sb, "error loading logical volume descriptor: "
  			"Invalid packet length %u
  ",
  			(unsigned)sdata->s_packet_len);
  		return -EIO;
  	}
  	if (spm->numSparingTables > 4) {
  		udf_err(sb, "error loading logical volume descriptor: "
  			"Too many sparing tables (%d)
  ",
  			(int)spm->numSparingTables);
  		return -EIO;
  	}
  
  	for (i = 0; i < spm->numSparingTables; i++) {
  		loc = le32_to_cpu(spm->locSparingTable[i]);
  		bh = udf_read_tagged(sb, loc, loc, &ident);
  		if (!bh)
  			continue;
  
  		st = (struct sparingTable *)bh->b_data;
  		if (ident != 0 ||
  		    strncmp(st->sparingIdent.ident, UDF_ID_SPARING,
  			    strlen(UDF_ID_SPARING)) ||
  		    sizeof(*st) + le16_to_cpu(st->reallocationTableLen) >
  							sb->s_blocksize) {
  			brelse(bh);
  			continue;
  		}
  
  		sdata->s_spar_map[i] = bh;
  	}
  	map->s_partition_func = udf_get_pblock_spar15;
  	return 0;
  }
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1369
  static int udf_load_logicalvol(struct super_block *sb, sector_t block,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1370
  			       struct kernel_lb_addr *fileset)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1371
1372
  {
  	struct logicalVolDesc *lvd;
1df2ae31c   Jan Kara   udf: Fortify load...
1373
  	int i, offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374
  	uint8_t type;
6c79e987d   Marcin Slusarz   udf: remove some ...
1375
  	struct udf_sb_info *sbi = UDF_SB(sb);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1376
  	struct genericPartitionMap *gpm;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1377
1378
  	uint16_t ident;
  	struct buffer_head *bh;
adee11b20   Jan Kara   udf: Avoid run aw...
1379
  	unsigned int table_len;
d759bfa4e   Jan Kara   udf: Standardize ...
1380
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1381

c0eb31ed1   Jan Kara   udf: Cleanup volu...
1382
1383
  	bh = udf_read_tagged(sb, block, block, &ident);
  	if (!bh)
d759bfa4e   Jan Kara   udf: Standardize ...
1384
  		return -EAGAIN;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1385
  	BUG_ON(ident != TAG_IDENT_LVD);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1386
  	lvd = (struct logicalVolDesc *)bh->b_data;
adee11b20   Jan Kara   udf: Avoid run aw...
1387
  	table_len = le32_to_cpu(lvd->mapTableLength);
57b9655d0   Jan Kara   udf: Improve tabl...
1388
  	if (table_len > sb->s_blocksize - sizeof(*lvd)) {
adee11b20   Jan Kara   udf: Avoid run aw...
1389
1390
1391
1392
  		udf_err(sb, "error loading logical volume descriptor: "
  			"Partition table too long (%u > %lu)
  ", table_len,
  			sb->s_blocksize - sizeof(*lvd));
d759bfa4e   Jan Kara   udf: Standardize ...
1393
  		ret = -EIO;
adee11b20   Jan Kara   udf: Avoid run aw...
1394
1395
  		goto out_bh;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1396

2dee5aac0   Jan Kara   udf: Verify domai...
1397
1398
1399
1400
  	ret = udf_verify_domain_identifier(sb, &lvd->domainIdent,
  					   "logical volume");
  	if (ret)
  		goto out_bh;
cb14d340e   Jan Kara   udf: Use 'ret' in...
1401
1402
  	ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
  	if (ret)
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1403
  		goto out_bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1404

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1405
  	for (i = 0, offset = 0;
adee11b20   Jan Kara   udf: Avoid run aw...
1406
  	     i < sbi->s_partitions && offset < table_len;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1407
1408
1409
1410
1411
  	     i++, offset += gpm->partitionMapLength) {
  		struct udf_part_map *map = &sbi->s_partmaps[i];
  		gpm = (struct genericPartitionMap *)
  				&(lvd->partitionMaps[offset]);
  		type = gpm->partitionMapType;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1412
  		if (type == 1) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1413
1414
  			struct genericPartitionMap1 *gpm1 =
  				(struct genericPartitionMap1 *)gpm;
6c79e987d   Marcin Slusarz   udf: remove some ...
1415
1416
1417
1418
  			map->s_partition_type = UDF_TYPE1_MAP15;
  			map->s_volumeseqnum = le16_to_cpu(gpm1->volSeqNum);
  			map->s_partition_num = le16_to_cpu(gpm1->partitionNum);
  			map->s_partition_func = NULL;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1419
  		} else if (type == 2) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1420
1421
1422
1423
1424
1425
1426
  			struct udfPartitionMap2 *upm2 =
  						(struct udfPartitionMap2 *)gpm;
  			if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL,
  						strlen(UDF_ID_VIRTUAL))) {
  				u16 suf =
  					le16_to_cpu(((__le16 *)upm2->partIdent.
  							identSuffix)[0]);
c82a12750   Jan Kara   udf: Fix detectio...
1427
  				if (suf < 0x0200) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1428
1429
1430
1431
  					map->s_partition_type =
  							UDF_VIRTUAL_MAP15;
  					map->s_partition_func =
  							udf_get_pblock_virt15;
c82a12750   Jan Kara   udf: Fix detectio...
1432
  				} else {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1433
1434
1435
1436
  					map->s_partition_type =
  							UDF_VIRTUAL_MAP20;
  					map->s_partition_func =
  							udf_get_pblock_virt20;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1437
  				}
4b11111ab   Marcin Slusarz   udf: fix coding s...
1438
1439
1440
  			} else if (!strncmp(upm2->partIdent.ident,
  						UDF_ID_SPARABLE,
  						strlen(UDF_ID_SPARABLE))) {
d759bfa4e   Jan Kara   udf: Standardize ...
1441
1442
1443
  				ret = udf_load_sparable_map(sb, map,
  					(struct sparablePartitionMap *)gpm);
  				if (ret < 0)
1df2ae31c   Jan Kara   udf: Fortify load...
1444
  					goto out_bh;
bfb257a59   Jan Kara   udf: Add read-onl...
1445
1446
1447
1448
1449
1450
1451
1452
  			} else if (!strncmp(upm2->partIdent.ident,
  						UDF_ID_METADATA,
  						strlen(UDF_ID_METADATA))) {
  				struct udf_meta_data *mdata =
  					&map->s_type_specific.s_metadata;
  				struct metadataPartitionMap *mdm =
  						(struct metadataPartitionMap *)
  						&(lvd->partitionMaps[offset]);
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1453
1454
  				udf_debug("Parsing Logical vol part %d type %u  id=%s
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1455
  					  i, type, UDF_ID_METADATA);
bfb257a59   Jan Kara   udf: Add read-onl...
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
  
  				map->s_partition_type = UDF_METADATA_MAP25;
  				map->s_partition_func = udf_get_pblock_meta25;
  
  				mdata->s_meta_file_loc   =
  					le32_to_cpu(mdm->metadataFileLoc);
  				mdata->s_mirror_file_loc =
  					le32_to_cpu(mdm->metadataMirrorFileLoc);
  				mdata->s_bitmap_file_loc =
  					le32_to_cpu(mdm->metadataBitmapFileLoc);
  				mdata->s_alloc_unit_size =
  					le32_to_cpu(mdm->allocUnitSize);
  				mdata->s_align_unit_size =
  					le16_to_cpu(mdm->alignUnitSize);
ed47a7d00   Jan Kara   udf: Cleanup meta...
1470
1471
  				if (mdm->flags & 0x01)
  					mdata->s_flags |= MF_DUPLICATE_MD;
bfb257a59   Jan Kara   udf: Add read-onl...
1472
1473
1474
  
  				udf_debug("Metadata Ident suffix=0x%x
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1475
1476
  					  le16_to_cpu(*(__le16 *)
  						      mdm->partIdent.identSuffix));
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1477
1478
  				udf_debug("Metadata part num=%u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1479
  					  le16_to_cpu(mdm->partitionNum));
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1480
1481
  				udf_debug("Metadata part alloc unit size=%u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1482
  					  le32_to_cpu(mdm->allocUnitSize));
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1483
1484
  				udf_debug("Metadata file loc=%u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1485
  					  le32_to_cpu(mdm->metadataFileLoc));
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1486
1487
  				udf_debug("Mirror file loc=%u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1488
  					  le32_to_cpu(mdm->metadataMirrorFileLoc));
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1489
1490
  				udf_debug("Bitmap file loc=%u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1491
  					  le32_to_cpu(mdm->metadataBitmapFileLoc));
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1492
1493
  				udf_debug("Flags: %d %u
  ",
ed47a7d00   Jan Kara   udf: Cleanup meta...
1494
  					  mdata->s_flags, mdm->flags);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1495
  			} else {
3a71fc5de   Marcin Slusarz   udf: fix coding s...
1496
1497
1498
  				udf_debug("Unknown ident: %s
  ",
  					  upm2->partIdent.ident);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499
1500
  				continue;
  			}
6c79e987d   Marcin Slusarz   udf: remove some ...
1501
1502
  			map->s_volumeseqnum = le16_to_cpu(upm2->volSeqNum);
  			map->s_partition_num = le16_to_cpu(upm2->partitionNum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503
  		}
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1504
1505
  		udf_debug("Partition (%d:%u) type %u on volume %u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1506
  			  i, map->s_partition_num, type, map->s_volumeseqnum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1507
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1508
  	if (fileset) {
5ca4e4be8   Pekka Enberg   Remove struct typ...
1509
  		struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510
1511
  
  		*fileset = lelb_to_cpu(la->extLocation);
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1512
1513
  		udf_debug("FileSet found in LogicalVolDesc at block=%u, partition=%u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1514
  			  fileset->logicalBlockNum,
28de7948a   Cyrill Gorcunov   UDF: coding style...
1515
  			  fileset->partitionReferenceNum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1516
1517
1518
  	}
  	if (lvd->integritySeqExt.extLength)
  		udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
d759bfa4e   Jan Kara   udf: Standardize ...
1519
  	ret = 0;
4f5edd82e   Steve Magnani   udf: disallow RW ...
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
  
  	if (!sbi->s_lvid_bh) {
  		/* We can't generate unique IDs without a valid LVID */
  		if (sb_rdonly(sb)) {
  			UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
  		} else {
  			udf_warn(sb, "Damaged or missing LVID, forcing "
  				     "readonly mount
  ");
  			ret = -EACCES;
  		}
  	}
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1532
1533
1534
  out_bh:
  	brelse(bh);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1535
1536
1537
  }
  
  /*
a47241cde   Alden Tondettar   udf: Prevent stac...
1538
   * Find the prevailing Logical Volume Integrity Descriptor.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1539
   */
5ca4e4be8   Pekka Enberg   Remove struct typ...
1540
  static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1541
  {
a47241cde   Alden Tondettar   udf: Prevent stac...
1542
  	struct buffer_head *bh, *final_bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1543
  	uint16_t ident;
6c79e987d   Marcin Slusarz   udf: remove some ...
1544
1545
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct logicalVolIntegrityDesc *lvid;
a47241cde   Alden Tondettar   udf: Prevent stac...
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
  	int indirections = 0;
  
  	while (++indirections <= UDF_MAX_LVID_NESTING) {
  		final_bh = NULL;
  		while (loc.extLength > 0 &&
  			(bh = udf_read_tagged(sb, loc.extLocation,
  					loc.extLocation, &ident))) {
  			if (ident != TAG_IDENT_LVID) {
  				brelse(bh);
  				break;
  			}
  
  			brelse(final_bh);
  			final_bh = bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1560

a47241cde   Alden Tondettar   udf: Prevent stac...
1561
1562
1563
  			loc.extLength -= sb->s_blocksize;
  			loc.extLocation++;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1564

a47241cde   Alden Tondettar   udf: Prevent stac...
1565
1566
  		if (!final_bh)
  			return;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1567

a47241cde   Alden Tondettar   udf: Prevent stac...
1568
1569
1570
1571
1572
1573
1574
1575
  		brelse(sbi->s_lvid_bh);
  		sbi->s_lvid_bh = final_bh;
  
  		lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data;
  		if (lvid->nextIntegrityExt.extLength == 0)
  			return;
  
  		loc = leea_to_cpu(lvid->nextIntegrityExt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
  	}
a47241cde   Alden Tondettar   udf: Prevent stac...
1577
1578
1579
1580
1581
1582
  
  	udf_warn(sb, "Too many LVID indirections (max %u), ignoring.
  ",
  		UDF_MAX_LVID_NESTING);
  	brelse(sbi->s_lvid_bh);
  	sbi->s_lvid_bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1583
  }
7b78fd02f   Jan Kara   udf: Fix handling...
1584
1585
1586
1587
1588
  /*
   * Step for reallocation of table of partition descriptor sequence numbers.
   * Must be power of 2.
   */
  #define PART_DESC_ALLOC_STEP 32
ee4af50ca   Jan Kara   udf: Fix mounting...
1589
1590
1591
1592
  struct part_desc_seq_scan_data {
  	struct udf_vds_record rec;
  	u32 partnum;
  };
7b78fd02f   Jan Kara   udf: Fix handling...
1593
1594
1595
  struct desc_seq_scan_data {
  	struct udf_vds_record vds[VDS_POS_LENGTH];
  	unsigned int size_part_descs;
ee4af50ca   Jan Kara   udf: Fix mounting...
1596
1597
  	unsigned int num_part_descs;
  	struct part_desc_seq_scan_data *part_descs_loc;
7b78fd02f   Jan Kara   udf: Fix handling...
1598
1599
1600
1601
1602
1603
1604
1605
  };
  
  static struct udf_vds_record *handle_partition_descriptor(
  				struct buffer_head *bh,
  				struct desc_seq_scan_data *data)
  {
  	struct partitionDesc *desc = (struct partitionDesc *)bh->b_data;
  	int partnum;
ee4af50ca   Jan Kara   udf: Fix mounting...
1606
  	int i;
7b78fd02f   Jan Kara   udf: Fix handling...
1607
1608
  
  	partnum = le16_to_cpu(desc->partitionNumber);
ee4af50ca   Jan Kara   udf: Fix mounting...
1609
1610
1611
1612
1613
  	for (i = 0; i < data->num_part_descs; i++)
  		if (partnum == data->part_descs_loc[i].partnum)
  			return &(data->part_descs_loc[i].rec);
  	if (data->num_part_descs >= data->size_part_descs) {
  		struct part_desc_seq_scan_data *new_loc;
7b78fd02f   Jan Kara   udf: Fix handling...
1614
  		unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
6396bb221   Kees Cook   treewide: kzalloc...
1615
  		new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
7b78fd02f   Jan Kara   udf: Fix handling...
1616
1617
1618
1619
1620
1621
1622
1623
  		if (!new_loc)
  			return ERR_PTR(-ENOMEM);
  		memcpy(new_loc, data->part_descs_loc,
  		       data->size_part_descs * sizeof(*new_loc));
  		kfree(data->part_descs_loc);
  		data->part_descs_loc = new_loc;
  		data->size_part_descs = new_size;
  	}
ee4af50ca   Jan Kara   udf: Fix mounting...
1624
  	return &(data->part_descs_loc[data->num_part_descs++].rec);
7b78fd02f   Jan Kara   udf: Fix handling...
1625
1626
1627
1628
1629
  }
  
  
  static struct udf_vds_record *get_volume_descriptor_record(uint16_t ident,
  		struct buffer_head *bh, struct desc_seq_scan_data *data)
18cf4781c   Jan Kara   udf: Unify common...
1630
1631
1632
  {
  	switch (ident) {
  	case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
7b78fd02f   Jan Kara   udf: Fix handling...
1633
  		return &(data->vds[VDS_POS_PRIMARY_VOL_DESC]);
18cf4781c   Jan Kara   udf: Unify common...
1634
  	case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
7b78fd02f   Jan Kara   udf: Fix handling...
1635
  		return &(data->vds[VDS_POS_IMP_USE_VOL_DESC]);
18cf4781c   Jan Kara   udf: Unify common...
1636
  	case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
7b78fd02f   Jan Kara   udf: Fix handling...
1637
  		return &(data->vds[VDS_POS_LOGICAL_VOL_DESC]);
18cf4781c   Jan Kara   udf: Unify common...
1638
  	case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
7b78fd02f   Jan Kara   udf: Fix handling...
1639
1640
1641
  		return &(data->vds[VDS_POS_UNALLOC_SPACE_DESC]);
  	case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
  		return handle_partition_descriptor(bh, data);
18cf4781c   Jan Kara   udf: Unify common...
1642
1643
1644
  	}
  	return NULL;
  }
e7a4eb861   Vegard Nossum   udf: limit the ma...
1645
1646
  
  /*
d759bfa4e   Jan Kara   udf: Standardize ...
1647
1648
1649
1650
   * Process a main/reserve volume descriptor sequence.
   *   @block		First block of first extent of the sequence.
   *   @lastblock		Lastblock of first extent of the sequence.
   *   @fileset		There we store extent containing root fileset
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1651
   *
d759bfa4e   Jan Kara   udf: Standardize ...
1652
1653
   * Returns <0 on error, 0 on success. -EAGAIN is special - try next descriptor
   * sequence
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654
   */
d759bfa4e   Jan Kara   udf: Standardize ...
1655
1656
1657
1658
  static noinline int udf_process_sequence(
  		struct super_block *sb,
  		sector_t block, sector_t lastblock,
  		struct kernel_lb_addr *fileset)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1659
1660
  {
  	struct buffer_head *bh = NULL;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1661
  	struct udf_vds_record *curr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
1663
  	struct generic_desc *gd;
  	struct volDescPtr *vdp;
2b8f94211   Fabian Frederick   udf: use bool for...
1664
  	bool done = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1665
1666
  	uint32_t vdsn;
  	uint16_t ident;
d759bfa4e   Jan Kara   udf: Standardize ...
1667
  	int ret;
e7a4eb861   Vegard Nossum   udf: limit the ma...
1668
  	unsigned int indirections = 0;
7b78fd02f   Jan Kara   udf: Fix handling...
1669
1670
1671
1672
1673
  	struct desc_seq_scan_data data;
  	unsigned int i;
  
  	memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
  	data.size_part_descs = PART_DESC_ALLOC_STEP;
ee4af50ca   Jan Kara   udf: Fix mounting...
1674
  	data.num_part_descs = 0;
6396bb221   Kees Cook   treewide: kzalloc...
1675
1676
1677
  	data.part_descs_loc = kcalloc(data.size_part_descs,
  				      sizeof(*data.part_descs_loc),
  				      GFP_KERNEL);
7b78fd02f   Jan Kara   udf: Fix handling...
1678
1679
  	if (!data.part_descs_loc)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680

c0eb31ed1   Jan Kara   udf: Cleanup volu...
1681
1682
1683
1684
  	/*
  	 * Read the main descriptor sequence and find which descriptors
  	 * are in it.
  	 */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1685
  	for (; (!done && block <= lastblock); block++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1686
  		bh = udf_read_tagged(sb, block, block, &ident);
67621675e   Jan Kara   udf: Allow volume...
1687
1688
  		if (!bh)
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1689
1690
1691
1692
  
  		/* Process each descriptor (ISO 13346 3/8.3-8.4) */
  		gd = (struct generic_desc *)bh->b_data;
  		vdsn = le32_to_cpu(gd->volDescSeqNum);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1693
  		switch (ident) {
28de7948a   Cyrill Gorcunov   UDF: coding style...
1694
  		case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
7b568cba4   Jan Kara   udf: Simplify han...
1695
1696
1697
1698
1699
1700
1701
  			if (++indirections > UDF_MAX_TD_NESTING) {
  				udf_err(sb, "too many Volume Descriptor "
  					"Pointers (max %u supported)
  ",
  					UDF_MAX_TD_NESTING);
  				brelse(bh);
  				return -EIO;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1702
  			}
7b568cba4   Jan Kara   udf: Simplify han...
1703
1704
1705
1706
1707
1708
1709
1710
1711
  
  			vdp = (struct volDescPtr *)bh->b_data;
  			block = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
  			lastblock = le32_to_cpu(
  				vdp->nextVolDescSeqExt.extLength) >>
  				sb->s_blocksize_bits;
  			lastblock += block - 1;
  			/* For loop is going to increment 'block' again */
  			block--;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1712
  			break;
18cf4781c   Jan Kara   udf: Unify common...
1713
  		case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
28de7948a   Cyrill Gorcunov   UDF: coding style...
1714
  		case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
18cf4781c   Jan Kara   udf: Unify common...
1715
1716
  		case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
  		case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
7b78fd02f   Jan Kara   udf: Fix handling...
1717
1718
1719
1720
1721
1722
1723
1724
1725
  		case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
  			curr = get_volume_descriptor_record(ident, bh, &data);
  			if (IS_ERR(curr)) {
  				brelse(bh);
  				return PTR_ERR(curr);
  			}
  			/* Descriptor we don't care about? */
  			if (!curr)
  				break;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1726
1727
1728
  			if (vdsn >= curr->volDescSeqNum) {
  				curr->volDescSeqNum = vdsn;
  				curr->block = block;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1729
1730
  			}
  			break;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1731
  		case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
7b568cba4   Jan Kara   udf: Simplify han...
1732
  			done = true;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1733
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1734
  		}
3bf25cb40   Jan Kara   udf: use get_bh()
1735
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1736
  	}
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1737
1738
1739
1740
  	/*
  	 * Now read interesting descriptors again and process them
  	 * in a suitable order
  	 */
7b78fd02f   Jan Kara   udf: Fix handling...
1741
  	if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) {
78ace70c4   Joe Perches   udf: Convert prin...
1742
1743
  		udf_err(sb, "Primary Volume Descriptor not found!
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
1744
1745
  		return -EAGAIN;
  	}
7b78fd02f   Jan Kara   udf: Fix handling...
1746
  	ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block);
d759bfa4e   Jan Kara   udf: Standardize ...
1747
1748
  	if (ret < 0)
  		return ret;
7b78fd02f   Jan Kara   udf: Fix handling...
1749
  	if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) {
d759bfa4e   Jan Kara   udf: Standardize ...
1750
  		ret = udf_load_logicalvol(sb,
7b78fd02f   Jan Kara   udf: Fix handling...
1751
1752
  				data.vds[VDS_POS_LOGICAL_VOL_DESC].block,
  				fileset);
d759bfa4e   Jan Kara   udf: Standardize ...
1753
1754
  		if (ret < 0)
  			return ret;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1755
  	}
165923fa4   Marcin Slusarz   udf: super.c reor...
1756

7b78fd02f   Jan Kara   udf: Fix handling...
1757
  	/* Now handle prevailing Partition Descriptors */
ee4af50ca   Jan Kara   udf: Fix mounting...
1758
1759
1760
1761
  	for (i = 0; i < data.num_part_descs; i++) {
  		ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block);
  		if (ret < 0)
  			return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1762
1763
1764
1765
  	}
  
  	return 0;
  }
d759bfa4e   Jan Kara   udf: Standardize ...
1766
1767
1768
1769
1770
  /*
   * Load Volume Descriptor Sequence described by anchor in bh
   *
   * Returns <0 on error, 0 on success
   */
403460051   Jan Kara   udf: Try anchor i...
1771
1772
  static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
  			     struct kernel_lb_addr *fileset)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1773
  {
403460051   Jan Kara   udf: Try anchor i...
1774
  	struct anchorVolDescPtr *anchor;
d759bfa4e   Jan Kara   udf: Standardize ...
1775
1776
  	sector_t main_s, main_e, reserve_s, reserve_e;
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1777

403460051   Jan Kara   udf: Try anchor i...
1778
1779
1780
1781
1782
1783
  	anchor = (struct anchorVolDescPtr *)bh->b_data;
  
  	/* Locate the main sequence */
  	main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
  	main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
  	main_e = main_e >> sb->s_blocksize_bits;
91c9c9ec5   Jan Kara   udf: Fix off-by-o...
1784
  	main_e += main_s - 1;
403460051   Jan Kara   udf: Try anchor i...
1785
1786
1787
1788
1789
  
  	/* Locate the reserve sequence */
  	reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
  	reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
  	reserve_e = reserve_e >> sb->s_blocksize_bits;
91c9c9ec5   Jan Kara   udf: Fix off-by-o...
1790
  	reserve_e += reserve_s - 1;
403460051   Jan Kara   udf: Try anchor i...
1791
1792
1793
  
  	/* Process the main & reserve sequences */
  	/* responsible for finding the PartitionDesc(s) */
d759bfa4e   Jan Kara   udf: Standardize ...
1794
1795
1796
  	ret = udf_process_sequence(sb, main_s, main_e, fileset);
  	if (ret != -EAGAIN)
  		return ret;
bff943af6   Jan Kara   udf: Fix memory l...
1797
  	udf_sb_free_partitions(sb);
d759bfa4e   Jan Kara   udf: Standardize ...
1798
1799
1800
1801
1802
1803
1804
1805
  	ret = udf_process_sequence(sb, reserve_s, reserve_e, fileset);
  	if (ret < 0) {
  		udf_sb_free_partitions(sb);
  		/* No sequence was OK, return -EIO */
  		if (ret == -EAGAIN)
  			ret = -EIO;
  	}
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1806
  }
403460051   Jan Kara   udf: Try anchor i...
1807
1808
1809
  /*
   * Check whether there is an anchor block in the given block and
   * load Volume Descriptor Sequence if so.
d759bfa4e   Jan Kara   udf: Standardize ...
1810
1811
1812
   *
   * Returns <0 on error, 0 on success, -EAGAIN is special - try next anchor
   * block
403460051   Jan Kara   udf: Try anchor i...
1813
1814
1815
   */
  static int udf_check_anchor_block(struct super_block *sb, sector_t block,
  				  struct kernel_lb_addr *fileset)
1197e4dfc   Clemens Ladisch   udf: use hardware...
1816
  {
403460051   Jan Kara   udf: Try anchor i...
1817
1818
1819
  	struct buffer_head *bh;
  	uint16_t ident;
  	int ret;
1197e4dfc   Clemens Ladisch   udf: use hardware...
1820

403460051   Jan Kara   udf: Try anchor i...
1821
1822
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
  	    udf_fixed_to_variable(block) >=
23bcda112   Fabian Frederick   udf: atomically r...
1823
  	    i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits)
d759bfa4e   Jan Kara   udf: Standardize ...
1824
  		return -EAGAIN;
403460051   Jan Kara   udf: Try anchor i...
1825
1826
1827
  
  	bh = udf_read_tagged(sb, block, block, &ident);
  	if (!bh)
d759bfa4e   Jan Kara   udf: Standardize ...
1828
  		return -EAGAIN;
403460051   Jan Kara   udf: Try anchor i...
1829
1830
  	if (ident != TAG_IDENT_AVDP) {
  		brelse(bh);
d759bfa4e   Jan Kara   udf: Standardize ...
1831
  		return -EAGAIN;
1197e4dfc   Clemens Ladisch   udf: use hardware...
1832
  	}
403460051   Jan Kara   udf: Try anchor i...
1833
1834
1835
  	ret = udf_load_sequence(sb, bh, fileset);
  	brelse(bh);
  	return ret;
1197e4dfc   Clemens Ladisch   udf: use hardware...
1836
  }
d759bfa4e   Jan Kara   udf: Standardize ...
1837
1838
1839
1840
1841
1842
1843
1844
  /*
   * Search for an anchor volume descriptor pointer.
   *
   * Returns < 0 on error, 0 on success. -EAGAIN is special - try next set
   * of anchors.
   */
  static int udf_scan_anchors(struct super_block *sb, sector_t *lastblock,
  			    struct kernel_lb_addr *fileset)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1845
  {
403460051   Jan Kara   udf: Try anchor i...
1846
  	sector_t last[6];
38b74a53e   Jan Kara   udf: Move process...
1847
  	int i;
403460051   Jan Kara   udf: Try anchor i...
1848
1849
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	int last_count = 0;
d759bfa4e   Jan Kara   udf: Standardize ...
1850
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1851

403460051   Jan Kara   udf: Try anchor i...
1852
1853
  	/* First try user provided anchor */
  	if (sbi->s_anchor) {
d759bfa4e   Jan Kara   udf: Standardize ...
1854
1855
1856
  		ret = udf_check_anchor_block(sb, sbi->s_anchor, fileset);
  		if (ret != -EAGAIN)
  			return ret;
403460051   Jan Kara   udf: Try anchor i...
1857
1858
1859
1860
1861
1862
1863
1864
  	}
  	/*
  	 * according to spec, anchor is in either:
  	 *     block 256
  	 *     lastblock-256
  	 *     lastblock
  	 *  however, if the disc isn't closed, it could be 512.
  	 */
d759bfa4e   Jan Kara   udf: Standardize ...
1865
1866
1867
  	ret = udf_check_anchor_block(sb, sbi->s_session + 256, fileset);
  	if (ret != -EAGAIN)
  		return ret;
403460051   Jan Kara   udf: Try anchor i...
1868
1869
1870
1871
  	/*
  	 * The trouble is which block is the last one. Drives often misreport
  	 * this so we try various possibilities.
  	 */
d759bfa4e   Jan Kara   udf: Standardize ...
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
  	last[last_count++] = *lastblock;
  	if (*lastblock >= 1)
  		last[last_count++] = *lastblock - 1;
  	last[last_count++] = *lastblock + 1;
  	if (*lastblock >= 2)
  		last[last_count++] = *lastblock - 2;
  	if (*lastblock >= 150)
  		last[last_count++] = *lastblock - 150;
  	if (*lastblock >= 152)
  		last[last_count++] = *lastblock - 152;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1882

403460051   Jan Kara   udf: Try anchor i...
1883
  	for (i = 0; i < last_count; i++) {
23bcda112   Fabian Frederick   udf: atomically r...
1884
  		if (last[i] >= i_size_read(sb->s_bdev->bd_inode) >>
403460051   Jan Kara   udf: Try anchor i...
1885
  				sb->s_blocksize_bits)
28f7c4d41   Marcin Slusarz   udf: improve read...
1886
  			continue;
d759bfa4e   Jan Kara   udf: Standardize ...
1887
1888
1889
1890
1891
1892
  		ret = udf_check_anchor_block(sb, last[i], fileset);
  		if (ret != -EAGAIN) {
  			if (!ret)
  				*lastblock = last[i];
  			return ret;
  		}
403460051   Jan Kara   udf: Try anchor i...
1893
  		if (last[i] < 256)
28f7c4d41   Marcin Slusarz   udf: improve read...
1894
  			continue;
d759bfa4e   Jan Kara   udf: Standardize ...
1895
1896
1897
1898
1899
1900
  		ret = udf_check_anchor_block(sb, last[i] - 256, fileset);
  		if (ret != -EAGAIN) {
  			if (!ret)
  				*lastblock = last[i];
  			return ret;
  		}
403460051   Jan Kara   udf: Try anchor i...
1901
  	}
28f7c4d41   Marcin Slusarz   udf: improve read...
1902

403460051   Jan Kara   udf: Try anchor i...
1903
  	/* Finally try block 512 in case media is open */
d759bfa4e   Jan Kara   udf: Standardize ...
1904
  	return udf_check_anchor_block(sb, sbi->s_session + 512, fileset);
403460051   Jan Kara   udf: Try anchor i...
1905
  }
28f7c4d41   Marcin Slusarz   udf: improve read...
1906

403460051   Jan Kara   udf: Try anchor i...
1907
1908
1909
1910
1911
  /*
   * Find an anchor volume descriptor and load Volume Descriptor Sequence from
   * area specified by it. The function expects sbi->s_lastblock to be the last
   * block on the media.
   *
d759bfa4e   Jan Kara   udf: Standardize ...
1912
1913
   * Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor
   * was not found.
403460051   Jan Kara   udf: Try anchor i...
1914
1915
1916
1917
   */
  static int udf_find_anchor(struct super_block *sb,
  			   struct kernel_lb_addr *fileset)
  {
403460051   Jan Kara   udf: Try anchor i...
1918
  	struct udf_sb_info *sbi = UDF_SB(sb);
d759bfa4e   Jan Kara   udf: Standardize ...
1919
1920
  	sector_t lastblock = sbi->s_last_block;
  	int ret;
28f7c4d41   Marcin Slusarz   udf: improve read...
1921

d759bfa4e   Jan Kara   udf: Standardize ...
1922
1923
  	ret = udf_scan_anchors(sb, &lastblock, fileset);
  	if (ret != -EAGAIN)
403460051   Jan Kara   udf: Try anchor i...
1924
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1925

403460051   Jan Kara   udf: Try anchor i...
1926
1927
  	/* No anchor found? Try VARCONV conversion of block numbers */
  	UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
d759bfa4e   Jan Kara   udf: Standardize ...
1928
  	lastblock = udf_variable_to_fixed(sbi->s_last_block);
403460051   Jan Kara   udf: Try anchor i...
1929
  	/* Firstly, we try to not convert number of the last block */
d759bfa4e   Jan Kara   udf: Standardize ...
1930
1931
  	ret = udf_scan_anchors(sb, &lastblock, fileset);
  	if (ret != -EAGAIN)
403460051   Jan Kara   udf: Try anchor i...
1932
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1933

d759bfa4e   Jan Kara   udf: Standardize ...
1934
  	lastblock = sbi->s_last_block;
403460051   Jan Kara   udf: Try anchor i...
1935
  	/* Secondly, we try with converted number of the last block */
d759bfa4e   Jan Kara   udf: Standardize ...
1936
1937
  	ret = udf_scan_anchors(sb, &lastblock, fileset);
  	if (ret < 0) {
403460051   Jan Kara   udf: Try anchor i...
1938
1939
  		/* VARCONV didn't help. Clear it. */
  		UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1940
  	}
403460051   Jan Kara   udf: Try anchor i...
1941
  out:
d759bfa4e   Jan Kara   udf: Standardize ...
1942
1943
1944
  	if (ret == 0)
  		sbi->s_last_block = lastblock;
  	return ret;
403460051   Jan Kara   udf: Try anchor i...
1945
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1946

403460051   Jan Kara   udf: Try anchor i...
1947
1948
  /*
   * Check Volume Structure Descriptor, find Anchor block and load Volume
d759bfa4e   Jan Kara   udf: Standardize ...
1949
1950
1951
1952
   * Descriptor Sequence.
   *
   * Returns < 0 on error, 0 on success. -EAGAIN is special meaning anchor
   * block was not found.
403460051   Jan Kara   udf: Try anchor i...
1953
1954
1955
1956
1957
   */
  static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
  			int silent, struct kernel_lb_addr *fileset)
  {
  	struct udf_sb_info *sbi = UDF_SB(sb);
ba54aef03   Steven J. Magnani   udf: refactor VRS...
1958
  	int nsr = 0;
d759bfa4e   Jan Kara   udf: Standardize ...
1959
  	int ret;
403460051   Jan Kara   udf: Try anchor i...
1960
1961
1962
  
  	if (!sb_set_blocksize(sb, uopt->blocksize)) {
  		if (!silent)
78ace70c4   Joe Perches   udf: Convert prin...
1963
1964
  			udf_warn(sb, "Bad block size
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
1965
  		return -EINVAL;
403460051   Jan Kara   udf: Try anchor i...
1966
1967
1968
1969
  	}
  	sbi->s_last_block = uopt->lastblock;
  	if (!uopt->novrs) {
  		/* Check that it is NSR02 compliant */
ba54aef03   Steven J. Magnani   udf: refactor VRS...
1970
1971
  		nsr = udf_check_vsd(sb);
  		if (!nsr) {
403460051   Jan Kara   udf: Try anchor i...
1972
  			if (!silent)
78ace70c4   Joe Perches   udf: Convert prin...
1973
1974
  				udf_warn(sb, "No VRS found
  ");
70f16cef0   Fabian Frederick   udf: allow implic...
1975
  			return -EINVAL;
403460051   Jan Kara   udf: Try anchor i...
1976
  		}
ba54aef03   Steven J. Magnani   udf: refactor VRS...
1977
  		if (nsr == -1)
444996027   Peter A. Felvegi   udf: fix for path...
1978
1979
1980
1981
  			udf_debug("Failed to read sector at offset %d. "
  				  "Assuming open disc. Skipping validity "
  				  "check
  ", VSD_FIRST_SECTOR_OFFSET);
403460051   Jan Kara   udf: Try anchor i...
1982
1983
1984
1985
1986
  		if (!sbi->s_last_block)
  			sbi->s_last_block = udf_get_last_block(sb);
  	} else {
  		udf_debug("Validity check skipped because of novrs option
  ");
28f7c4d41   Marcin Slusarz   udf: improve read...
1987
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1988

403460051   Jan Kara   udf: Try anchor i...
1989
1990
  	/* Look for anchor block and load Volume Descriptor Sequence */
  	sbi->s_anchor = uopt->anchor;
d759bfa4e   Jan Kara   udf: Standardize ...
1991
1992
1993
  	ret = udf_find_anchor(sb, fileset);
  	if (ret < 0) {
  		if (!silent && ret == -EAGAIN)
78ace70c4   Joe Perches   udf: Convert prin...
1994
1995
  			udf_warn(sb, "No anchor found
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
1996
  		return ret;
403460051   Jan Kara   udf: Try anchor i...
1997
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
1998
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1999
  }
ebbd5e99f   Steve Magnani   udf: factor out L...
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
  static void udf_finalize_lvid(struct logicalVolIntegrityDesc *lvid)
  {
  	struct timespec64 ts;
  
  	ktime_get_real_ts64(&ts);
  	udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts);
  	lvid->descTag.descCRC = cpu_to_le16(
  		crc_itu_t(0, (char *)lvid + sizeof(struct tag),
  			le16_to_cpu(lvid->descTag.descCRCLength)));
  	lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2011
2012
  static void udf_open_lvid(struct super_block *sb)
  {
6c79e987d   Marcin Slusarz   udf: remove some ...
2013
2014
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct buffer_head *bh = sbi->s_lvid_bh;
165923fa4   Marcin Slusarz   udf: super.c reor...
2015
2016
  	struct logicalVolIntegrityDesc *lvid;
  	struct logicalVolIntegrityDescImpUse *lvidiu;
146bca72c   Jan Kara   udf: Don't write ...
2017

165923fa4   Marcin Slusarz   udf: super.c reor...
2018
2019
  	if (!bh)
  		return;
165923fa4   Marcin Slusarz   udf: super.c reor...
2020
  	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
69d75671d   Jan Kara   udf: Fortify LVID...
2021
2022
2023
  	lvidiu = udf_sb_lvidiu(sb);
  	if (!lvidiu)
  		return;
165923fa4   Marcin Slusarz   udf: super.c reor...
2024

69d75671d   Jan Kara   udf: Fortify LVID...
2025
  	mutex_lock(&sbi->s_alloc_mutex);
165923fa4   Marcin Slusarz   udf: super.c reor...
2026
2027
  	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
b72e632c6   Jan Kara   udf: Do not mark ...
2028
2029
2030
2031
  	if (le32_to_cpu(lvid->integrityType) == LVID_INTEGRITY_TYPE_CLOSE)
  		lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
  	else
  		UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT);
165923fa4   Marcin Slusarz   udf: super.c reor...
2032

ebbd5e99f   Steve Magnani   udf: factor out L...
2033
  	udf_finalize_lvid(lvid);
165923fa4   Marcin Slusarz   udf: super.c reor...
2034
  	mark_buffer_dirty(bh);
146bca72c   Jan Kara   udf: Don't write ...
2035
  	sbi->s_lvid_dirty = 0;
949f4a7c0   Jan Kara   udf: Protect all ...
2036
  	mutex_unlock(&sbi->s_alloc_mutex);
9734c971a   Jan Kara   udf: Write LVID t...
2037
2038
  	/* Make opening of filesystem visible on the media immediately */
  	sync_dirty_buffer(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2039
2040
2041
2042
  }
  
  static void udf_close_lvid(struct super_block *sb)
  {
6c79e987d   Marcin Slusarz   udf: remove some ...
2043
2044
2045
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct buffer_head *bh = sbi->s_lvid_bh;
  	struct logicalVolIntegrityDesc *lvid;
165923fa4   Marcin Slusarz   udf: super.c reor...
2046
  	struct logicalVolIntegrityDescImpUse *lvidiu;
28de7948a   Cyrill Gorcunov   UDF: coding style...
2047

6c79e987d   Marcin Slusarz   udf: remove some ...
2048
2049
  	if (!bh)
  		return;
69d75671d   Jan Kara   udf: Fortify LVID...
2050
2051
2052
2053
  	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
  	lvidiu = udf_sb_lvidiu(sb);
  	if (!lvidiu)
  		return;
6c79e987d   Marcin Slusarz   udf: remove some ...
2054

949f4a7c0   Jan Kara   udf: Protect all ...
2055
  	mutex_lock(&sbi->s_alloc_mutex);
165923fa4   Marcin Slusarz   udf: super.c reor...
2056
2057
  	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
165923fa4   Marcin Slusarz   udf: super.c reor...
2058
2059
2060
2061
2062
2063
  	if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev))
  		lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
  	if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev))
  		lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev);
  	if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev))
  		lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev);
b72e632c6   Jan Kara   udf: Do not mark ...
2064
2065
  	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT))
  		lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
165923fa4   Marcin Slusarz   udf: super.c reor...
2066

853a0c25b   Jan Kara   udf: Mark LVID bu...
2067
2068
2069
2070
2071
2072
  	/*
  	 * We set buffer uptodate unconditionally here to avoid spurious
  	 * warnings from mark_buffer_dirty() when previous EIO has marked
  	 * the buffer as !uptodate
  	 */
  	set_buffer_uptodate(bh);
ebbd5e99f   Steve Magnani   udf: factor out L...
2073
  	udf_finalize_lvid(lvid);
165923fa4   Marcin Slusarz   udf: super.c reor...
2074
  	mark_buffer_dirty(bh);
146bca72c   Jan Kara   udf: Don't write ...
2075
  	sbi->s_lvid_dirty = 0;
949f4a7c0   Jan Kara   udf: Protect all ...
2076
  	mutex_unlock(&sbi->s_alloc_mutex);
9734c971a   Jan Kara   udf: Write LVID t...
2077
2078
  	/* Make closing of filesystem visible on the media immediately */
  	sync_dirty_buffer(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2079
  }
d664b6af6   Jan Kara   udf: Move handlin...
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
  u64 lvid_get_unique_id(struct super_block *sb)
  {
  	struct buffer_head *bh;
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct logicalVolIntegrityDesc *lvid;
  	struct logicalVolHeaderDesc *lvhd;
  	u64 uniqueID;
  	u64 ret;
  
  	bh = sbi->s_lvid_bh;
  	if (!bh)
  		return 0;
  
  	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
  	lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse;
  
  	mutex_lock(&sbi->s_alloc_mutex);
  	ret = uniqueID = le64_to_cpu(lvhd->uniqueID);
  	if (!(++uniqueID & 0xFFFFFFFF))
  		uniqueID += 16;
  	lvhd->uniqueID = cpu_to_le64(uniqueID);
e8b427473   Steve Magnani   udf: finalize int...
2101
  	udf_updated_lvid(sb);
d664b6af6   Jan Kara   udf: Move handlin...
2102
  	mutex_unlock(&sbi->s_alloc_mutex);
d664b6af6   Jan Kara   udf: Move handlin...
2103
2104
  
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2105
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2106
2107
  static int udf_fill_super(struct super_block *sb, void *options, int silent)
  {
d759bfa4e   Jan Kara   udf: Standardize ...
2108
  	int ret = -EINVAL;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2109
  	struct inode *inode = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2110
  	struct udf_options uopt;
5ca4e4be8   Pekka Enberg   Remove struct typ...
2111
  	struct kernel_lb_addr rootdir, fileset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2112
  	struct udf_sb_info *sbi;
9181f8bf5   Jan Kara   udf: Don't modify...
2113
  	bool lvid_open = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2114
2115
  
  	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
116e5258e   Jan Kara   udf: Provide sane...
2116
2117
2118
  	/* By default we'll use overflow[ug]id when UDF inode [ug]id == -1 */
  	uopt.uid = make_kuid(current_user_ns(), overflowuid);
  	uopt.gid = make_kgid(current_user_ns(), overflowgid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2119
  	uopt.umask = 0;
87bc730c0   Marcin Slusarz   udf: fix default ...
2120
2121
  	uopt.fmode = UDF_INVALID_MODE;
  	uopt.dmode = UDF_INVALID_MODE;
785dffe1d   Chengguang Xu   udf: fix potentia...
2122
  	uopt.nls_map = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2123

033c9da00   Markus Elfring   fs-udf: Improve s...
2124
  	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
9db9f9e31   Alessio Igor Bogani   udf: Remove unnec...
2125
  	if (!sbi)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2126
  		return -ENOMEM;
28de7948a   Cyrill Gorcunov   UDF: coding style...
2127

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2128
  	sb->s_fs_info = sbi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2129

1e7933def   Ingo Molnar   [PATCH] sem2mutex...
2130
  	mutex_init(&sbi->s_alloc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2131

6da80894c   Miklos Szeredi   mount options: fi...
2132
  	if (!udf_parse_options((char *)options, &uopt, false))
fdf2657bc   Markus Elfring   udf: One function...
2133
  		goto parse_options_failure;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2134
2135
  
  	if (uopt.flags & (1 << UDF_FLAG_UTF8) &&
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2136
  	    uopt.flags & (1 << UDF_FLAG_NLS_MAP)) {
8076c363d   Joe Perches   udf: Rename udf_e...
2137
2138
  		udf_err(sb, "utf8 cannot be combined with iocharset
  ");
fdf2657bc   Markus Elfring   udf: One function...
2139
  		goto parse_options_failure;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2140
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2141
  	if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2142
2143
2144
2145
2146
2147
2148
  		uopt.nls_map = load_nls_default();
  		if (!uopt.nls_map)
  			uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP);
  		else
  			udf_debug("Using default NLS map
  ");
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2149
2150
2151
2152
2153
  	if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP)))
  		uopt.flags |= (1 << UDF_FLAG_UTF8);
  
  	fileset.logicalBlockNum = 0xFFFFFFFF;
  	fileset.partitionReferenceNum = 0xFFFF;
6c79e987d   Marcin Slusarz   udf: remove some ...
2154
2155
2156
2157
  	sbi->s_flags = uopt.flags;
  	sbi->s_uid = uopt.uid;
  	sbi->s_gid = uopt.gid;
  	sbi->s_umask = uopt.umask;
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
2158
2159
  	sbi->s_fmode = uopt.fmode;
  	sbi->s_dmode = uopt.dmode;
6c79e987d   Marcin Slusarz   udf: remove some ...
2160
  	sbi->s_nls_map = uopt.nls_map;
c03cad241   Jan Kara   udf: Protect defa...
2161
  	rwlock_init(&sbi->s_cred_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2162

cb00ea352   Cyrill Gorcunov   UDF: coding style...
2163
  	if (uopt.session == 0xFFFFFFFF)
6c79e987d   Marcin Slusarz   udf: remove some ...
2164
  		sbi->s_session = udf_get_last_session(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2165
  	else
6c79e987d   Marcin Slusarz   udf: remove some ...
2166
  		sbi->s_session = uopt.session;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2167

6c79e987d   Marcin Slusarz   udf: remove some ...
2168
2169
  	udf_debug("Multi-session=%d
  ", sbi->s_session);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2170

403460051   Jan Kara   udf: Try anchor i...
2171
2172
2173
  	/* Fill in the rest of the superblock */
  	sb->s_op = &udf_sb_ops;
  	sb->s_export_op = &udf_export_ops;
123e9caf1   Christoph Hellwig   quota: explicitly...
2174

403460051   Jan Kara   udf: Try anchor i...
2175
2176
  	sb->s_magic = UDF_SUPER_MAGIC;
  	sb->s_time_gran = 1000;
1197e4dfc   Clemens Ladisch   udf: use hardware...
2177
  	if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) {
403460051   Jan Kara   udf: Try anchor i...
2178
  		ret = udf_load_vrs(sb, &uopt, silent, &fileset);
1197e4dfc   Clemens Ladisch   udf: use hardware...
2179
  	} else {
e1defc4ff   Martin K. Petersen   block: Do away wi...
2180
  		uopt.blocksize = bdev_logical_block_size(sb->s_bdev);
70f16cef0   Fabian Frederick   udf: allow implic...
2181
  		while (uopt.blocksize <= 4096) {
403460051   Jan Kara   udf: Try anchor i...
2182
  			ret = udf_load_vrs(sb, &uopt, silent, &fileset);
70f16cef0   Fabian Frederick   udf: allow implic...
2183
2184
  			if (ret < 0) {
  				if (!silent && ret != -EACCES) {
fcbf7637e   Steve Magnani   udf: Fix signed/u...
2185
2186
  					pr_notice("Scanning with blocksize %u failed
  ",
70f16cef0   Fabian Frederick   udf: allow implic...
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
  						  uopt.blocksize);
  				}
  				brelse(sbi->s_lvid_bh);
  				sbi->s_lvid_bh = NULL;
  				/*
  				 * EACCES is special - we want to propagate to
  				 * upper layers that we cannot handle RW mount.
  				 */
  				if (ret == -EACCES)
  					break;
  			} else
  				break;
  
  			uopt.blocksize <<= 1;
1197e4dfc   Clemens Ladisch   udf: use hardware...
2201
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2202
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
2203
2204
2205
2206
2207
2208
  	if (ret < 0) {
  		if (ret == -EAGAIN) {
  			udf_warn(sb, "No partition found (1)
  ");
  			ret = -EINVAL;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2209
2210
  		goto error_out;
  	}
fcbf7637e   Steve Magnani   udf: Fix signed/u...
2211
2212
  	udf_debug("Lastblock=%u
  ", sbi->s_last_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2213

6c79e987d   Marcin Slusarz   udf: remove some ...
2214
  	if (sbi->s_lvid_bh) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2215
  		struct logicalVolIntegrityDescImpUse *lvidiu =
69d75671d   Jan Kara   udf: Fortify LVID...
2216
2217
2218
  							udf_sb_lvidiu(sb);
  		uint16_t minUDFReadRev;
  		uint16_t minUDFWriteRev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2219

69d75671d   Jan Kara   udf: Fortify LVID...
2220
2221
2222
2223
2224
2225
  		if (!lvidiu) {
  			ret = -EINVAL;
  			goto error_out;
  		}
  		minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev);
  		minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2226
  		if (minUDFReadRev > UDF_MAX_READ_VERSION) {
78ace70c4   Joe Perches   udf: Convert prin...
2227
2228
  			udf_err(sb, "minUDFReadRev=%x (max is %x)
  ",
69d75671d   Jan Kara   udf: Fortify LVID...
2229
  				minUDFReadRev,
78ace70c4   Joe Perches   udf: Convert prin...
2230
  				UDF_MAX_READ_VERSION);
d759bfa4e   Jan Kara   udf: Standardize ...
2231
  			ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2232
  			goto error_out;
a9ad01bc7   Jan Kara   udf: Prevent writ...
2233
2234
2235
2236
2237
2238
  		} else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) {
  			if (!sb_rdonly(sb)) {
  				ret = -EACCES;
  				goto error_out;
  			}
  			UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
e729eac6f   Jan Kara   udf: Refuse RW mo...
2239
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2240

6c79e987d   Marcin Slusarz   udf: remove some ...
2241
  		sbi->s_udfrev = minUDFWriteRev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2242
2243
2244
2245
2246
2247
  
  		if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE)
  			UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE);
  		if (minUDFReadRev >= UDF_VERS_USE_STREAMS)
  			UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS);
  	}
6c79e987d   Marcin Slusarz   udf: remove some ...
2248
  	if (!sbi->s_partitions) {
78ace70c4   Joe Perches   udf: Convert prin...
2249
2250
  		udf_warn(sb, "No partition found (2)
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
2251
  		ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2252
2253
  		goto error_out;
  	}
4b11111ab   Marcin Slusarz   udf: fix coding s...
2254
  	if (sbi->s_partmaps[sbi->s_partition].s_partition_flags &
a9ad01bc7   Jan Kara   udf: Prevent writ...
2255
2256
2257
2258
2259
2260
  			UDF_PART_FLAG_READ_ONLY) {
  		if (!sb_rdonly(sb)) {
  			ret = -EACCES;
  			goto error_out;
  		}
  		UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
c1a26e7d4   Peter Osterlund   [PATCH] UDF: Fix ...
2261
  	}
39b3f6d6e   Eric Sandeen   [PATCH] mount udf...
2262

2dee5aac0   Jan Kara   udf: Verify domai...
2263
2264
  	ret = udf_find_fileset(sb, &fileset, &rootdir);
  	if (ret < 0) {
78ace70c4   Joe Perches   udf: Convert prin...
2265
2266
  		udf_warn(sb, "No fileset found
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2267
2268
  		goto error_out;
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2269
  	if (!silent) {
5ca4e4be8   Pekka Enberg   Remove struct typ...
2270
  		struct timestamp ts;
56774805d   Marcin Slusarz   udf: convert udf_...
2271
  		udf_time_to_disk_stamp(&ts, sbi->s_record_time);
78ace70c4   Joe Perches   udf: Convert prin...
2272
2273
2274
2275
  		udf_info("Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)
  ",
  			 sbi->s_volume_ident,
  			 le16_to_cpu(ts.year), ts.month, ts.day,
56774805d   Marcin Slusarz   udf: convert udf_...
2276
  			 ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2277
  	}
bc98a42c1   David Howells   VFS: Convert sb->...
2278
  	if (!sb_rdonly(sb)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2279
  		udf_open_lvid(sb);
9181f8bf5   Jan Kara   udf: Don't modify...
2280
2281
  		lvid_open = true;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2282
2283
2284
2285
  
  	/* Assign the root inode */
  	/* assign inodes by physical block number */
  	/* perhaps it's not extensible enough, but for now ... */
97e961fdb   Pekka Enberg   Fix the udf code ...
2286
  	inode = udf_iget(sb, &rootdir);
6d3d5e860   Jan Kara   udf: Make udf_rea...
2287
  	if (IS_ERR(inode)) {
fcbf7637e   Steve Magnani   udf: Fix signed/u...
2288
2289
  		udf_err(sb, "Error in udf_iget, block=%u, partition=%u
  ",
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2290
  		       rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
6d3d5e860   Jan Kara   udf: Make udf_rea...
2291
  		ret = PTR_ERR(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2292
2293
2294
2295
  		goto error_out;
  	}
  
  	/* Allocate a dentry for the root inode */
48fde701a   Al Viro   switch open-coded...
2296
  	sb->s_root = d_make_root(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2297
  	if (!sb->s_root) {
78ace70c4   Joe Perches   udf: Convert prin...
2298
2299
  		udf_err(sb, "Couldn't allocate root dentry
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
2300
  		ret = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2301
2302
  		goto error_out;
  	}
31170b6ad   Jan Kara   udf: support file...
2303
  	sb->s_maxbytes = MAX_LFS_FILESIZE;
8de527787   Al Viro   vfs: check i_nlin...
2304
  	sb->s_max_links = UDF_MAX_LINKS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2305
  	return 0;
28de7948a   Cyrill Gorcunov   UDF: coding style...
2306
  error_out:
0d454e4a4   Markus Elfring   udf: Deletion of ...
2307
  	iput(sbi->s_vat_inode);
fdf2657bc   Markus Elfring   udf: One function...
2308
  parse_options_failure:
785dffe1d   Chengguang Xu   udf: fix potentia...
2309
2310
  	if (uopt.nls_map)
  		unload_nls(uopt.nls_map);
9181f8bf5   Jan Kara   udf: Don't modify...
2311
  	if (lvid_open)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2312
  		udf_close_lvid(sb);
6c79e987d   Marcin Slusarz   udf: remove some ...
2313
  	brelse(sbi->s_lvid_bh);
bff943af6   Jan Kara   udf: Fix memory l...
2314
  	udf_sb_free_partitions(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2315
2316
  	kfree(sbi);
  	sb->s_fs_info = NULL;
28de7948a   Cyrill Gorcunov   UDF: coding style...
2317

d759bfa4e   Jan Kara   udf: Standardize ...
2318
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2319
  }
8076c363d   Joe Perches   udf: Rename udf_e...
2320
2321
  void _udf_err(struct super_block *sb, const char *function,
  	      const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2322
  {
c2bff36c2   Joe Perches   udf: Neaten loggi...
2323
  	struct va_format vaf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2324
  	va_list args;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2325
  	va_start(args, fmt);
c2bff36c2   Joe Perches   udf: Neaten loggi...
2326
2327
2328
2329
2330
  
  	vaf.fmt = fmt;
  	vaf.va = &args;
  
  	pr_err("error (device %s): %s: %pV", sb->s_id, function, &vaf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2331
  	va_end(args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2332
  }
a40ecd7b3   Joe Perches   udf: Rename udf_w...
2333
2334
  void _udf_warn(struct super_block *sb, const char *function,
  	       const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2335
  {
c2bff36c2   Joe Perches   udf: Neaten loggi...
2336
  	struct va_format vaf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2337
  	va_list args;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2338
  	va_start(args, fmt);
c2bff36c2   Joe Perches   udf: Neaten loggi...
2339
2340
2341
2342
2343
  
  	vaf.fmt = fmt;
  	vaf.va = &args;
  
  	pr_warn("warning (device %s): %s: %pV", sb->s_id, function, &vaf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2344
  	va_end(args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2345
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2346
  static void udf_put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2347
  {
6c79e987d   Marcin Slusarz   udf: remove some ...
2348
  	struct udf_sb_info *sbi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2349

6c79e987d   Marcin Slusarz   udf: remove some ...
2350
  	sbi = UDF_SB(sb);
6cfd01484   Christoph Hellwig   push BKL down int...
2351

0d454e4a4   Markus Elfring   udf: Deletion of ...
2352
  	iput(sbi->s_vat_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2353
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
6c79e987d   Marcin Slusarz   udf: remove some ...
2354
  		unload_nls(sbi->s_nls_map);
bc98a42c1   David Howells   VFS: Convert sb->...
2355
  	if (!sb_rdonly(sb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2356
  		udf_close_lvid(sb);
6c79e987d   Marcin Slusarz   udf: remove some ...
2357
  	brelse(sbi->s_lvid_bh);
bff943af6   Jan Kara   udf: Fix memory l...
2358
  	udf_sb_free_partitions(sb);
bbe48dd81   Fabian Frederick   udf: destroy sbi ...
2359
  	mutex_destroy(&sbi->s_alloc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2360
2361
2362
  	kfree(sb->s_fs_info);
  	sb->s_fs_info = NULL;
  }
146bca72c   Jan Kara   udf: Don't write ...
2363
2364
2365
2366
2367
2368
  static int udf_sync_fs(struct super_block *sb, int wait)
  {
  	struct udf_sb_info *sbi = UDF_SB(sb);
  
  	mutex_lock(&sbi->s_alloc_mutex);
  	if (sbi->s_lvid_dirty) {
e8b427473   Steve Magnani   udf: finalize int...
2369
  		struct buffer_head *bh = sbi->s_lvid_bh;
52b9666ef   Jan Kara   udf: Drop pointle...
2370
  		struct logicalVolIntegrityDesc *lvid;
e8b427473   Steve Magnani   udf: finalize int...
2371

52b9666ef   Jan Kara   udf: Drop pointle...
2372
2373
  		lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
  		udf_finalize_lvid(lvid);
e8b427473   Steve Magnani   udf: finalize int...
2374

146bca72c   Jan Kara   udf: Don't write ...
2375
2376
2377
2378
  		/*
  		 * Blockdevice will be synced later so we don't have to submit
  		 * the buffer for IO
  		 */
e8b427473   Steve Magnani   udf: finalize int...
2379
  		mark_buffer_dirty(bh);
146bca72c   Jan Kara   udf: Don't write ...
2380
2381
2382
2383
2384
2385
  		sbi->s_lvid_dirty = 0;
  	}
  	mutex_unlock(&sbi->s_alloc_mutex);
  
  	return 0;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2386
  static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2387
  {
726c33422   David Howells   [PATCH] VFS: Perm...
2388
  	struct super_block *sb = dentry->d_sb;
6c79e987d   Marcin Slusarz   udf: remove some ...
2389
2390
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct logicalVolIntegrityDescImpUse *lvidiu;
557f5a146   Coly Li   udf: return f_fsi...
2391
  	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
6c79e987d   Marcin Slusarz   udf: remove some ...
2392

69d75671d   Jan Kara   udf: Fortify LVID...
2393
  	lvidiu = udf_sb_lvidiu(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2394
2395
  	buf->f_type = UDF_SUPER_MAGIC;
  	buf->f_bsize = sb->s_blocksize;
6c79e987d   Marcin Slusarz   udf: remove some ...
2396
  	buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2397
2398
  	buf->f_bfree = udf_count_free(sb);
  	buf->f_bavail = buf->f_bfree;
6c79e987d   Marcin Slusarz   udf: remove some ...
2399
2400
2401
  	buf->f_files = (lvidiu != NULL ? (le32_to_cpu(lvidiu->numFiles) +
  					  le32_to_cpu(lvidiu->numDirs)) : 0)
  			+ buf->f_bfree;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2402
  	buf->f_ffree = buf->f_bfree;
9fba70569   Andrew Gabbasov   udf: Adjust UDF_N...
2403
  	buf->f_namelen = UDF_NAME_LEN;
557f5a146   Coly Li   udf: return f_fsi...
2404
2405
  	buf->f_fsid.val[0] = (u32)id;
  	buf->f_fsid.val[1] = (u32)(id >> 32);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2406
2407
2408
  
  	return 0;
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
2409
2410
  static unsigned int udf_count_free_bitmap(struct super_block *sb,
  					  struct udf_bitmap *bitmap)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2411
2412
2413
2414
  {
  	struct buffer_head *bh = NULL;
  	unsigned int accum = 0;
  	int index;
b490bdd63   Steve Magnani   udf: Fix 64-bit s...
2415
  	udf_pblk_t block = 0, newblock;
5ca4e4be8   Pekka Enberg   Remove struct typ...
2416
  	struct kernel_lb_addr loc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2417
  	uint32_t bytes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2418
2419
2420
  	uint8_t *ptr;
  	uint16_t ident;
  	struct spaceBitmapDesc *bm;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2421
  	loc.logicalBlockNum = bitmap->s_extPosition;
6c79e987d   Marcin Slusarz   udf: remove some ...
2422
  	loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
97e961fdb   Pekka Enberg   Fix the udf code ...
2423
  	bh = udf_read_ptagged(sb, &loc, 0, &ident);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2424

cb00ea352   Cyrill Gorcunov   UDF: coding style...
2425
  	if (!bh) {
78ace70c4   Joe Perches   udf: Convert prin...
2426
2427
  		udf_err(sb, "udf_count_free failed
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2428
  		goto out;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2429
  	} else if (ident != TAG_IDENT_SBD) {
3bf25cb40   Jan Kara   udf: use get_bh()
2430
  		brelse(bh);
78ace70c4   Joe Perches   udf: Convert prin...
2431
2432
  		udf_err(sb, "udf_count_free failed
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2433
2434
2435
2436
2437
  		goto out;
  	}
  
  	bm = (struct spaceBitmapDesc *)bh->b_data;
  	bytes = le32_to_cpu(bm->numOfBytes);
28de7948a   Cyrill Gorcunov   UDF: coding style...
2438
2439
  	index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
  	ptr = (uint8_t *)bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2440

cb00ea352   Cyrill Gorcunov   UDF: coding style...
2441
  	while (bytes > 0) {
01b954a36   Marcin Slusarz   udf: convert udf_...
2442
2443
2444
2445
  		u32 cur_bytes = min_t(u32, bytes, sb->s_blocksize - index);
  		accum += bitmap_weight((const unsigned long *)(ptr + index),
  					cur_bytes * 8);
  		bytes -= cur_bytes;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2446
  		if (bytes) {
3bf25cb40   Jan Kara   udf: use get_bh()
2447
  			brelse(bh);
97e961fdb   Pekka Enberg   Fix the udf code ...
2448
  			newblock = udf_get_lb_pblock(sb, &loc, ++block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2449
  			bh = udf_tread(sb, newblock);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2450
  			if (!bh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2451
2452
2453
2454
2455
  				udf_debug("read failed
  ");
  				goto out;
  			}
  			index = 0;
28de7948a   Cyrill Gorcunov   UDF: coding style...
2456
  			ptr = (uint8_t *)bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2457
2458
  		}
  	}
3bf25cb40   Jan Kara   udf: use get_bh()
2459
  	brelse(bh);
28de7948a   Cyrill Gorcunov   UDF: coding style...
2460
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2461
2462
  	return accum;
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
2463
2464
  static unsigned int udf_count_free_table(struct super_block *sb,
  					 struct inode *table)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2465
2466
  {
  	unsigned int accum = 0;
ff116fc8d   Jan Kara   UDF: introduce st...
2467
  	uint32_t elen;
5ca4e4be8   Pekka Enberg   Remove struct typ...
2468
  	struct kernel_lb_addr eloc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2469
  	int8_t etype;
ff116fc8d   Jan Kara   UDF: introduce st...
2470
  	struct extent_position epos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2471

d1668fe39   Jan Kara   udf: Remove BKL f...
2472
  	mutex_lock(&UDF_SB(sb)->s_alloc_mutex);
c0b344385   Marcin Slusarz   udf: remove UDF_I...
2473
  	epos.block = UDF_I(table)->i_location;
ff116fc8d   Jan Kara   UDF: introduce st...
2474
2475
  	epos.offset = sizeof(struct unallocSpaceEntry);
  	epos.bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2476

3a71fc5de   Marcin Slusarz   udf: fix coding s...
2477
  	while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2478
  		accum += (elen >> table->i_sb->s_blocksize_bits);
3a71fc5de   Marcin Slusarz   udf: fix coding s...
2479

3bf25cb40   Jan Kara   udf: use get_bh()
2480
  	brelse(epos.bh);
d1668fe39   Jan Kara   udf: Remove BKL f...
2481
  	mutex_unlock(&UDF_SB(sb)->s_alloc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2482
2483
2484
  
  	return accum;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2485
2486
  
  static unsigned int udf_count_free(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2487
2488
  {
  	unsigned int accum = 0;
6c79e987d   Marcin Slusarz   udf: remove some ...
2489
2490
  	struct udf_sb_info *sbi;
  	struct udf_part_map *map;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2491

6c79e987d   Marcin Slusarz   udf: remove some ...
2492
2493
  	sbi = UDF_SB(sb);
  	if (sbi->s_lvid_bh) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2494
2495
2496
  		struct logicalVolIntegrityDesc *lvid =
  			(struct logicalVolIntegrityDesc *)
  			sbi->s_lvid_bh->b_data;
6c79e987d   Marcin Slusarz   udf: remove some ...
2497
  		if (le32_to_cpu(lvid->numOfPartitions) > sbi->s_partition) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2498
2499
  			accum = le32_to_cpu(
  					lvid->freeSpaceTable[sbi->s_partition]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2500
2501
2502
2503
2504
2505
2506
  			if (accum == 0xFFFFFFFF)
  				accum = 0;
  		}
  	}
  
  	if (accum)
  		return accum;
6c79e987d   Marcin Slusarz   udf: remove some ...
2507
2508
  	map = &sbi->s_partmaps[sbi->s_partition];
  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
28de7948a   Cyrill Gorcunov   UDF: coding style...
2509
  		accum += udf_count_free_bitmap(sb,
6c79e987d   Marcin Slusarz   udf: remove some ...
2510
  					       map->s_uspace.s_bitmap);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2511
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2512
2513
  	if (accum)
  		return accum;
6c79e987d   Marcin Slusarz   udf: remove some ...
2514
  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
28de7948a   Cyrill Gorcunov   UDF: coding style...
2515
  		accum += udf_count_free_table(sb,
6c79e987d   Marcin Slusarz   udf: remove some ...
2516
  					      map->s_uspace.s_table);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2517
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2518
2519
  	return accum;
  }
54bb60d53   Fabian Frederick   udf: merge module...
2520
2521
2522
2523
2524
2525
  
  MODULE_AUTHOR("Ben Fennema");
  MODULE_DESCRIPTION("Universal Disk Format Filesystem");
  MODULE_LICENSE("GPL");
  module_init(init_udf_fs)
  module_exit(exit_udf_fs)