Blame view

fs/udf/super.c 67.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * 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/
248727a49   Alexander A. Klimov   udf: Replace HTTP...
14
15
   *    https://www.ecma.ch/
   *    https://www.iso.org/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
   *
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

382a2287b   Jan Kara   udf: Remove point...
164
  	ei->i_data = NULL;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
165
  	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
  static int udf_verify_domain_identifier(struct super_block *sb,
  					struct regid *ident, char *dname)
  {
871b9b14c   Pali Rohár   udf: Move OSTA Id...
752
  	struct domainIdentSuffix *suffix;
8b47ea6c2   Jan Kara   udf: Drop forward...
753
754
755
756
757
758
  
  	if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) {
  		udf_warn(sb, "Not OSTA UDF compliant %s descriptor.
  ", dname);
  		goto force_ro;
  	}
49be68c49   Pali Rohár   udf: Fix meaning ...
759
  	if (ident->flags & ENTITYID_FLAGS_DIRTY) {
8b47ea6c2   Jan Kara   udf: Drop forward...
760
761
762
763
764
  		udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor.
  ",
  			 dname);
  		goto force_ro;
  	}
871b9b14c   Pali Rohár   udf: Move OSTA Id...
765
766
767
  	suffix = (struct domainIdentSuffix *)ident->identSuffix;
  	if ((suffix->domainFlags & DOMAIN_FLAGS_HARD_WRITE_PROTECT) ||
  	    (suffix->domainFlags & DOMAIN_FLAGS_SOFT_WRITE_PROTECT)) {
8b47ea6c2   Jan Kara   udf: Drop forward...
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
  		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;
aa9f6661e   Jing Xiangfeng   udf: Remove redun...
842
  	int ret;
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
  	struct udf_bitmap *bitmap;
256ccb9ba   Denis Efremov   udf: Use kvzalloc...
1001
  	int nr_groups = udf_compute_nr_groups(sb, index);
66e1da3f4   Marcin Slusarz   udf: convert macr...
1002

256ccb9ba   Denis Efremov   udf: Use kvzalloc...
1003
1004
  	bitmap = kvzalloc(struct_size(bitmap, s_block_bitmap, nr_groups),
  			  GFP_KERNEL);
ba2eb866a   Markus Elfring   fs-udf: Adjust tw...
1005
  	if (!bitmap)
66e1da3f4   Marcin Slusarz   udf: convert macr...
1006
  		return NULL;
66e1da3f4   Marcin Slusarz   udf: convert macr...
1007

66e1da3f4   Marcin Slusarz   udf: convert macr...
1008
1009
1010
  	bitmap->s_nr_groups = nr_groups;
  	return bitmap;
  }
b085fbe2e   Jan Kara   udf: Fix crash du...
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
  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:
b085fbe2e   Jan Kara   udf: Fix crash du...
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
  	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 ||
57debb815   Pali Rohár   udf: Disallow R/W...
1048
1049
  	    map->s_partition_type == UDF_VIRTUAL_MAP20 ||
  	    map->s_partition_type == UDF_METADATA_MAP25)
b085fbe2e   Jan Kara   udf: Fix crash du...
1050
1051
1052
1053
1054
1055
1056
1057
1058
  		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...
1059
1060
  static int udf_fill_partdesc_info(struct super_block *sb,
  		struct partitionDesc *p, int p_index)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1061
  {
6c79e987d   Marcin Slusarz   udf: remove some ...
1062
  	struct udf_part_map *map;
165923fa4   Marcin Slusarz   udf: super.c reor...
1063
  	struct udf_sb_info *sbi = UDF_SB(sb);
3fb38dfa0   Jan Kara   udf: Move filling...
1064
  	struct partitionHeaderDesc *phd;
b085fbe2e   Jan Kara   udf: Fix crash du...
1065
  	int err;
165923fa4   Marcin Slusarz   udf: super.c reor...
1066

3fb38dfa0   Jan Kara   udf: Move filling...
1067
  	map = &sbi->s_partmaps[p_index];
165923fa4   Marcin Slusarz   udf: super.c reor...
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
  
  	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...
1080
1081
  	udf_debug("Partition (%d type %x) starts at physical %u, block length %u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1082
1083
  		  p_index, map->s_partition_type,
  		  map->s_partition_root, map->s_partition_len);
165923fa4   Marcin Slusarz   udf: super.c reor...
1084

b085fbe2e   Jan Kara   udf: Fix crash du...
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
  	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...
1095
  		return 0;
165923fa4   Marcin Slusarz   udf: super.c reor...
1096
1097
1098
  
  	phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
  	if (phd->unallocSpaceTable.extLength) {
5ca4e4be8   Pekka Enberg   Remove struct typ...
1099
  		struct kernel_lb_addr loc = {
165923fa4   Marcin Slusarz   udf: super.c reor...
1100
1101
  			.logicalBlockNum = le32_to_cpu(
  				phd->unallocSpaceTable.extPosition),
3fb38dfa0   Jan Kara   udf: Move filling...
1102
  			.partitionReferenceNum = p_index,
165923fa4   Marcin Slusarz   udf: super.c reor...
1103
  		};
6d3d5e860   Jan Kara   udf: Make udf_rea...
1104
  		struct inode *inode;
165923fa4   Marcin Slusarz   udf: super.c reor...
1105

6174c2eb8   Jan Kara   udf: Fix loading ...
1106
  		inode = udf_iget_special(sb, &loc);
6d3d5e860   Jan Kara   udf: Make udf_rea...
1107
  		if (IS_ERR(inode)) {
165923fa4   Marcin Slusarz   udf: super.c reor...
1108
1109
  			udf_debug("cannot load unallocSpaceTable (part %d)
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1110
  				  p_index);
6d3d5e860   Jan Kara   udf: Make udf_rea...
1111
  			return PTR_ERR(inode);
165923fa4   Marcin Slusarz   udf: super.c reor...
1112
  		}
6d3d5e860   Jan Kara   udf: Make udf_rea...
1113
  		map->s_uspace.s_table = inode;
165923fa4   Marcin Slusarz   udf: super.c reor...
1114
  		map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE;
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1115
1116
  		udf_debug("unallocSpaceTable (part %d) @ %lu
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1117
  			  p_index, map->s_uspace.s_table->i_ino);
165923fa4   Marcin Slusarz   udf: super.c reor...
1118
1119
1120
  	}
  
  	if (phd->unallocSpaceBitmap.extLength) {
3fb38dfa0   Jan Kara   udf: Move filling...
1121
1122
  		struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
  		if (!bitmap)
d759bfa4e   Jan Kara   udf: Standardize ...
1123
  			return -ENOMEM;
165923fa4   Marcin Slusarz   udf: super.c reor...
1124
  		map->s_uspace.s_bitmap = bitmap;
2e0838fd0   Jan Kara   udf: Improve erro...
1125
  		bitmap->s_extPosition = le32_to_cpu(
165923fa4   Marcin Slusarz   udf: super.c reor...
1126
  				phd->unallocSpaceBitmap.extPosition);
2e0838fd0   Jan Kara   udf: Improve erro...
1127
  		map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
fcbf7637e   Steve Magnani   udf: Fix signed/u...
1128
1129
  		udf_debug("unallocSpaceBitmap (part %d) @ %u
  ",
a983f368f   Joe Perches   udf: Neaten udf_d...
1130
  			  p_index, bitmap->s_extPosition);
165923fa4   Marcin Slusarz   udf: super.c reor...
1131
  	}
3fb38dfa0   Jan Kara   udf: Move filling...
1132
1133
  	return 0;
  }
e971b0b9e   Jan Kara   udf: Try harder w...
1134
1135
  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...
1136
1137
1138
  {
  	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...
1139
  	sector_t vat_block;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1140
  	struct kernel_lb_addr ino;
6d3d5e860   Jan Kara   udf: Make udf_rea...
1141
  	struct inode *inode;
e971b0b9e   Jan Kara   udf: Try harder w...
1142
1143
1144
1145
1146
1147
1148
1149
  
  	/*
  	 * 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...
1150
  	     vat_block >= start_block - 3; vat_block--) {
e971b0b9e   Jan Kara   udf: Try harder w...
1151
  		ino.logicalBlockNum = vat_block - map->s_partition_root;
6174c2eb8   Jan Kara   udf: Fix loading ...
1152
  		inode = udf_iget_special(sb, &ino);
6d3d5e860   Jan Kara   udf: Make udf_rea...
1153
1154
1155
1156
  		if (!IS_ERR(inode)) {
  			sbi->s_vat_inode = inode;
  			break;
  		}
e971b0b9e   Jan Kara   udf: Try harder w...
1157
1158
1159
1160
1161
1162
1163
  	}
  }
  
  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...
1164
1165
1166
1167
  	struct buffer_head *bh = NULL;
  	struct udf_inode_info *vati;
  	uint32_t pos;
  	struct virtualAllocationTable20 *vat20;
23bcda112   Fabian Frederick   udf: atomically r...
1168
1169
  	sector_t blocks = i_size_read(sb->s_bdev->bd_inode) >>
  			  sb->s_blocksize_bits;
38b74a53e   Jan Kara   udf: Move process...
1170

e971b0b9e   Jan Kara   udf: Try harder w...
1171
  	udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
4bf17af0d   Jan Kara   udf: Fix loading ...
1172
1173
  	if (!sbi->s_vat_inode &&
  	    sbi->s_last_block != blocks - 1) {
78ace70c4   Joe Perches   udf: Convert prin...
1174
1175
1176
1177
  		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...
1178
  		udf_find_vat_block(sb, p_index, type1_index, blocks - 1);
4bf17af0d   Jan Kara   udf: Fix loading ...
1179
  	}
38b74a53e   Jan Kara   udf: Move process...
1180
  	if (!sbi->s_vat_inode)
d759bfa4e   Jan Kara   udf: Standardize ...
1181
  		return -EIO;
38b74a53e   Jan Kara   udf: Move process...
1182
1183
  
  	if (map->s_partition_type == UDF_VIRTUAL_MAP15) {
47c9358a0   Sebastian Manciulea   udf: Fix bug in V...
1184
  		map->s_type_specific.s_virtual.s_start_offset = 0;
38b74a53e   Jan Kara   udf: Move process...
1185
1186
1187
  		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...
1188
1189
1190
1191
1192
  		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 ...
1193
  				return -EIO;
fa5e08156   Jan Kara   udf: Handle VAT p...
1194
1195
1196
  			vat20 = (struct virtualAllocationTable20 *)bh->b_data;
  		} else {
  			vat20 = (struct virtualAllocationTable20 *)
382a2287b   Jan Kara   udf: Remove point...
1197
  							vati->i_data;
fa5e08156   Jan Kara   udf: Handle VAT p...
1198
  		}
38b74a53e   Jan Kara   udf: Move process...
1199

38b74a53e   Jan Kara   udf: Move process...
1200
  		map->s_type_specific.s_virtual.s_start_offset =
47c9358a0   Sebastian Manciulea   udf: Fix bug in V...
1201
  			le16_to_cpu(vat20->lengthHeader);
38b74a53e   Jan Kara   udf: Move process...
1202
1203
1204
1205
1206
1207
1208
1209
  		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 ...
1210
1211
1212
1213
1214
1215
  /*
   * Load partition descriptor block
   *
   * Returns <0 on error, 0 on success, -EAGAIN is special - try next descriptor
   * sequence.
   */
3fb38dfa0   Jan Kara   udf: Move filling...
1216
1217
1218
1219
1220
1221
  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...
1222
  	int i, type1_idx;
3fb38dfa0   Jan Kara   udf: Move filling...
1223
1224
  	uint16_t partitionNumber;
  	uint16_t ident;
d759bfa4e   Jan Kara   udf: Standardize ...
1225
  	int ret;
3fb38dfa0   Jan Kara   udf: Move filling...
1226
1227
1228
  
  	bh = udf_read_tagged(sb, block, block, &ident);
  	if (!bh)
d759bfa4e   Jan Kara   udf: Standardize ...
1229
1230
1231
  		return -EAGAIN;
  	if (ident != TAG_IDENT_PD) {
  		ret = 0;
3fb38dfa0   Jan Kara   udf: Move filling...
1232
  		goto out_bh;
d759bfa4e   Jan Kara   udf: Standardize ...
1233
  	}
3fb38dfa0   Jan Kara   udf: Move filling...
1234
1235
1236
  
  	p = (struct partitionDesc *)bh->b_data;
  	partitionNumber = le16_to_cpu(p->partitionNumber);
38b74a53e   Jan Kara   udf: Move process...
1237

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

3fb38dfa0   Jan Kara   udf: Move filling...
1257
  	ret = udf_fill_partdesc_info(sb, p, i);
d759bfa4e   Jan Kara   udf: Standardize ...
1258
1259
  	if (ret < 0)
  		goto out_bh;
38b74a53e   Jan Kara   udf: Move process...
1260
1261
  
  	/*
bfb257a59   Jan Kara   udf: Add read-onl...
1262
1263
  	 * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and
  	 * PHYSICAL partitions are already set up
38b74a53e   Jan Kara   udf: Move process...
1264
1265
  	 */
  	type1_idx = i;
444996027   Peter A. Felvegi   udf: fix for path...
1266
  	map = NULL; /* supress 'maybe used uninitialized' warning */
38b74a53e   Jan Kara   udf: Move process...
1267
1268
1269
1270
1271
  	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...
1272
1273
  		     map->s_partition_type == UDF_VIRTUAL_MAP20 ||
  		     map->s_partition_type == UDF_METADATA_MAP25))
38b74a53e   Jan Kara   udf: Move process...
1274
1275
  			break;
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
1276
1277
  	if (i >= sbi->s_partitions) {
  		ret = 0;
38b74a53e   Jan Kara   udf: Move process...
1278
  		goto out_bh;
d759bfa4e   Jan Kara   udf: Standardize ...
1279
  	}
38b74a53e   Jan Kara   udf: Move process...
1280
1281
  
  	ret = udf_fill_partdesc_info(sb, p, i);
d759bfa4e   Jan Kara   udf: Standardize ...
1282
  	if (ret < 0)
38b74a53e   Jan Kara   udf: Move process...
1283
  		goto out_bh;
bfb257a59   Jan Kara   udf: Add read-onl...
1284
  	if (map->s_partition_type == UDF_METADATA_MAP25) {
7888824b0   Alden Tondettar   udf: Use correct ...
1285
  		ret = udf_load_metadata_files(sb, i, type1_idx);
d759bfa4e   Jan Kara   udf: Standardize ...
1286
  		if (ret < 0) {
78ace70c4   Joe Perches   udf: Convert prin...
1287
1288
1289
  			udf_err(sb, "error loading MetaData partition map %d
  ",
  				i);
bfb257a59   Jan Kara   udf: Add read-onl...
1290
1291
1292
  			goto out_bh;
  		}
  	} else {
e729eac6f   Jan Kara   udf: Refuse RW mo...
1293
1294
1295
1296
1297
  		/*
  		 * 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->...
1298
  		if (!sb_rdonly(sb)) {
e729eac6f   Jan Kara   udf: Refuse RW mo...
1299
1300
1301
  			ret = -EACCES;
  			goto out_bh;
  		}
a9ad01bc7   Jan Kara   udf: Prevent writ...
1302
  		UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
bfb257a59   Jan Kara   udf: Add read-onl...
1303
  		ret = udf_load_vat(sb, i, type1_idx);
d759bfa4e   Jan Kara   udf: Standardize ...
1304
  		if (ret < 0)
bfb257a59   Jan Kara   udf: Add read-onl...
1305
  			goto out_bh;
bfb257a59   Jan Kara   udf: Add read-onl...
1306
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
1307
  	ret = 0;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1308
  out_bh:
2e0838fd0   Jan Kara   udf: Improve erro...
1309
  	/* In case loading failed, we handle cleanup in udf_fill_super */
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1310
1311
  	brelse(bh);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312
  }
1df2ae31c   Jan Kara   udf: Fortify load...
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
  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;
  	}
44ac6b829   Jan Kara   udf: Limit sparin...
1340
1341
1342
1343
1344
1345
1346
  	if (le32_to_cpu(spm->sizeSparingTable) > sb->s_blocksize) {
  		udf_err(sb, "error loading logical volume descriptor: "
  			"Too big sparing table size (%u)
  ",
  			le32_to_cpu(spm->sizeSparingTable));
  		return -EIO;
  	}
1df2ae31c   Jan Kara   udf: Fortify load...
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
  
  	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
  			if (++indirections > UDF_MAX_TD_NESTING) {
  				udf_err(sb, "too many Volume Descriptor "
  					"Pointers (max %u supported)
  ",
  					UDF_MAX_TD_NESTING);
  				brelse(bh);
a7be300de   Jan Kara   udf: Fix memory l...
1701
1702
  				ret = -EIO;
  				goto out;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1703
  			}
7b568cba4   Jan Kara   udf: Simplify han...
1704
1705
1706
1707
1708
1709
1710
1711
1712
  
  			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...
1713
  			break;
18cf4781c   Jan Kara   udf: Unify common...
1714
  		case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
28de7948a   Cyrill Gorcunov   UDF: coding style...
1715
  		case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
18cf4781c   Jan Kara   udf: Unify common...
1716
1717
  		case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
  		case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
7b78fd02f   Jan Kara   udf: Fix handling...
1718
1719
1720
1721
  		case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
  			curr = get_volume_descriptor_record(ident, bh, &data);
  			if (IS_ERR(curr)) {
  				brelse(bh);
a7be300de   Jan Kara   udf: Fix memory l...
1722
1723
  				ret = PTR_ERR(curr);
  				goto out;
7b78fd02f   Jan Kara   udf: Fix handling...
1724
1725
1726
1727
  			}
  			/* Descriptor we don't care about? */
  			if (!curr)
  				break;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1728
1729
1730
  			if (vdsn >= curr->volDescSeqNum) {
  				curr->volDescSeqNum = vdsn;
  				curr->block = block;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1731
1732
  			}
  			break;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1733
  		case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
7b568cba4   Jan Kara   udf: Simplify han...
1734
  			done = true;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1735
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1736
  		}
3bf25cb40   Jan Kara   udf: use get_bh()
1737
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1738
  	}
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1739
1740
1741
1742
  	/*
  	 * Now read interesting descriptors again and process them
  	 * in a suitable order
  	 */
7b78fd02f   Jan Kara   udf: Fix handling...
1743
  	if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) {
78ace70c4   Joe Perches   udf: Convert prin...
1744
1745
  		udf_err(sb, "Primary Volume Descriptor not found!
  ");
a7be300de   Jan Kara   udf: Fix memory l...
1746
1747
  		ret = -EAGAIN;
  		goto out;
d759bfa4e   Jan Kara   udf: Standardize ...
1748
  	}
7b78fd02f   Jan Kara   udf: Fix handling...
1749
  	ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block);
d759bfa4e   Jan Kara   udf: Standardize ...
1750
  	if (ret < 0)
a7be300de   Jan Kara   udf: Fix memory l...
1751
  		goto out;
d759bfa4e   Jan Kara   udf: Standardize ...
1752

7b78fd02f   Jan Kara   udf: Fix handling...
1753
  	if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) {
d759bfa4e   Jan Kara   udf: Standardize ...
1754
  		ret = udf_load_logicalvol(sb,
7b78fd02f   Jan Kara   udf: Fix handling...
1755
1756
  				data.vds[VDS_POS_LOGICAL_VOL_DESC].block,
  				fileset);
d759bfa4e   Jan Kara   udf: Standardize ...
1757
  		if (ret < 0)
a7be300de   Jan Kara   udf: Fix memory l...
1758
  			goto out;
c0eb31ed1   Jan Kara   udf: Cleanup volu...
1759
  	}
165923fa4   Marcin Slusarz   udf: super.c reor...
1760

7b78fd02f   Jan Kara   udf: Fix handling...
1761
  	/* Now handle prevailing Partition Descriptors */
ee4af50ca   Jan Kara   udf: Fix mounting...
1762
1763
1764
  	for (i = 0; i < data.num_part_descs; i++) {
  		ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block);
  		if (ret < 0)
a7be300de   Jan Kara   udf: Fix memory l...
1765
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1766
  	}
a7be300de   Jan Kara   udf: Fix memory l...
1767
1768
1769
1770
  	ret = 0;
  out:
  	kfree(data.part_descs_loc);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1771
  }
d759bfa4e   Jan Kara   udf: Standardize ...
1772
1773
1774
1775
1776
  /*
   * Load Volume Descriptor Sequence described by anchor in bh
   *
   * Returns <0 on error, 0 on success
   */
403460051   Jan Kara   udf: Try anchor i...
1777
1778
  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
1779
  {
403460051   Jan Kara   udf: Try anchor i...
1780
  	struct anchorVolDescPtr *anchor;
d759bfa4e   Jan Kara   udf: Standardize ...
1781
1782
  	sector_t main_s, main_e, reserve_s, reserve_e;
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1783

403460051   Jan Kara   udf: Try anchor i...
1784
1785
1786
1787
1788
1789
  	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...
1790
  	main_e += main_s - 1;
403460051   Jan Kara   udf: Try anchor i...
1791
1792
1793
1794
1795
  
  	/* 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...
1796
  	reserve_e += reserve_s - 1;
403460051   Jan Kara   udf: Try anchor i...
1797
1798
1799
  
  	/* Process the main & reserve sequences */
  	/* responsible for finding the PartitionDesc(s) */
d759bfa4e   Jan Kara   udf: Standardize ...
1800
1801
1802
  	ret = udf_process_sequence(sb, main_s, main_e, fileset);
  	if (ret != -EAGAIN)
  		return ret;
bff943af6   Jan Kara   udf: Fix memory l...
1803
  	udf_sb_free_partitions(sb);
d759bfa4e   Jan Kara   udf: Standardize ...
1804
1805
1806
1807
1808
1809
1810
1811
  	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
1812
  }
403460051   Jan Kara   udf: Try anchor i...
1813
1814
1815
  /*
   * Check whether there is an anchor block in the given block and
   * load Volume Descriptor Sequence if so.
d759bfa4e   Jan Kara   udf: Standardize ...
1816
1817
1818
   *
   * Returns <0 on error, 0 on success, -EAGAIN is special - try next anchor
   * block
403460051   Jan Kara   udf: Try anchor i...
1819
1820
1821
   */
  static int udf_check_anchor_block(struct super_block *sb, sector_t block,
  				  struct kernel_lb_addr *fileset)
1197e4dfc   Clemens Ladisch   udf: use hardware...
1822
  {
403460051   Jan Kara   udf: Try anchor i...
1823
1824
1825
  	struct buffer_head *bh;
  	uint16_t ident;
  	int ret;
1197e4dfc   Clemens Ladisch   udf: use hardware...
1826

403460051   Jan Kara   udf: Try anchor i...
1827
1828
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
  	    udf_fixed_to_variable(block) >=
23bcda112   Fabian Frederick   udf: atomically r...
1829
  	    i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits)
d759bfa4e   Jan Kara   udf: Standardize ...
1830
  		return -EAGAIN;
403460051   Jan Kara   udf: Try anchor i...
1831
1832
1833
  
  	bh = udf_read_tagged(sb, block, block, &ident);
  	if (!bh)
d759bfa4e   Jan Kara   udf: Standardize ...
1834
  		return -EAGAIN;
403460051   Jan Kara   udf: Try anchor i...
1835
1836
  	if (ident != TAG_IDENT_AVDP) {
  		brelse(bh);
d759bfa4e   Jan Kara   udf: Standardize ...
1837
  		return -EAGAIN;
1197e4dfc   Clemens Ladisch   udf: use hardware...
1838
  	}
403460051   Jan Kara   udf: Try anchor i...
1839
1840
1841
  	ret = udf_load_sequence(sb, bh, fileset);
  	brelse(bh);
  	return ret;
1197e4dfc   Clemens Ladisch   udf: use hardware...
1842
  }
d759bfa4e   Jan Kara   udf: Standardize ...
1843
1844
1845
1846
1847
1848
1849
1850
  /*
   * 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
1851
  {
403460051   Jan Kara   udf: Try anchor i...
1852
  	sector_t last[6];
38b74a53e   Jan Kara   udf: Move process...
1853
  	int i;
403460051   Jan Kara   udf: Try anchor i...
1854
1855
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	int last_count = 0;
d759bfa4e   Jan Kara   udf: Standardize ...
1856
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1857

403460051   Jan Kara   udf: Try anchor i...
1858
1859
  	/* First try user provided anchor */
  	if (sbi->s_anchor) {
d759bfa4e   Jan Kara   udf: Standardize ...
1860
1861
1862
  		ret = udf_check_anchor_block(sb, sbi->s_anchor, fileset);
  		if (ret != -EAGAIN)
  			return ret;
403460051   Jan Kara   udf: Try anchor i...
1863
1864
1865
1866
1867
1868
1869
1870
  	}
  	/*
  	 * 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 ...
1871
1872
1873
  	ret = udf_check_anchor_block(sb, sbi->s_session + 256, fileset);
  	if (ret != -EAGAIN)
  		return ret;
403460051   Jan Kara   udf: Try anchor i...
1874
1875
1876
1877
  	/*
  	 * The trouble is which block is the last one. Drives often misreport
  	 * this so we try various possibilities.
  	 */
d759bfa4e   Jan Kara   udf: Standardize ...
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
  	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
1888

403460051   Jan Kara   udf: Try anchor i...
1889
  	for (i = 0; i < last_count; i++) {
23bcda112   Fabian Frederick   udf: atomically r...
1890
  		if (last[i] >= i_size_read(sb->s_bdev->bd_inode) >>
403460051   Jan Kara   udf: Try anchor i...
1891
  				sb->s_blocksize_bits)
28f7c4d41   Marcin Slusarz   udf: improve read...
1892
  			continue;
d759bfa4e   Jan Kara   udf: Standardize ...
1893
1894
1895
1896
1897
1898
  		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...
1899
  		if (last[i] < 256)
28f7c4d41   Marcin Slusarz   udf: improve read...
1900
  			continue;
d759bfa4e   Jan Kara   udf: Standardize ...
1901
1902
1903
1904
1905
1906
  		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...
1907
  	}
28f7c4d41   Marcin Slusarz   udf: improve read...
1908

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

403460051   Jan Kara   udf: Try anchor i...
1913
1914
1915
1916
1917
  /*
   * 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 ...
1918
1919
   * Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor
   * was not found.
403460051   Jan Kara   udf: Try anchor i...
1920
1921
1922
1923
   */
  static int udf_find_anchor(struct super_block *sb,
  			   struct kernel_lb_addr *fileset)
  {
403460051   Jan Kara   udf: Try anchor i...
1924
  	struct udf_sb_info *sbi = UDF_SB(sb);
d759bfa4e   Jan Kara   udf: Standardize ...
1925
1926
  	sector_t lastblock = sbi->s_last_block;
  	int ret;
28f7c4d41   Marcin Slusarz   udf: improve read...
1927

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

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

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

403460051   Jan Kara   udf: Try anchor i...
1953
1954
  /*
   * Check Volume Structure Descriptor, find Anchor block and load Volume
d759bfa4e   Jan Kara   udf: Standardize ...
1955
1956
1957
1958
   * 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...
1959
1960
1961
1962
1963
   */
  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...
1964
  	int nsr = 0;
d759bfa4e   Jan Kara   udf: Standardize ...
1965
  	int ret;
403460051   Jan Kara   udf: Try anchor i...
1966
1967
1968
  
  	if (!sb_set_blocksize(sb, uopt->blocksize)) {
  		if (!silent)
78ace70c4   Joe Perches   udf: Convert prin...
1969
1970
  			udf_warn(sb, "Bad block size
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
1971
  		return -EINVAL;
403460051   Jan Kara   udf: Try anchor i...
1972
1973
1974
1975
  	}
  	sbi->s_last_block = uopt->lastblock;
  	if (!uopt->novrs) {
  		/* Check that it is NSR02 compliant */
ba54aef03   Steven J. Magnani   udf: refactor VRS...
1976
1977
  		nsr = udf_check_vsd(sb);
  		if (!nsr) {
403460051   Jan Kara   udf: Try anchor i...
1978
  			if (!silent)
78ace70c4   Joe Perches   udf: Convert prin...
1979
1980
  				udf_warn(sb, "No VRS found
  ");
70f16cef0   Fabian Frederick   udf: allow implic...
1981
  			return -EINVAL;
403460051   Jan Kara   udf: Try anchor i...
1982
  		}
ba54aef03   Steven J. Magnani   udf: refactor VRS...
1983
  		if (nsr == -1)
444996027   Peter A. Felvegi   udf: fix for path...
1984
1985
1986
1987
  			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...
1988
1989
1990
1991
1992
  		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...
1993
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1994

403460051   Jan Kara   udf: Try anchor i...
1995
1996
  	/* Look for anchor block and load Volume Descriptor Sequence */
  	sbi->s_anchor = uopt->anchor;
d759bfa4e   Jan Kara   udf: Standardize ...
1997
1998
1999
  	ret = udf_find_anchor(sb, fileset);
  	if (ret < 0) {
  		if (!silent && ret == -EAGAIN)
78ace70c4   Joe Perches   udf: Convert prin...
2000
2001
  			udf_warn(sb, "No anchor found
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
2002
  		return ret;
403460051   Jan Kara   udf: Try anchor i...
2003
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
2004
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2005
  }
ebbd5e99f   Steve Magnani   udf: factor out L...
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
  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
2017
2018
  static void udf_open_lvid(struct super_block *sb)
  {
6c79e987d   Marcin Slusarz   udf: remove some ...
2019
2020
  	struct udf_sb_info *sbi = UDF_SB(sb);
  	struct buffer_head *bh = sbi->s_lvid_bh;
165923fa4   Marcin Slusarz   udf: super.c reor...
2021
2022
  	struct logicalVolIntegrityDesc *lvid;
  	struct logicalVolIntegrityDescImpUse *lvidiu;
146bca72c   Jan Kara   udf: Don't write ...
2023

165923fa4   Marcin Slusarz   udf: super.c reor...
2024
2025
  	if (!bh)
  		return;
165923fa4   Marcin Slusarz   udf: super.c reor...
2026
  	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
69d75671d   Jan Kara   udf: Fortify LVID...
2027
2028
2029
  	lvidiu = udf_sb_lvidiu(sb);
  	if (!lvidiu)
  		return;
165923fa4   Marcin Slusarz   udf: super.c reor...
2030

69d75671d   Jan Kara   udf: Fortify LVID...
2031
  	mutex_lock(&sbi->s_alloc_mutex);
165923fa4   Marcin Slusarz   udf: super.c reor...
2032
2033
  	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
b72e632c6   Jan Kara   udf: Do not mark ...
2034
2035
2036
2037
  	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...
2038

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

6c79e987d   Marcin Slusarz   udf: remove some ...
2054
2055
  	if (!bh)
  		return;
69d75671d   Jan Kara   udf: Fortify LVID...
2056
2057
2058
2059
  	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
  	lvidiu = udf_sb_lvidiu(sb);
  	if (!lvidiu)
  		return;
6c79e987d   Marcin Slusarz   udf: remove some ...
2060

949f4a7c0   Jan Kara   udf: Protect all ...
2061
  	mutex_lock(&sbi->s_alloc_mutex);
165923fa4   Marcin Slusarz   udf: super.c reor...
2062
2063
  	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
165923fa4   Marcin Slusarz   udf: super.c reor...
2064
2065
2066
2067
2068
2069
  	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 ...
2070
2071
  	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT))
  		lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
165923fa4   Marcin Slusarz   udf: super.c reor...
2072

853a0c25b   Jan Kara   udf: Mark LVID bu...
2073
2074
2075
2076
2077
2078
  	/*
  	 * 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...
2079
  	udf_finalize_lvid(lvid);
165923fa4   Marcin Slusarz   udf: super.c reor...
2080
  	mark_buffer_dirty(bh);
146bca72c   Jan Kara   udf: Don't write ...
2081
  	sbi->s_lvid_dirty = 0;
949f4a7c0   Jan Kara   udf: Protect all ...
2082
  	mutex_unlock(&sbi->s_alloc_mutex);
9734c971a   Jan Kara   udf: Write LVID t...
2083
2084
  	/* Make closing of filesystem visible on the media immediately */
  	sync_dirty_buffer(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2085
  }
d664b6af6   Jan Kara   udf: Move handlin...
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
  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...
2107
  	udf_updated_lvid(sb);
d664b6af6   Jan Kara   udf: Move handlin...
2108
  	mutex_unlock(&sbi->s_alloc_mutex);
d664b6af6   Jan Kara   udf: Move handlin...
2109
2110
  
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2111
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2112
2113
  static int udf_fill_super(struct super_block *sb, void *options, int silent)
  {
d759bfa4e   Jan Kara   udf: Standardize ...
2114
  	int ret = -EINVAL;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2115
  	struct inode *inode = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2116
  	struct udf_options uopt;
5ca4e4be8   Pekka Enberg   Remove struct typ...
2117
  	struct kernel_lb_addr rootdir, fileset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2118
  	struct udf_sb_info *sbi;
9181f8bf5   Jan Kara   udf: Don't modify...
2119
  	bool lvid_open = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2120
2121
  
  	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
116e5258e   Jan Kara   udf: Provide sane...
2122
2123
2124
  	/* 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
2125
  	uopt.umask = 0;
87bc730c0   Marcin Slusarz   udf: fix default ...
2126
2127
  	uopt.fmode = UDF_INVALID_MODE;
  	uopt.dmode = UDF_INVALID_MODE;
785dffe1d   Chengguang Xu   udf: fix potentia...
2128
  	uopt.nls_map = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2129

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2134
  	sb->s_fs_info = sbi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2135

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

6da80894c   Miklos Szeredi   mount options: fi...
2138
  	if (!udf_parse_options((char *)options, &uopt, false))
fdf2657bc   Markus Elfring   udf: One function...
2139
  		goto parse_options_failure;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2140
2141
  
  	if (uopt.flags & (1 << UDF_FLAG_UTF8) &&
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2142
  	    uopt.flags & (1 << UDF_FLAG_NLS_MAP)) {
8076c363d   Joe Perches   udf: Rename udf_e...
2143
2144
  		udf_err(sb, "utf8 cannot be combined with iocharset
  ");
fdf2657bc   Markus Elfring   udf: One function...
2145
  		goto parse_options_failure;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2146
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2147
  	if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2148
2149
2150
2151
2152
2153
2154
  		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
2155
2156
2157
2158
2159
  	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 ...
2160
2161
2162
2163
  	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...
2164
2165
  	sbi->s_fmode = uopt.fmode;
  	sbi->s_dmode = uopt.dmode;
6c79e987d   Marcin Slusarz   udf: remove some ...
2166
  	sbi->s_nls_map = uopt.nls_map;
c03cad241   Jan Kara   udf: Protect defa...
2167
  	rwlock_init(&sbi->s_cred_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2168

cb00ea352   Cyrill Gorcunov   UDF: coding style...
2169
  	if (uopt.session == 0xFFFFFFFF)
6c79e987d   Marcin Slusarz   udf: remove some ...
2170
  		sbi->s_session = udf_get_last_session(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2171
  	else
6c79e987d   Marcin Slusarz   udf: remove some ...
2172
  		sbi->s_session = uopt.session;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2173

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

403460051   Jan Kara   udf: Try anchor i...
2177
2178
2179
  	/* 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...
2180

403460051   Jan Kara   udf: Try anchor i...
2181
2182
  	sb->s_magic = UDF_SUPER_MAGIC;
  	sb->s_time_gran = 1000;
1197e4dfc   Clemens Ladisch   udf: use hardware...
2183
  	if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) {
403460051   Jan Kara   udf: Try anchor i...
2184
  		ret = udf_load_vrs(sb, &uopt, silent, &fileset);
1197e4dfc   Clemens Ladisch   udf: use hardware...
2185
  	} else {
e1defc4ff   Martin K. Petersen   block: Do away wi...
2186
  		uopt.blocksize = bdev_logical_block_size(sb->s_bdev);
70f16cef0   Fabian Frederick   udf: allow implic...
2187
  		while (uopt.blocksize <= 4096) {
403460051   Jan Kara   udf: Try anchor i...
2188
  			ret = udf_load_vrs(sb, &uopt, silent, &fileset);
70f16cef0   Fabian Frederick   udf: allow implic...
2189
2190
  			if (ret < 0) {
  				if (!silent && ret != -EACCES) {
fcbf7637e   Steve Magnani   udf: Fix signed/u...
2191
2192
  					pr_notice("Scanning with blocksize %u failed
  ",
70f16cef0   Fabian Frederick   udf: allow implic...
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
  						  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...
2207
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2208
  	}
d759bfa4e   Jan Kara   udf: Standardize ...
2209
2210
2211
2212
2213
2214
  	if (ret < 0) {
  		if (ret == -EAGAIN) {
  			udf_warn(sb, "No partition found (1)
  ");
  			ret = -EINVAL;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2215
2216
  		goto error_out;
  	}
fcbf7637e   Steve Magnani   udf: Fix signed/u...
2217
2218
  	udf_debug("Lastblock=%u
  ", sbi->s_last_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2219

6c79e987d   Marcin Slusarz   udf: remove some ...
2220
  	if (sbi->s_lvid_bh) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2221
  		struct logicalVolIntegrityDescImpUse *lvidiu =
69d75671d   Jan Kara   udf: Fortify LVID...
2222
2223
2224
  							udf_sb_lvidiu(sb);
  		uint16_t minUDFReadRev;
  		uint16_t minUDFWriteRev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2225

69d75671d   Jan Kara   udf: Fortify LVID...
2226
2227
2228
2229
2230
2231
  		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...
2232
  		if (minUDFReadRev > UDF_MAX_READ_VERSION) {
78ace70c4   Joe Perches   udf: Convert prin...
2233
2234
  			udf_err(sb, "minUDFReadRev=%x (max is %x)
  ",
69d75671d   Jan Kara   udf: Fortify LVID...
2235
  				minUDFReadRev,
78ace70c4   Joe Perches   udf: Convert prin...
2236
  				UDF_MAX_READ_VERSION);
d759bfa4e   Jan Kara   udf: Standardize ...
2237
  			ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2238
  			goto error_out;
a9ad01bc7   Jan Kara   udf: Prevent writ...
2239
2240
2241
2242
2243
2244
  		} 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...
2245
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2246

6c79e987d   Marcin Slusarz   udf: remove some ...
2247
  		sbi->s_udfrev = minUDFWriteRev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2248
2249
2250
2251
2252
2253
  
  		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 ...
2254
  	if (!sbi->s_partitions) {
78ace70c4   Joe Perches   udf: Convert prin...
2255
2256
  		udf_warn(sb, "No partition found (2)
  ");
d759bfa4e   Jan Kara   udf: Standardize ...
2257
  		ret = -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2258
2259
  		goto error_out;
  	}
4b11111ab   Marcin Slusarz   udf: fix coding s...
2260
  	if (sbi->s_partmaps[sbi->s_partition].s_partition_flags &
a9ad01bc7   Jan Kara   udf: Prevent writ...
2261
2262
2263
2264
2265
2266
  			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 ...
2267
  	}
39b3f6d6e   Eric Sandeen   [PATCH] mount udf...
2268

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

d759bfa4e   Jan Kara   udf: Standardize ...
2324
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2325
  }
8076c363d   Joe Perches   udf: Rename udf_e...
2326
2327
  void _udf_err(struct super_block *sb, const char *function,
  	      const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2328
  {
c2bff36c2   Joe Perches   udf: Neaten loggi...
2329
  	struct va_format vaf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2330
  	va_list args;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2331
  	va_start(args, fmt);
c2bff36c2   Joe Perches   udf: Neaten loggi...
2332
2333
2334
2335
2336
  
  	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
2337
  	va_end(args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2338
  }
a40ecd7b3   Joe Perches   udf: Rename udf_w...
2339
2340
  void _udf_warn(struct super_block *sb, const char *function,
  	       const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2341
  {
c2bff36c2   Joe Perches   udf: Neaten loggi...
2342
  	struct va_format vaf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2343
  	va_list args;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2344
  	va_start(args, fmt);
c2bff36c2   Joe Perches   udf: Neaten loggi...
2345
2346
2347
2348
2349
  
  	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
2350
  	va_end(args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2351
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2352
  static void udf_put_super(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2353
  {
6c79e987d   Marcin Slusarz   udf: remove some ...
2354
  	struct udf_sb_info *sbi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2355

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

0d454e4a4   Markus Elfring   udf: Deletion of ...
2358
  	iput(sbi->s_vat_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2359
  	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
6c79e987d   Marcin Slusarz   udf: remove some ...
2360
  		unload_nls(sbi->s_nls_map);
bc98a42c1   David Howells   VFS: Convert sb->...
2361
  	if (!sb_rdonly(sb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2362
  		udf_close_lvid(sb);
6c79e987d   Marcin Slusarz   udf: remove some ...
2363
  	brelse(sbi->s_lvid_bh);
bff943af6   Jan Kara   udf: Fix memory l...
2364
  	udf_sb_free_partitions(sb);
bbe48dd81   Fabian Frederick   udf: destroy sbi ...
2365
  	mutex_destroy(&sbi->s_alloc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2366
2367
2368
  	kfree(sb->s_fs_info);
  	sb->s_fs_info = NULL;
  }
146bca72c   Jan Kara   udf: Don't write ...
2369
2370
2371
2372
2373
2374
  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...
2375
  		struct buffer_head *bh = sbi->s_lvid_bh;
52b9666ef   Jan Kara   udf: Drop pointle...
2376
  		struct logicalVolIntegrityDesc *lvid;
e8b427473   Steve Magnani   udf: finalize int...
2377

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

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

69d75671d   Jan Kara   udf: Fortify LVID...
2399
  	lvidiu = udf_sb_lvidiu(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2400
2401
  	buf->f_type = UDF_SUPER_MAGIC;
  	buf->f_bsize = sb->s_blocksize;
6c79e987d   Marcin Slusarz   udf: remove some ...
2402
  	buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2403
2404
  	buf->f_bfree = udf_count_free(sb);
  	buf->f_bavail = buf->f_bfree;
356557be8   Jan Kara   udf: Clarify mean...
2405
2406
2407
2408
  	/*
  	 * Let's pretend each free block is also a free 'inode' since UDF does
  	 * not have separate preallocated table of inodes.
  	 */
6c79e987d   Marcin Slusarz   udf: remove some ...
2409
2410
2411
  	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
2412
  	buf->f_ffree = buf->f_bfree;
9fba70569   Andrew Gabbasov   udf: Adjust UDF_N...
2413
  	buf->f_namelen = UDF_NAME_LEN;
6d1349c76   Al Viro   [PATCH] reduce bo...
2414
  	buf->f_fsid = u64_to_fsid(id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2415
2416
2417
  
  	return 0;
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
2418
2419
  static unsigned int udf_count_free_bitmap(struct super_block *sb,
  					  struct udf_bitmap *bitmap)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2420
2421
2422
2423
  {
  	struct buffer_head *bh = NULL;
  	unsigned int accum = 0;
  	int index;
b490bdd63   Steve Magnani   udf: Fix 64-bit s...
2424
  	udf_pblk_t block = 0, newblock;
5ca4e4be8   Pekka Enberg   Remove struct typ...
2425
  	struct kernel_lb_addr loc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2426
  	uint32_t bytes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2427
2428
2429
  	uint8_t *ptr;
  	uint16_t ident;
  	struct spaceBitmapDesc *bm;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2430
  	loc.logicalBlockNum = bitmap->s_extPosition;
6c79e987d   Marcin Slusarz   udf: remove some ...
2431
  	loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
97e961fdb   Pekka Enberg   Fix the udf code ...
2432
  	bh = udf_read_ptagged(sb, &loc, 0, &ident);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2433

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

cb00ea352   Cyrill Gorcunov   UDF: coding style...
2450
  	while (bytes > 0) {
01b954a36   Marcin Slusarz   udf: convert udf_...
2451
2452
2453
2454
  		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...
2455
  		if (bytes) {
3bf25cb40   Jan Kara   udf: use get_bh()
2456
  			brelse(bh);
97e961fdb   Pekka Enberg   Fix the udf code ...
2457
  			newblock = udf_get_lb_pblock(sb, &loc, ++block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2458
  			bh = udf_tread(sb, newblock);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2459
  			if (!bh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2460
2461
2462
2463
2464
  				udf_debug("read failed
  ");
  				goto out;
  			}
  			index = 0;
28de7948a   Cyrill Gorcunov   UDF: coding style...
2465
  			ptr = (uint8_t *)bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2466
2467
  		}
  	}
3bf25cb40   Jan Kara   udf: use get_bh()
2468
  	brelse(bh);
28de7948a   Cyrill Gorcunov   UDF: coding style...
2469
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2470
2471
  	return accum;
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
2472
2473
  static unsigned int udf_count_free_table(struct super_block *sb,
  					 struct inode *table)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
2475
  {
  	unsigned int accum = 0;
ff116fc8d   Jan Kara   UDF: introduce st...
2476
  	uint32_t elen;
5ca4e4be8   Pekka Enberg   Remove struct typ...
2477
  	struct kernel_lb_addr eloc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2478
  	int8_t etype;
ff116fc8d   Jan Kara   UDF: introduce st...
2479
  	struct extent_position epos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2480

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

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

3bf25cb40   Jan Kara   udf: use get_bh()
2489
  	brelse(epos.bh);
d1668fe39   Jan Kara   udf: Remove BKL f...
2490
  	mutex_unlock(&UDF_SB(sb)->s_alloc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2491
2492
2493
  
  	return accum;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2494
2495
  
  static unsigned int udf_count_free(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2496
2497
  {
  	unsigned int accum = 0;
a4a8b99ec   Jan Kara   udf: Fix free spa...
2498
  	struct udf_sb_info *sbi = UDF_SB(sb);
6c79e987d   Marcin Slusarz   udf: remove some ...
2499
  	struct udf_part_map *map;
a4a8b99ec   Jan Kara   udf: Fix free spa...
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
  	unsigned int part = sbi->s_partition;
  	int ptype = sbi->s_partmaps[part].s_partition_type;
  
  	if (ptype == UDF_METADATA_MAP25) {
  		part = sbi->s_partmaps[part].s_type_specific.s_metadata.
  							s_phys_partition_ref;
  	} else if (ptype == UDF_VIRTUAL_MAP15 || ptype == UDF_VIRTUAL_MAP20) {
  		/*
  		 * Filesystems with VAT are append-only and we cannot write to
   		 * them. Let's just report 0 here.
  		 */
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2513

6c79e987d   Marcin Slusarz   udf: remove some ...
2514
  	if (sbi->s_lvid_bh) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2515
2516
2517
  		struct logicalVolIntegrityDesc *lvid =
  			(struct logicalVolIntegrityDesc *)
  			sbi->s_lvid_bh->b_data;
a4a8b99ec   Jan Kara   udf: Fix free spa...
2518
  		if (le32_to_cpu(lvid->numOfPartitions) > part) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2519
  			accum = le32_to_cpu(
a4a8b99ec   Jan Kara   udf: Fix free spa...
2520
  					lvid->freeSpaceTable[part]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2521
2522
2523
2524
2525
2526
2527
  			if (accum == 0xFFFFFFFF)
  				accum = 0;
  		}
  	}
  
  	if (accum)
  		return accum;
a4a8b99ec   Jan Kara   udf: Fix free spa...
2528
  	map = &sbi->s_partmaps[part];
6c79e987d   Marcin Slusarz   udf: remove some ...
2529
  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
28de7948a   Cyrill Gorcunov   UDF: coding style...
2530
  		accum += udf_count_free_bitmap(sb,
6c79e987d   Marcin Slusarz   udf: remove some ...
2531
  					       map->s_uspace.s_bitmap);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2532
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2533
2534
  	if (accum)
  		return accum;
6c79e987d   Marcin Slusarz   udf: remove some ...
2535
  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
28de7948a   Cyrill Gorcunov   UDF: coding style...
2536
  		accum += udf_count_free_table(sb,
6c79e987d   Marcin Slusarz   udf: remove some ...
2537
  					      map->s_uspace.s_table);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2538
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2539
2540
  	return accum;
  }
54bb60d53   Fabian Frederick   udf: merge module...
2541
2542
2543
2544
2545
2546
  
  MODULE_AUTHOR("Ben Fennema");
  MODULE_DESCRIPTION("Universal Disk Format Filesystem");
  MODULE_LICENSE("GPL");
  module_init(init_udf_fs)
  module_exit(exit_udf_fs)