super.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,070 行 · 第 1/5 页

C
2,070
字号
	struct inode *ino;	struct page *page;	unsigned long index, max_index;	unsigned int size;	int i, max;	ntfs_debug("Entering.");	/* Read upcase table and setup vol->upcase and vol->upcase_len. */	ino = ntfs_iget(sb, FILE_UpCase);	if (IS_ERR(ino) || is_bad_inode(ino)) {		if (!IS_ERR(ino))			iput(ino);		goto upcase_failed;	}	/*	 * The upcase size must not be above 64k Unicode characters, must not	 * be zero and must be a multiple of sizeof(ntfschar).	 */	if (!ino->i_size || ino->i_size & (sizeof(ntfschar) - 1) ||			ino->i_size > 64ULL * 1024 * sizeof(ntfschar))		goto iput_upcase_failed;	vol->upcase = (ntfschar*)ntfs_malloc_nofs(ino->i_size);	if (!vol->upcase)		goto iput_upcase_failed;	index = 0;	max_index = ino->i_size >> PAGE_CACHE_SHIFT;	size = PAGE_CACHE_SIZE;	while (index < max_index) {		/* Read the upcase table and copy it into the linear buffer. */read_partial_upcase_page:		page = ntfs_map_page(ino->i_mapping, index);		if (IS_ERR(page))			goto iput_upcase_failed;		memcpy((char*)vol->upcase + (index++ << PAGE_CACHE_SHIFT),				page_address(page), size);		ntfs_unmap_page(page);	};	if (size == PAGE_CACHE_SIZE) {		size = ino->i_size & ~PAGE_CACHE_MASK;		if (size)			goto read_partial_upcase_page;	}	vol->upcase_len = ino->i_size >> UCHAR_T_SIZE_BITS;	ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).",			ino->i_size, 64 * 1024 * sizeof(ntfschar));	iput(ino);	down(&ntfs_lock);	if (!default_upcase) {		ntfs_debug("Using volume specified $UpCase since default is "				"not present.");		up(&ntfs_lock);		return TRUE;	}	max = default_upcase_len;	if (max > vol->upcase_len)		max = vol->upcase_len;	for (i = 0; i < max; i++)		if (vol->upcase[i] != default_upcase[i])			break;	if (i == max) {		ntfs_free(vol->upcase);		vol->upcase = default_upcase;		vol->upcase_len = max;		ntfs_nr_upcase_users++;		up(&ntfs_lock);		ntfs_debug("Volume specified $UpCase matches default. Using "				"default.");		return TRUE;	}	up(&ntfs_lock);	ntfs_debug("Using volume specified $UpCase since it does not match "			"the default.");	return TRUE;iput_upcase_failed:	iput(ino);	ntfs_free(vol->upcase);	vol->upcase = NULL;upcase_failed:	down(&ntfs_lock);	if (default_upcase) {		vol->upcase = default_upcase;		vol->upcase_len = default_upcase_len;		ntfs_nr_upcase_users++;		up(&ntfs_lock);		ntfs_error(sb, "Failed to load $UpCase from the volume. Using "				"default.");		return TRUE;	}	up(&ntfs_lock);	ntfs_error(sb, "Failed to initialize upcase table.");	return FALSE;}/** * load_system_files - open the system files using normal functions * @vol:	ntfs super block describing device whose system files to load * * Open the system files with normal access functions and complete setting up * the ntfs super block @vol. * * Return TRUE on success or FALSE on error. */static BOOL load_system_files(ntfs_volume *vol){	struct super_block *sb = vol->sb;	MFT_RECORD *m;	VOLUME_INFORMATION *vi;	ntfs_attr_search_ctx *ctx;	ntfs_debug("Entering.");#ifdef NTFS_RW	/* Get mft mirror inode compare the contents of $MFT and $MFTMirr. */	if (!load_and_init_mft_mirror(vol) || !check_mft_mirror(vol)) {		static const char *es1 = "Failed to load $MFTMirr";		static const char *es2 = "$MFTMirr does not match $MFT";		static const char *es3 = ".  Run ntfsfix and/or chkdsk.";		/* If a read-write mount, convert it to a read-only mount. */		if (!(sb->s_flags & MS_RDONLY)) {			if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |					ON_ERRORS_CONTINUE))) {				ntfs_error(sb, "%s and neither on_errors="						"continue nor on_errors="						"remount-ro was specified%s",						!vol->mftmirr_ino ? es1 : es2,						es3);				goto iput_mirr_err_out;			}			sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;			ntfs_error(sb, "%s.  Mounting read-only%s",					!vol->mftmirr_ino ? es1 : es2, es3);		} else			ntfs_warning(sb, "%s.  Will not be able to remount "					"read-write%s",					!vol->mftmirr_ino ? es1 : es2, es3);		/* This will prevent a read-write remount. */		NVolSetErrors(vol);	}#endif /* NTFS_RW */	/* Get mft bitmap attribute inode. */	vol->mftbmp_ino = ntfs_attr_iget(vol->mft_ino, AT_BITMAP, NULL, 0);	if (IS_ERR(vol->mftbmp_ino)) {		ntfs_error(sb, "Failed to load $MFT/$BITMAP attribute.");		goto iput_mirr_err_out;	}	/* Read upcase table and setup @vol->upcase and @vol->upcase_len. */	if (!load_and_init_upcase(vol))		goto iput_mftbmp_err_out;#ifdef NTFS_RW	/*	 * Read attribute definitions table and setup @vol->attrdef and	 * @vol->attrdef_size.	 */	if (!load_and_init_attrdef(vol))		goto iput_upcase_err_out;#endif /* NTFS_RW */	/*	 * Get the cluster allocation bitmap inode and verify the size, no	 * need for any locking at this stage as we are already running	 * exclusively as we are mount in progress task.	 */	vol->lcnbmp_ino = ntfs_iget(sb, FILE_Bitmap);	if (IS_ERR(vol->lcnbmp_ino) || is_bad_inode(vol->lcnbmp_ino)) {		if (!IS_ERR(vol->lcnbmp_ino))			iput(vol->lcnbmp_ino);		goto bitmap_failed;	}	if ((vol->nr_clusters + 7) >> 3 > vol->lcnbmp_ino->i_size) {		iput(vol->lcnbmp_ino);bitmap_failed:		ntfs_error(sb, "Failed to load $Bitmap.");		goto iput_attrdef_err_out;	}	/*	 * Get the volume inode and setup our cache of the volume flags and	 * version.	 */	vol->vol_ino = ntfs_iget(sb, FILE_Volume);	if (IS_ERR(vol->vol_ino) || is_bad_inode(vol->vol_ino)) {		if (!IS_ERR(vol->vol_ino))			iput(vol->vol_ino);volume_failed:		ntfs_error(sb, "Failed to load $Volume.");		goto iput_lcnbmp_err_out;	}	m = map_mft_record(NTFS_I(vol->vol_ino));	if (IS_ERR(m)) {iput_volume_failed:		iput(vol->vol_ino);		goto volume_failed;	}	if (!(ctx = ntfs_attr_get_search_ctx(NTFS_I(vol->vol_ino), m))) {		ntfs_error(sb, "Failed to get attribute search context.");		goto get_ctx_vol_failed;	}	if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0,			ctx) || ctx->attr->non_resident || ctx->attr->flags) {err_put_vol:		ntfs_attr_put_search_ctx(ctx);get_ctx_vol_failed:		unmap_mft_record(NTFS_I(vol->vol_ino));		goto iput_volume_failed;	}	vi = (VOLUME_INFORMATION*)((char*)ctx->attr +			le16_to_cpu(ctx->attr->data.resident.value_offset));	/* Some bounds checks. */	if ((u8*)vi < (u8*)ctx->attr || (u8*)vi +			le32_to_cpu(ctx->attr->data.resident.value_length) >			(u8*)ctx->attr + le32_to_cpu(ctx->attr->length))		goto err_put_vol;	/* Copy the volume flags and version to the ntfs_volume structure. */	vol->vol_flags = vi->flags;	vol->major_ver = vi->major_ver;	vol->minor_ver = vi->minor_ver;	ntfs_attr_put_search_ctx(ctx);	unmap_mft_record(NTFS_I(vol->vol_ino));	printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,			vol->minor_ver);#ifdef NTFS_RW	/* Make sure that no unsupported volume flags are set. */	if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {		static const char *es1a = "Volume is dirty";		static const char *es1b = "Volume has unsupported flags set";		static const char *es2 = ".  Run chkdsk and mount in Windows.";		const char *es1;				es1 = vol->vol_flags & VOLUME_IS_DIRTY ? es1a : es1b;		/* If a read-write mount, convert it to a read-only mount. */		if (!(sb->s_flags & MS_RDONLY)) {			if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |					ON_ERRORS_CONTINUE))) {				ntfs_error(sb, "%s and neither on_errors="						"continue nor on_errors="						"remount-ro was specified%s",						es1, es2);				goto iput_vol_err_out;			}			sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;			ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		} else			ntfs_warning(sb, "%s.  Will not be able to remount "					"read-write%s", es1, es2);		/*		 * Do not set NVolErrors() because ntfs_remount() re-checks the		 * flags which we need to do in case any flags have changed.		 */	}	/*	 * Get the inode for the logfile, check it and determine if the volume	 * was shutdown cleanly.	 */	if (!load_and_check_logfile(vol) ||			!ntfs_is_logfile_clean(vol->logfile_ino)) {		static const char *es1a = "Failed to load $LogFile";		static const char *es1b = "$LogFile is not clean";		static const char *es2 = ".  Mount in Windows.";		const char *es1;		es1 = !vol->logfile_ino ? es1a : es1b;		/* If a read-write mount, convert it to a read-only mount. */		if (!(sb->s_flags & MS_RDONLY)) {			if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |					ON_ERRORS_CONTINUE))) {				ntfs_error(sb, "%s and neither on_errors="						"continue nor on_errors="						"remount-ro was specified%s",						es1, es2);				goto iput_logfile_err_out;			}			sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;			ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		} else			ntfs_warning(sb, "%s.  Will not be able to remount "					"read-write%s", es1, es2);		/* This will prevent a read-write remount. */		NVolSetErrors(vol);	}	/* If (still) a read-write mount, mark the volume dirty. */	if (!(sb->s_flags & MS_RDONLY) &&			ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {		static const char *es1 = "Failed to set dirty bit in volume "				"information flags";		static const char *es2 = ".  Run chkdsk.";		/* Convert to a read-only mount. */		if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |				ON_ERRORS_CONTINUE))) {			ntfs_error(sb, "%s and neither on_errors=continue nor "					"on_errors=remount-ro was specified%s",					es1, es2);			goto iput_logfile_err_out;		}		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;		/*		 * Do not set NVolErrors() because ntfs_remount() might manage		 * to set the dirty flag in which case all would be well.		 */	}#if 0	// TODO: Enable this code once we start modifying anything that is	//	 different between NTFS 1.2 and 3.x...	/*	 * If (still) a read-write mount, set the NT4 compatibility flag on	 * newer NTFS version volumes.	 */	if (!(sb->s_flags & MS_RDONLY) && (vol->major_ver > 1) &&			ntfs_set_volume_flags(vol, VOLUME_MOUNTED_ON_NT4)) {		static const char *es1 = "Failed to set NT4 compatibility flag";		static const char *es2 = ".  Run chkdsk.";		/* Convert to a read-only mount. */		if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |				ON_ERRORS_CONTINUE))) {			ntfs_error(sb, "%s and neither on_errors=continue nor "					"on_errors=remount-ro was specified%s",					es1, es2);			goto iput_logfile_err_out;		}		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;		NVolSetErrors(vol);	}#endif	/* If (still) a read-write mount, empty the logfile. */	if (!(sb->s_flags & MS_RDONLY) &&			!ntfs_empty_logfile(vol->logfile_ino)) {		static const char *es1 = "Failed to empty $LogFile";		static const char *es2 = ".  Mount in Windows.";		/* Convert to a read-only mount. */		if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |				ON_ERRORS_CONTINUE))) {			ntfs_error(sb, "%s and neither on_errors=continue nor "					"on_errors=remount-ro was specified%s",					es1, es2);			goto iput_logfile_err_out;		}		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;		NVolSetErrors(vol);	}#endif /* NTFS_RW */	/* Get the root directory inode. */	vol->root_ino = ntfs_iget(sb, FILE_root);	if (IS_ERR(vol->root_ino) || is_bad_inode(vol->root_ino)) {		if (!IS_ERR(vol->root_ino))			iput(vol->root_ino);		ntfs_error(sb, "Failed to load root directory.");		goto iput_logfile_err_out;	}	/* If on NTFS versions before 3.0, we are done. */	if (vol->major_ver < 3)		return TRUE;	/* NTFS 3.0+ specific initialization. */	/* Get the security descriptors inode. */	vol->secure_ino = ntfs_iget(sb, FILE_Secure);	if (IS_ERR(vol->secure_ino) || is_bad_inode(vol->secure_ino)) {		if (!IS_ERR(vol->secure_ino))			iput(vol->secure_ino);		ntfs_error(sb, "Failed to load $Secure.");		goto iput_root_err_out;	}	// FIXME: Initialize security.	/* Get the extended system files' directory inode. */	vol->extend_ino = ntfs_iget(sb, FILE_Extend);	if (IS_ERR(vol->extend_ino) || is_bad_inode(vol->extend_ino)) {		if (!IS_ERR(vol->extend_ino))			iput(vol->extend_ino);		ntfs_error(sb, "Failed to load $Extend.");		goto iput_sec_err_out;	}#ifdef NTFS_RW	/* Find the quota file, load it if present, and set it up. */	if (!load_and_init_quota(vol)) {		static const char *es1 = "Failed to load $Quota";		static const char *es2 = ".  Run chkdsk.";		/* If a read-write mount, convert it to a read-only mount. */		if (!(sb->s_flags & MS_RDONLY)) {			if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |					ON_ERRORS_CONTINUE))) {				ntfs_error(sb, "%s and neither on_errors="						"continue nor on_errors="						"remount-ro was specified%s",						es1, es2);				goto iput_quota_err_out;			}			sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;			ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		} else			ntfs_warning(sb, "%s.  Will not be able to remount "					"read-write%s", es1, es2);		/* This will prevent a read-write remount. */		NVolSetErrors(vol);	}	/* If (still) a read-write mount, mark the quotas out of date. */	if (!(sb->s_flags & MS_RDONLY) &&			!ntfs_mark_quotas_out_of_date(vol)) {		static const char *es1 = "Failed to mark quotas out of date";		static const char *es2 = ".  Run chkdsk.";		/* Convert to a read-only mount. */		if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |				ON_ERRORS_CONTINUE))) {			ntfs_error(sb, "%s and neither on_errors=continue nor "					"on_errors=remount-ro was specified%s",					es1, es2);			goto iput_quota_err_out;		}		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;		NVolSetErrors(vol);	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?