File Index
Files and directories
Sign in
FILE

super.c

File preview with syntax highlighting.

linux-6.19.14/fs/hpfs/super.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  linux/fs/hpfs/super.c
  4 *
  5 *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  6 *
  7 *  mounting, unmounting, error handling
  8 */
  9
 10#include "hpfs_fn.h"
 11#include <linux/module.h>
 12#include <linux/fs_struct.h>
 13#include <linux/fs_context.h>
 14#include <linux/fs_parser.h>
 15#include <linux/init.h>
 16#include <linux/statfs.h>
 17#include <linux/magic.h>
 18#include <linux/sched.h>
 19#include <linux/bitmap.h>
 20#include <linux/slab.h>
 21#include <linux/seq_file.h>
 22
 23/* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
 24
 25static void mark_dirty(struct super_block *s, int remount)
 26{
 27	if (hpfs_sb(s)->sb_chkdsk && (remount || !sb_rdonly(s))) {
 28		struct buffer_head *bh;
 29		struct hpfs_spare_block *sb;
 30		if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
 31			sb->dirty = 1;
 32			sb->old_wrote = 0;
 33			mark_buffer_dirty(bh);
 34			sync_dirty_buffer(bh);
 35			brelse(bh);
 36		}
 37	}
 38}
 39
 40/* Mark the filesystem clean (mark it dirty for chkdsk if chkdsk==2 or if there
 41   were errors) */
 42
 43static void unmark_dirty(struct super_block *s)
 44{
 45	struct buffer_head *bh;
 46	struct hpfs_spare_block *sb;
 47	if (sb_rdonly(s)) return;
 48	sync_blockdev(s->s_bdev);
 49	if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
 50		sb->dirty = hpfs_sb(s)->sb_chkdsk > 1 - hpfs_sb(s)->sb_was_error;
 51		sb->old_wrote = hpfs_sb(s)->sb_chkdsk >= 2 && !hpfs_sb(s)->sb_was_error;
 52		mark_buffer_dirty(bh);
 53		sync_dirty_buffer(bh);
 54		brelse(bh);
 55	}
 56}
 57
 58/* Filesystem error... */
 59void hpfs_error(struct super_block *s, const char *fmt, ...)
 60{
 61	struct va_format vaf;
 62	va_list args;
 63
 64	va_start(args, fmt);
 65
 66	vaf.fmt = fmt;
 67	vaf.va = &args;
 68
 69	pr_err("filesystem error: %pV", &vaf);
 70
 71	va_end(args);
 72
 73	if (!hpfs_sb(s)->sb_was_error) {
 74		if (hpfs_sb(s)->sb_err == 2) {
 75			pr_cont("; crashing the system because you wanted it\n");
 76			mark_dirty(s, 0);
 77			panic("HPFS panic");
 78		} else if (hpfs_sb(s)->sb_err == 1) {
 79			if (sb_rdonly(s))
 80				pr_cont("; already mounted read-only\n");
 81			else {
 82				pr_cont("; remounting read-only\n");
 83				mark_dirty(s, 0);
 84				s->s_flags |= SB_RDONLY;
 85			}
 86		} else if (sb_rdonly(s))
 87				pr_cont("; going on - but anything won't be destroyed because it's read-only\n");
 88		else
 89			pr_cont("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
 90	} else
 91		pr_cont("\n");
 92	hpfs_sb(s)->sb_was_error = 1;
 93}
 94
 95/*
 96 * A little trick to detect cycles in many hpfs structures and don't let the
 97 * kernel crash on corrupted filesystem. When first called, set c2 to 0.
 98 *
 99 * BTW. chkdsk doesn't detect cycles correctly. When I had 2 lost directories
100 * nested each in other, chkdsk locked up happilly.
101 */
102
103int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2,
104		char *msg)
105{
106	if (*c2 && *c1 == key) {
107		hpfs_error(s, "cycle detected on key %08x in %s", key, msg);
108		return 1;
109	}
110	(*c2)++;
111	if (!((*c2 - 1) & *c2)) *c1 = key;
112	return 0;
113}
114
115static void free_sbi(struct hpfs_sb_info *sbi)
116{
117	kfree(sbi->sb_cp_table);
118	kfree(sbi->sb_bmp_dir);
119	kfree(sbi);
120}
121
122static void lazy_free_sbi(struct rcu_head *rcu)
123{
124	free_sbi(container_of(rcu, struct hpfs_sb_info, rcu));
125}
126
127static void hpfs_put_super(struct super_block *s)
128{
129	hpfs_lock(s);
130	unmark_dirty(s);
131	hpfs_unlock(s);
132	call_rcu(&hpfs_sb(s)->rcu, lazy_free_sbi);
133}
134
135static unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
136{
137	struct quad_buffer_head qbh;
138	unsigned long *bits;
139	unsigned count;
140
141	bits = hpfs_map_4sectors(s, secno, &qbh, 0);
142	if (!bits)
143		return (unsigned)-1;
144	count = bitmap_weight(bits, 2048 * BITS_PER_BYTE);
145	hpfs_brelse4(&qbh);
146	return count;
147}
148
149static unsigned count_bitmaps(struct super_block *s)
150{
151	unsigned n, count, n_bands;
152	n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14;
153	count = 0;
154	for (n = 0; n < COUNT_RD_AHEAD; n++) {
155		hpfs_prefetch_bitmap(s, n);
156	}
157	for (n = 0; n < n_bands; n++) {
158		unsigned c;
159		hpfs_prefetch_bitmap(s, n + COUNT_RD_AHEAD);
160		c = hpfs_count_one_bitmap(s, le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[n]));
161		if (c != (unsigned)-1)
162			count += c;
163	}
164	return count;
165}
166
167unsigned hpfs_get_free_dnodes(struct super_block *s)
168{
169	struct hpfs_sb_info *sbi = hpfs_sb(s);
170	if (sbi->sb_n_free_dnodes == (unsigned)-1) {
171		unsigned c = hpfs_count_one_bitmap(s, sbi->sb_dmap);
172		if (c == (unsigned)-1)
173			return 0;
174		sbi->sb_n_free_dnodes = c;
175	}
176	return sbi->sb_n_free_dnodes;
177}
178
179static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf)
180{
181	struct super_block *s = dentry->d_sb;
182	struct hpfs_sb_info *sbi = hpfs_sb(s);
183	u64 id = huge_encode_dev(s->s_bdev->bd_dev);
184
185	hpfs_lock(s);
186
187	if (sbi->sb_n_free == (unsigned)-1)
188		sbi->sb_n_free = count_bitmaps(s);
189
190	buf->f_type = s->s_magic;
191	buf->f_bsize = 512;
192	buf->f_blocks = sbi->sb_fs_size;
193	buf->f_bfree = sbi->sb_n_free;
194	buf->f_bavail = sbi->sb_n_free;
195	buf->f_files = sbi->sb_dirband_size / 4;
196	buf->f_ffree = hpfs_get_free_dnodes(s);
197	buf->f_fsid = u64_to_fsid(id);
198	buf->f_namelen = 254;
199
200	hpfs_unlock(s);
201
202	return 0;
203}
204
205
206long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg)
207{
208	switch (cmd) {
209		case FITRIM: {
210			struct fstrim_range range;
211			secno n_trimmed;
212			int r;
213			if (!capable(CAP_SYS_ADMIN))
214				return -EPERM;
215			if (copy_from_user(&range, (struct fstrim_range __user *)arg, sizeof(range)))
216				return -EFAULT;
217			r = hpfs_trim_fs(file_inode(file)->i_sb, range.start >> 9, (range.start + range.len) >> 9, (range.minlen + 511) >> 9, &n_trimmed);
218			if (r)
219				return r;
220			range.len = (u64)n_trimmed << 9;
221			if (copy_to_user((struct fstrim_range __user *)arg, &range, sizeof(range)))
222				return -EFAULT;
223			return 0;
224		}
225		default: {
226			return -ENOIOCTLCMD;
227		}
228	}
229}
230
231
232static struct kmem_cache * hpfs_inode_cachep;
233
234static struct inode *hpfs_alloc_inode(struct super_block *sb)
235{
236	struct hpfs_inode_info *ei;
237	ei = alloc_inode_sb(sb, hpfs_inode_cachep, GFP_NOFS);
238	if (!ei)
239		return NULL;
240	return &ei->vfs_inode;
241}
242
243static void hpfs_free_inode(struct inode *inode)
244{
245	kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode));
246}
247
248static void init_once(void *foo)
249{
250	struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo;
251
252	inode_init_once(&ei->vfs_inode);
253}
254
255static int init_inodecache(void)
256{
257	hpfs_inode_cachep = kmem_cache_create("hpfs_inode_cache",
258					     sizeof(struct hpfs_inode_info),
259					     0, (SLAB_RECLAIM_ACCOUNT|
260						SLAB_ACCOUNT),
261					     init_once);
262	if (hpfs_inode_cachep == NULL)
263		return -ENOMEM;
264	return 0;
265}
266
267static void destroy_inodecache(void)
268{
269	/*
270	 * Make sure all delayed rcu free inodes are flushed before we
271	 * destroy cache.
272	 */
273	rcu_barrier();
274	kmem_cache_destroy(hpfs_inode_cachep);
275}
276
277enum {
278	Opt_help, Opt_uid, Opt_gid, Opt_umask, Opt_case,
279	Opt_check, Opt_err, Opt_eas, Opt_chkdsk, Opt_timeshift,
280};
281
282static const struct constant_table hpfs_param_case[] = {
283	{"asis",	0},
284	{"lower",	1},
285	{}
286};
287
288static const struct constant_table hpfs_param_check[] = {
289	{"none",	0},
290	{"normal",	1},
291	{"strict",	2},
292	{}
293};
294
295static const struct constant_table hpfs_param_err[] = {
296	{"continue",	0},
297	{"remount-ro",	1},
298	{"panic",	2},
299	{}
300};
301
302static const struct constant_table hpfs_param_eas[] = {
303	{"no",		0},
304	{"ro",		1},
305	{"rw",		2},
306	{}
307};
308
309static const struct constant_table hpfs_param_chkdsk[] = {
310	{"no",		0},
311	{"errors",	1},
312	{"always",	2},
313	{}
314};
315
316static const struct fs_parameter_spec hpfs_param_spec[] = {
317	fsparam_flag	("help",	Opt_help),
318	fsparam_uid	("uid",		Opt_uid),
319	fsparam_gid	("gid",		Opt_gid),
320	fsparam_u32oct	("umask",	Opt_umask),
321	fsparam_enum	("case",	Opt_case,	hpfs_param_case),
322	fsparam_enum	("check",	Opt_check,	hpfs_param_check),
323	fsparam_enum	("errors",	Opt_err,	hpfs_param_err),
324	fsparam_enum	("eas",		Opt_eas,	hpfs_param_eas),
325	fsparam_enum	("chkdsk",	Opt_chkdsk,	hpfs_param_chkdsk),
326	fsparam_s32	("timeshift",	Opt_timeshift),
327	{}
328};
329
330struct hpfs_fc_context {
331	kuid_t uid;
332	kgid_t gid;
333	umode_t umask;
334	int lowercase;
335	int eas;
336	int chk;
337	int errs;
338	int chkdsk;
339	int timeshift;
340};
341
342static inline void hpfs_help(void)
343{
344	pr_info("\n\
345HPFS filesystem options:\n\
346      help              do not mount and display this text\n\
347      uid=xxx           set uid of files that don't have uid specified in eas\n\
348      gid=xxx           set gid of files that don't have gid specified in eas\n\
349      umask=xxx         set mode of files that don't have mode specified in eas\n\
350      case=lower        lowercase all files\n\
351      case=asis         do not lowercase files (default)\n\
352      check=none        no fs checks - kernel may crash on corrupted filesystem\n\
353      check=normal      do some checks - it should not crash (default)\n\
354      check=strict      do extra time-consuming checks, used for debugging\n\
355      errors=continue   continue on errors\n\
356      errors=remount-ro remount read-only if errors found (default)\n\
357      errors=panic      panic on errors\n\
358      chkdsk=no         do not mark fs for chkdsking even if there were errors\n\
359      chkdsk=errors     mark fs dirty if errors found (default)\n\
360      chkdsk=always     always mark fs dirty - used for debugging\n\
361      eas=no            ignore extended attributes\n\
362      eas=ro            read but do not write extended attributes\n\
363      eas=rw            r/w eas => enables chmod, chown, mknod, ln -s (default)\n\
364      timeshift=nnn	add nnn seconds to file times\n\
365\n");
366}
367
368static int hpfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
369{
370	struct hpfs_fc_context *ctx = fc->fs_private;
371	struct fs_parse_result result;
372	int opt;
373
374	opt = fs_parse(fc, hpfs_param_spec, param, &result);
375	if (opt < 0)
376		return opt;
377
378	switch (opt) {
379	case Opt_help:
380		hpfs_help();
381		return -EINVAL;
382	case Opt_uid:
383		ctx->uid = result.uid;
384		break;
385	case Opt_gid:
386		ctx->gid = result.gid;
387		break;
388	case Opt_umask:
389		ctx->umask = result.uint_32;
390		break;
391	case Opt_case:
392		ctx->lowercase = result.uint_32;
393		break;
394	case Opt_check:
395		ctx->chk = result.uint_32;
396		break;
397	case Opt_err:
398		ctx->errs = result.uint_32;
399		break;
400	case Opt_eas:
401		ctx->eas = result.uint_32;
402		break;
403	case Opt_chkdsk:
404		ctx->chkdsk = result.uint_32;
405		break;
406	case Opt_timeshift:
407		{
408			char *rhs = param->string;
409			int timeshift;
410
411			if (kstrtoint(rhs, 0, &timeshift))
412				return -EINVAL;
413			ctx->timeshift = timeshift;
414			break;
415		}
416	default:
417		return -EINVAL;
418	}
419
420	return 0;
421}
422
423static int hpfs_reconfigure(struct fs_context *fc)
424{
425	struct hpfs_fc_context *ctx = fc->fs_private;
426	struct super_block *s = fc->root->d_sb;
427	struct hpfs_sb_info *sbi = hpfs_sb(s);
428
429	sync_filesystem(s);
430
431	fc->sb_flags |= SB_NOATIME;
432
433	hpfs_lock(s);
434
435	if (ctx->timeshift != sbi->sb_timeshift) {
436		pr_err("timeshift can't be changed using remount.\n");
437		goto out_err;
438	}
439
440	unmark_dirty(s);
441
442	sbi->sb_uid = ctx->uid; sbi->sb_gid = ctx->gid;
443	sbi->sb_mode = 0777 & ~ctx->umask;
444	sbi->sb_lowercase = ctx->lowercase;
445	sbi->sb_eas = ctx->eas; sbi->sb_chk = ctx->chk;
446	sbi->sb_chkdsk = ctx->chkdsk;
447	sbi->sb_err = ctx->errs; sbi->sb_timeshift = ctx->timeshift;
448
449	if (!(fc->sb_flags & SB_RDONLY)) mark_dirty(s, 1);
450
451	hpfs_unlock(s);
452	return 0;
453
454out_err:
455	hpfs_unlock(s);
456	return -EINVAL;
457}
458
459static int hpfs_show_options(struct seq_file *seq, struct dentry *root)
460{
461	struct hpfs_sb_info *sbi = hpfs_sb(root->d_sb);
462
463	seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, sbi->sb_uid));
464	seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, sbi->sb_gid));
465	seq_printf(seq, ",umask=%03o", (~sbi->sb_mode & 0777));
466	if (sbi->sb_lowercase)
467		seq_printf(seq, ",case=lower");
468	if (!sbi->sb_chk)
469		seq_printf(seq, ",check=none");
470	if (sbi->sb_chk == 2)
471		seq_printf(seq, ",check=strict");
472	if (!sbi->sb_err)
473		seq_printf(seq, ",errors=continue");
474	if (sbi->sb_err == 2)
475		seq_printf(seq, ",errors=panic");
476	if (!sbi->sb_chkdsk)
477		seq_printf(seq, ",chkdsk=no");
478	if (sbi->sb_chkdsk == 2)
479		seq_printf(seq, ",chkdsk=always");
480	if (!sbi->sb_eas)
481		seq_printf(seq, ",eas=no");
482	if (sbi->sb_eas == 1)
483		seq_printf(seq, ",eas=ro");
484	if (sbi->sb_timeshift)
485		seq_printf(seq, ",timeshift=%d", sbi->sb_timeshift);
486	return 0;
487}
488
489/* Super operations */
490
491static const struct super_operations hpfs_sops =
492{
493	.alloc_inode	= hpfs_alloc_inode,
494	.free_inode	= hpfs_free_inode,
495	.evict_inode	= hpfs_evict_inode,
496	.put_super	= hpfs_put_super,
497	.statfs		= hpfs_statfs,
498	.show_options	= hpfs_show_options,
499};
500
501static int hpfs_fill_super(struct super_block *s, struct fs_context *fc)
502{
503	struct hpfs_fc_context *ctx = fc->fs_private;
504	struct buffer_head *bh0, *bh1, *bh2;
505	struct hpfs_boot_block *bootblock;
506	struct hpfs_super_block *superblock;
507	struct hpfs_spare_block *spareblock;
508	struct hpfs_sb_info *sbi;
509	struct inode *root;
510	int silent = fc->sb_flags & SB_SILENT;
511
512	dnode_secno root_dno;
513	struct hpfs_dirent *de = NULL;
514	struct quad_buffer_head qbh;
515
516	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
517	if (!sbi) {
518		return -ENOMEM;
519	}
520	s->s_fs_info = sbi;
521
522	mutex_init(&sbi->hpfs_mutex);
523	hpfs_lock(s);
524
525	/*sbi->sb_mounting = 1;*/
526	sb_set_blocksize(s, 512);
527	sbi->sb_fs_size = -1;
528	if (!(bootblock = hpfs_map_sector(s, 0, &bh0, 0))) goto bail1;
529	if (!(superblock = hpfs_map_sector(s, 16, &bh1, 1))) goto bail2;
530	if (!(spareblock = hpfs_map_sector(s, 17, &bh2, 0))) goto bail3;
531
532	/* Check magics */
533	if (/*le16_to_cpu(bootblock->magic) != BB_MAGIC
534	    ||*/ le32_to_cpu(superblock->magic) != SB_MAGIC
535	    || le32_to_cpu(spareblock->magic) != SP_MAGIC) {
536		if (!silent)
537			pr_err("Bad magic ... probably not HPFS\n");
538		goto bail4;
539	}
540
541	/* Check version */
542	if (!sb_rdonly(s) && superblock->funcversion != 2 && superblock->funcversion != 3) {
543		pr_err("Bad version %d,%d. Mount readonly to go around\n",
544			(int)superblock->version, (int)superblock->funcversion);
545		pr_err("please try recent version of HPFS driver at http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi and if it still can't understand this format, contact author - mikulas@artax.karlin.mff.cuni.cz\n");
546		goto bail4;
547	}
548
549	s->s_flags |= SB_NOATIME;
550
551	/* Fill superblock stuff */
552	s->s_magic = HPFS_SUPER_MAGIC;
553	s->s_op = &hpfs_sops;
554	set_default_d_op(s, &hpfs_dentry_operations);
555	s->s_time_min =  local_to_gmt(s, 0);
556	s->s_time_max =  local_to_gmt(s, U32_MAX);
557
558	sbi->sb_root = le32_to_cpu(superblock->root);
559	sbi->sb_fs_size = le32_to_cpu(superblock->n_sectors);
560	sbi->sb_bitmaps = le32_to_cpu(superblock->bitmaps);
561	sbi->sb_dirband_start = le32_to_cpu(superblock->dir_band_start);
562	sbi->sb_dirband_size = le32_to_cpu(superblock->n_dir_band);
563	sbi->sb_dmap = le32_to_cpu(superblock->dir_band_bitmap);
564	sbi->sb_uid = ctx->uid;
565	sbi->sb_gid = ctx->gid;
566	sbi->sb_mode = 0777 & ~ctx->umask;
567	sbi->sb_n_free = -1;
568	sbi->sb_n_free_dnodes = -1;
569	sbi->sb_lowercase = ctx->lowercase;
570	sbi->sb_eas = ctx->eas;
571	sbi->sb_chk = ctx->chk;
572	sbi->sb_chkdsk = ctx->chkdsk;
573	sbi->sb_err = ctx->errs;
574	sbi->sb_timeshift = ctx->timeshift;
575	sbi->sb_was_error = 0;
576	sbi->sb_cp_table = NULL;
577	sbi->sb_c_bitmap = -1;
578	sbi->sb_max_fwd_alloc = 0xffffff;
579
580	if (sbi->sb_fs_size >= 0x80000000) {
581		hpfs_error(s, "invalid size in superblock: %08x",
582			(unsigned)sbi->sb_fs_size);
583		goto bail4;
584	}
585
586	if (spareblock->n_spares_used)
587		hpfs_load_hotfix_map(s, spareblock);
588
589	/* Load bitmap directory */
590	if (!(sbi->sb_bmp_dir = hpfs_load_bitmap_directory(s, le32_to_cpu(superblock->bitmaps))))
591		goto bail4;
592	
593	/* Check for general fs errors*/
594	if (spareblock->dirty && !spareblock->old_wrote) {
595		if (sbi->sb_err == 2) {
596			pr_err("Improperly stopped, not mounted\n");
597			goto bail4;
598		}
599		hpfs_error(s, "improperly stopped");
600	}
601
602	if (!sb_rdonly(s)) {
603		spareblock->dirty = 1;
604		spareblock->old_wrote = 0;
605		mark_buffer_dirty(bh2);
606	}
607
608	if (le32_to_cpu(spareblock->n_dnode_spares) != le32_to_cpu(spareblock->n_dnode_spares_free)) {
609		if (sbi->sb_err >= 2) {
610			pr_err("Spare dnodes used, try chkdsk\n");
611			mark_dirty(s, 0);
612			goto bail4;
613		}
614		hpfs_error(s, "warning: spare dnodes used, try chkdsk");
615		if (sbi->sb_err == 0)
616			pr_err("Proceeding, but your filesystem could be corrupted if you delete files or directories\n");
617	}
618	if (sbi->sb_chk) {
619		unsigned a;
620		if (le32_to_cpu(superblock->dir_band_end) - le32_to_cpu(superblock->dir_band_start) + 1 != le32_to_cpu(superblock->n_dir_band) ||
621		    le32_to_cpu(superblock->dir_band_end) < le32_to_cpu(superblock->dir_band_start) || le32_to_cpu(superblock->n_dir_band) > 0x4000) {
622			hpfs_error(s, "dir band size mismatch: dir_band_start==%08x, dir_band_end==%08x, n_dir_band==%08x",
623				le32_to_cpu(superblock->dir_band_start), le32_to_cpu(superblock->dir_band_end), le32_to_cpu(superblock->n_dir_band));
624			goto bail4;
625		}
626		a = sbi->sb_dirband_size;
627		sbi->sb_dirband_size = 0;
628		if (hpfs_chk_sectors(s, le32_to_cpu(superblock->dir_band_start), le32_to_cpu(superblock->n_dir_band), "dir_band") ||
629		    hpfs_chk_sectors(s, le32_to_cpu(superblock->dir_band_bitmap), 4, "dir_band_bitmap") ||
630		    hpfs_chk_sectors(s, le32_to_cpu(superblock->bitmaps), 4, "bitmaps")) {
631			mark_dirty(s, 0);
632			goto bail4;
633		}
634		sbi->sb_dirband_size = a;
635	} else
636		pr_err("You really don't want any checks? You are crazy...\n");
637
638	/* Load code page table */
639	if (le32_to_cpu(spareblock->n_code_pages))
640		if (!(sbi->sb_cp_table = hpfs_load_code_page(s, le32_to_cpu(spareblock->code_page_dir))))
641			pr_err("code page support is disabled\n");
642
643	brelse(bh2);
644	brelse(bh1);
645	brelse(bh0);
646
647	root = iget_locked(s, sbi->sb_root);
648	if (!root)
649		goto bail0;
650	hpfs_init_inode(root);
651	hpfs_read_inode(root);
652	unlock_new_inode(root);
653	s->s_root = d_make_root(root);
654	if (!s->s_root)
655		goto bail0;
656
657	/*
658	 * find the root directory's . pointer & finish filling in the inode
659	 */
660
661	root_dno = hpfs_fnode_dno(s, sbi->sb_root);
662	if (root_dno)
663		de = map_dirent(root, root_dno, "\001\001", 2, NULL, &qbh);
664	if (!de)
665		hpfs_error(s, "unable to find root dir");
666	else {
667		inode_set_atime(root,
668				local_to_gmt(s, le32_to_cpu(de->read_date)),
669				0);
670		inode_set_mtime(root,
671				local_to_gmt(s, le32_to_cpu(de->write_date)),
672				0);
673		inode_set_ctime(root,
674				local_to_gmt(s, le32_to_cpu(de->creation_date)),
675				0);
676		hpfs_i(root)->i_ea_size = le32_to_cpu(de->ea_size);
677		hpfs_i(root)->i_parent_dir = root->i_ino;
678		if (root->i_size == -1)
679			root->i_size = 2048;
680		if (root->i_blocks == -1)
681			root->i_blocks = 5;
682		hpfs_brelse4(&qbh);
683	}
684	hpfs_unlock(s);
685	return 0;
686
687bail4:	brelse(bh2);
688bail3:	brelse(bh1);
689bail2:	brelse(bh0);
690bail1:
691bail0:
692	hpfs_unlock(s);
693	free_sbi(sbi);
694	return -EINVAL;
695}
696
697static int hpfs_get_tree(struct fs_context *fc)
698{
699	return get_tree_bdev(fc, hpfs_fill_super);
700}
701
702static void hpfs_free_fc(struct fs_context *fc)
703{
704	kfree(fc->fs_private);
705}
706
707static const struct fs_context_operations hpfs_fc_context_ops = {
708	.parse_param	= hpfs_parse_param,
709	.get_tree	= hpfs_get_tree,
710	.reconfigure	= hpfs_reconfigure,
711	.free		= hpfs_free_fc,
712};
713
714static int hpfs_init_fs_context(struct fs_context *fc)
715{
716	struct hpfs_fc_context *ctx;
717
718	ctx = kzalloc(sizeof(struct hpfs_fc_context), GFP_KERNEL);
719	if (!ctx)
720		return -ENOMEM;
721
722	if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
723		struct super_block *sb = fc->root->d_sb;
724		struct hpfs_sb_info *sbi = hpfs_sb(sb);
725
726		ctx->uid = sbi->sb_uid;
727		ctx->gid = sbi->sb_gid;
728		ctx->umask = 0777 & ~sbi->sb_mode;
729		ctx->lowercase = sbi->sb_lowercase;
730		ctx->eas = sbi->sb_eas;
731		ctx->chk = sbi->sb_chk;
732		ctx->chkdsk = sbi->sb_chkdsk;
733		ctx->errs = sbi->sb_err;
734		ctx->timeshift = sbi->sb_timeshift;
735
736	} else {
737		ctx->uid = current_uid();
738		ctx->gid = current_gid();
739		ctx->umask = current_umask();
740		ctx->lowercase = 0;
741		ctx->eas = 2;
742		ctx->chk = 1;
743		ctx->errs = 1;
744		ctx->chkdsk = 1;
745		ctx->timeshift = 0;
746	}
747
748	fc->fs_private = ctx;
749	fc->ops = &hpfs_fc_context_ops;
750
751	return 0;
752};
753
754static struct file_system_type hpfs_fs_type = {
755	.owner		= THIS_MODULE,
756	.name		= "hpfs",
757	.kill_sb	= kill_block_super,
758	.fs_flags	= FS_REQUIRES_DEV,
759	.init_fs_context = hpfs_init_fs_context,
760	.parameters	= hpfs_param_spec,
761};
762MODULE_ALIAS_FS("hpfs");
763
764static int __init init_hpfs_fs(void)
765{
766	int err = init_inodecache();
767	if (err)
768		goto out1;
769	err = register_filesystem(&hpfs_fs_type);
770	if (err)
771		goto out;
772	return 0;
773out:
774	destroy_inodecache();
775out1:
776	return err;
777}
778
779static void __exit exit_hpfs_fs(void)
780{
781	unregister_filesystem(&hpfs_fs_type);
782	destroy_inodecache();
783}
784
785module_init(init_hpfs_fs)
786module_exit(exit_hpfs_fs)
787MODULE_DESCRIPTION("OS/2 HPFS file system support");
788MODULE_LICENSE("GPL");
~/ Read-only file preview.