⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ntfs_error(sb, "Failed to initialize attribute definition table.");	return false;}#endif /* NTFS_RW *//** * load_and_init_upcase - load the upcase table for an ntfs volume * @vol:	ntfs super block describing device whose upcase to load * * Return 'true' on success or 'false' on error. */static bool load_and_init_upcase(ntfs_volume *vol){	loff_t i_size;	struct super_block *sb = vol->sb;	struct inode *ino;	struct page *page;	pgoff_t 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).	 */	i_size = i_size_read(ino);	if (!i_size || i_size & (sizeof(ntfschar) - 1) ||			i_size > 64ULL * 1024 * sizeof(ntfschar))		goto iput_upcase_failed;	vol->upcase = (ntfschar*)ntfs_malloc_nofs(i_size);	if (!vol->upcase)		goto iput_upcase_failed;	index = 0;	max_index = 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 = i_size & ~PAGE_CACHE_MASK;		if (size)			goto read_partial_upcase_page;	}	vol->upcase_len = i_size >> UCHAR_T_SIZE_BITS;	ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).",			i_size, 64 * 1024 * sizeof(ntfschar));	iput(ino);	mutex_lock(&ntfs_lock);	if (!default_upcase) {		ntfs_debug("Using volume specified $UpCase since default is "				"not present.");		mutex_unlock(&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++;		mutex_unlock(&ntfs_lock);		ntfs_debug("Volume specified $UpCase matches default. Using "				"default.");		return true;	}	mutex_unlock(&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:	mutex_lock(&ntfs_lock);	if (default_upcase) {		vol->upcase = default_upcase;		vol->upcase_len = default_upcase_len;		ntfs_nr_upcase_users++;		mutex_unlock(&ntfs_lock);		ntfs_error(sb, "Failed to load $UpCase from the volume. Using "				"default.");		return true;	}	mutex_unlock(&ntfs_lock);	ntfs_error(sb, "Failed to initialize upcase table.");	return false;}/* * The lcn and mft bitmap inodes are NTFS-internal inodes with * their own special locking rules: */static struct lock_class_key	lcnbmp_runlist_lock_key, lcnbmp_mrec_lock_key,	mftbmp_runlist_lock_key, mftbmp_mrec_lock_key;/** * 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;#ifdef NTFS_RW	RESTART_PAGE_HEADER *rp;	int err;#endif /* NTFS_RW */	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;			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;	}	lockdep_set_class(&NTFS_I(vol->mftbmp_ino)->runlist.lock,			   &mftbmp_runlist_lock_key);	lockdep_set_class(&NTFS_I(vol->mftbmp_ino)->mrec_lock,			   &mftbmp_mrec_lock_key);	/* 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;	}	lockdep_set_class(&NTFS_I(vol->lcnbmp_ino)->runlist.lock,			   &lcnbmp_runlist_lock_key);	lockdep_set_class(&NTFS_I(vol->lcnbmp_ino)->mrec_lock,			   &lcnbmp_mrec_lock_key);	NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino));	if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) {		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);	if (vol->major_ver < 3 && NVolSparseEnabled(vol)) {		ntfs_warning(vol->sb, "Disabling sparse support due to NTFS "				"volume version %i.%i (need at least version "				"3.0).", vol->major_ver, vol->minor_ver);		NVolClearSparseEnabled(vol);	}#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 been modified by chkdsk";		static const char *es1c = "Volume has unsupported flags set";		static const char *es2a = ".  Run chkdsk and mount in Windows.";		static const char *es2b = ".  Mount in Windows.";		const char *es1, *es2;		es2 = es2a;		if (vol->vol_flags & VOLUME_IS_DIRTY)			es1 = es1a;		else if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {			es1 = es1b;			es2 = es2b;		} else {			es1 = es1c;			ntfs_warning(sb, "Unsupported volume flags 0x%x "					"encountered.",					(unsigned)le16_to_cpu(vol->vol_flags));		}		/* 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;			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.	 */	rp = NULL;	if (!load_and_check_logfile(vol, &rp) ||			!ntfs_is_logfile_clean(vol->logfile_ino, rp)) {		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);				if (vol->logfile_ino) {					BUG_ON(!rp);					ntfs_free(rp);				}				goto iput_logfile_err_out;			}			sb->s_flags |= MS_RDONLY;			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);	}	ntfs_free(rp);#endif /* NTFS_RW */	/* Get the root directory inode so we can do path lookups. */	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;	}#ifdef NTFS_RW	/*	 * Check if Windows is suspended to disk on the target volume.  If it	 * is hibernated, we must not write *anything* to the disk so set	 * NVolErrors() without setting the dirty volume flag and mount	 * read-only.  This will prevent read-write remounting and it will also	 * prevent all writes.	 */	err = check_windows_hibernation_status(vol);	if (unlikely(err)) {		static const char *es1a = "Failed to determine if Windows is "				"hibernated";		static const char *es1b = "Windows is hibernated";		static const char *es2 = ".  Run chkdsk.";		const char *es1;		es1 = err < 0 ? 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_root_err_out;			}			sb->s_flags |= MS_RDONLY;			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_root_err_out;		}		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);		sb->s_flags |= MS_RDONLY;		/*		 * Do not 

⌨️ 快捷键说明

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