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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. * * Copyright (c) 2001-2007 Anton Altaparmakov * Copyright (c) 2001,2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program/include file is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (in the main directory of the Linux-NTFS * distribution in the file COPYING); if not, write to the Free Software * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <linux/stddef.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/spinlock.h>#include <linux/blkdev.h>	/* For bdev_hardsect_size(). */#include <linux/backing-dev.h>#include <linux/buffer_head.h>#include <linux/vfs.h>#include <linux/moduleparam.h>#include <linux/smp_lock.h>#include "sysctl.h"#include "logfile.h"#include "quota.h"#include "usnjrnl.h"#include "dir.h"#include "debug.h"#include "index.h"#include "aops.h"#include "layout.h"#include "malloc.h"#include "ntfs.h"/* Number of mounted filesystems which have compression enabled. */static unsigned long ntfs_nr_compression_users;/* A global default upcase table and a corresponding reference count. */static ntfschar *default_upcase = NULL;static unsigned long ntfs_nr_upcase_users = 0;/* Error constants/strings used in inode.c::ntfs_show_options(). */typedef enum {	/* One of these must be present, default is ON_ERRORS_CONTINUE. */	ON_ERRORS_PANIC			= 0x01,	ON_ERRORS_REMOUNT_RO		= 0x02,	ON_ERRORS_CONTINUE		= 0x04,	/* Optional, can be combined with any of the above. */	ON_ERRORS_RECOVER		= 0x10,} ON_ERRORS_ACTIONS;const option_t on_errors_arr[] = {	{ ON_ERRORS_PANIC,	"panic" },	{ ON_ERRORS_REMOUNT_RO,	"remount-ro", },	{ ON_ERRORS_CONTINUE,	"continue", },	{ ON_ERRORS_RECOVER,	"recover" },	{ 0,			NULL }};/** * simple_getbool - * * Copied from old ntfs driver (which copied from vfat driver). */static int simple_getbool(char *s, bool *setval){	if (s) {		if (!strcmp(s, "1") || !strcmp(s, "yes") || !strcmp(s, "true"))			*setval = true;		else if (!strcmp(s, "0") || !strcmp(s, "no") ||							!strcmp(s, "false"))			*setval = false;		else			return 0;	} else		*setval = true;	return 1;}/** * parse_options - parse the (re)mount options * @vol:	ntfs volume * @opt:	string containing the (re)mount options * * Parse the recognized options in @opt for the ntfs volume described by @vol. */static bool parse_options(ntfs_volume *vol, char *opt){	char *p, *v, *ov;	static char *utf8 = "utf8";	int errors = 0, sloppy = 0;	uid_t uid = (uid_t)-1;	gid_t gid = (gid_t)-1;	mode_t fmask = (mode_t)-1, dmask = (mode_t)-1;	int mft_zone_multiplier = -1, on_errors = -1;	int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1;	struct nls_table *nls_map = NULL, *old_nls;	/* I am lazy... (-8 */#define NTFS_GETOPT_WITH_DEFAULT(option, variable, default_value)	\	if (!strcmp(p, option)) {					\		if (!v || !*v)						\			variable = default_value;			\		else {							\			variable = simple_strtoul(ov = v, &v, 0);	\			if (*v)						\				goto needs_val;				\		}							\	}#define NTFS_GETOPT(option, variable)					\	if (!strcmp(p, option)) {					\		if (!v || !*v)						\			goto needs_arg;					\		variable = simple_strtoul(ov = v, &v, 0);		\		if (*v)							\			goto needs_val;					\	}#define NTFS_GETOPT_OCTAL(option, variable)				\	if (!strcmp(p, option)) {					\		if (!v || !*v)						\			goto needs_arg;					\		variable = simple_strtoul(ov = v, &v, 8);		\		if (*v)							\			goto needs_val;					\	}#define NTFS_GETOPT_BOOL(option, variable)				\	if (!strcmp(p, option)) {					\		bool val;						\		if (!simple_getbool(v, &val))				\			goto needs_bool;				\		variable = val;						\	}#define NTFS_GETOPT_OPTIONS_ARRAY(option, variable, opt_array)		\	if (!strcmp(p, option)) {					\		int _i;							\		if (!v || !*v)						\			goto needs_arg;					\		ov = v;							\		if (variable == -1)					\			variable = 0;					\		for (_i = 0; opt_array[_i].str && *opt_array[_i].str; _i++) \			if (!strcmp(opt_array[_i].str, v)) {		\				variable |= opt_array[_i].val;		\				break;					\			}						\		if (!opt_array[_i].str || !*opt_array[_i].str)		\			goto needs_val;					\	}	if (!opt || !*opt)		goto no_mount_options;	ntfs_debug("Entering with mount options string: %s", opt);	while ((p = strsep(&opt, ","))) {		if ((v = strchr(p, '=')))			*v++ = 0;		NTFS_GETOPT("uid", uid)		else NTFS_GETOPT("gid", gid)		else NTFS_GETOPT_OCTAL("umask", fmask = dmask)		else NTFS_GETOPT_OCTAL("fmask", fmask)		else NTFS_GETOPT_OCTAL("dmask", dmask)		else NTFS_GETOPT("mft_zone_multiplier", mft_zone_multiplier)		else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, true)		else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files)		else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive)		else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse)		else NTFS_GETOPT_OPTIONS_ARRAY("errors", on_errors,				on_errors_arr)		else if (!strcmp(p, "posix") || !strcmp(p, "show_inodes"))			ntfs_warning(vol->sb, "Ignoring obsolete option %s.",					p);		else if (!strcmp(p, "nls") || !strcmp(p, "iocharset")) {			if (!strcmp(p, "iocharset"))				ntfs_warning(vol->sb, "Option iocharset is "						"deprecated. Please use "						"option nls=<charsetname> in "						"the future.");			if (!v || !*v)				goto needs_arg;use_utf8:			old_nls = nls_map;			nls_map = load_nls(v);			if (!nls_map) {				if (!old_nls) {					ntfs_error(vol->sb, "NLS character set "							"%s not found.", v);					return false;				}				ntfs_error(vol->sb, "NLS character set %s not "						"found. Using previous one %s.",						v, old_nls->charset);				nls_map = old_nls;			} else /* nls_map */ {				if (old_nls)					unload_nls(old_nls);			}		} else if (!strcmp(p, "utf8")) {			bool val = false;			ntfs_warning(vol->sb, "Option utf8 is no longer "				   "supported, using option nls=utf8. Please "				   "use option nls=utf8 in the future and "				   "make sure utf8 is compiled either as a "				   "module or into the kernel.");			if (!v || !*v)				val = true;			else if (!simple_getbool(v, &val))				goto needs_bool;			if (val) {				v = utf8;				goto use_utf8;			}		} else {			ntfs_error(vol->sb, "Unrecognized mount option %s.", p);			if (errors < INT_MAX)				errors++;		}#undef NTFS_GETOPT_OPTIONS_ARRAY#undef NTFS_GETOPT_BOOL#undef NTFS_GETOPT#undef NTFS_GETOPT_WITH_DEFAULT	}no_mount_options:	if (errors && !sloppy)		return false;	if (sloppy)		ntfs_warning(vol->sb, "Sloppy option given. Ignoring "				"unrecognized mount option(s) and continuing.");	/* Keep this first! */	if (on_errors != -1) {		if (!on_errors) {			ntfs_error(vol->sb, "Invalid errors option argument "					"or bug in options parser.");			return false;		}	}	if (nls_map) {		if (vol->nls_map && vol->nls_map != nls_map) {			ntfs_error(vol->sb, "Cannot change NLS character set "					"on remount.");			return false;		} /* else (!vol->nls_map) */		ntfs_debug("Using NLS character set %s.", nls_map->charset);		vol->nls_map = nls_map;	} else /* (!nls_map) */ {		if (!vol->nls_map) {			vol->nls_map = load_nls_default();			if (!vol->nls_map) {				ntfs_error(vol->sb, "Failed to load default "						"NLS character set.");				return false;			}			ntfs_debug("Using default NLS character set (%s).",					vol->nls_map->charset);		}	}	if (mft_zone_multiplier != -1) {		if (vol->mft_zone_multiplier && vol->mft_zone_multiplier !=				mft_zone_multiplier) {			ntfs_error(vol->sb, "Cannot change mft_zone_multiplier "					"on remount.");			return false;		}		if (mft_zone_multiplier < 1 || mft_zone_multiplier > 4) {			ntfs_error(vol->sb, "Invalid mft_zone_multiplier. "					"Using default value, i.e. 1.");			mft_zone_multiplier = 1;		}		vol->mft_zone_multiplier = mft_zone_multiplier;	}	if (!vol->mft_zone_multiplier)		vol->mft_zone_multiplier = 1;	if (on_errors != -1)		vol->on_errors = on_errors;	if (!vol->on_errors || vol->on_errors == ON_ERRORS_RECOVER)		vol->on_errors |= ON_ERRORS_CONTINUE;	if (uid != (uid_t)-1)		vol->uid = uid;	if (gid != (gid_t)-1)		vol->gid = gid;	if (fmask != (mode_t)-1)		vol->fmask = fmask;	if (dmask != (mode_t)-1)		vol->dmask = dmask;	if (show_sys_files != -1) {		if (show_sys_files)			NVolSetShowSystemFiles(vol);		else			NVolClearShowSystemFiles(vol);	}	if (case_sensitive != -1) {		if (case_sensitive)			NVolSetCaseSensitive(vol);		else			NVolClearCaseSensitive(vol);	}	if (disable_sparse != -1) {		if (disable_sparse)			NVolClearSparseEnabled(vol);		else {			if (!NVolSparseEnabled(vol) &&					vol->major_ver && vol->major_ver < 3)				ntfs_warning(vol->sb, "Not enabling sparse "						"support due to NTFS volume "						"version %i.%i (need at least "						"version 3.0).", vol->major_ver,						vol->minor_ver);			else				NVolSetSparseEnabled(vol);		}	}	return true;needs_arg:	ntfs_error(vol->sb, "The %s option requires an argument.", p);	return false;needs_bool:	ntfs_error(vol->sb, "The %s option requires a boolean argument.", p);	return false;needs_val:	ntfs_error(vol->sb, "Invalid %s option argument: %s", p, ov);	return false;}#ifdef NTFS_RW/** * ntfs_write_volume_flags - write new flags to the volume information flags * @vol:	ntfs volume on which to modify the flags * @flags:	new flags value for the volume information flags * * Internal function.  You probably want to use ntfs_{set,clear}_volume_flags() * instead (see below). * * Replace the volume information flags on the volume @vol with the value * supplied in @flags.  Note, this overwrites the volume information flags, so * make sure to combine the flags you want to modify with the old flags and use * the result when calling ntfs_write_volume_flags(). * * Return 0 on success and -errno on error. */static int ntfs_write_volume_flags(ntfs_volume *vol, const VOLUME_FLAGS flags){	ntfs_inode *ni = NTFS_I(vol->vol_ino);	MFT_RECORD *m;	VOLUME_INFORMATION *vi;	ntfs_attr_search_ctx *ctx;	int err;	ntfs_debug("Entering, old flags = 0x%x, new flags = 0x%x.",			le16_to_cpu(vol->vol_flags), le16_to_cpu(flags));	if (vol->vol_flags == flags)		goto done;	BUG_ON(!ni);	m = map_mft_record(ni);	if (IS_ERR(m)) {		err = PTR_ERR(m);		goto err_out;	}	ctx = ntfs_attr_get_search_ctx(ni, m);	if (!ctx) {		err = -ENOMEM;		goto put_unm_err_out;	}	err = ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0,			ctx);	if (err)		goto put_unm_err_out;	vi = (VOLUME_INFORMATION*)((u8*)ctx->attr +			le16_to_cpu(ctx->attr->data.resident.value_offset));	vol->vol_flags = vi->flags = flags;	flush_dcache_mft_record_page(ctx->ntfs_ino);	mark_mft_record_dirty(ctx->ntfs_ino);	ntfs_attr_put_search_ctx(ctx);	unmap_mft_record(ni);done:	ntfs_debug("Done.");	return 0;put_unm_err_out:	if (ctx)		ntfs_attr_put_search_ctx(ctx);	unmap_mft_record(ni);err_out:	ntfs_error(vol->sb, "Failed with error code %i.", -err);	return err;}/** * ntfs_set_volume_flags - set bits in the volume information flags * @vol:	ntfs volume on which to modify the flags * @flags:	flags to set on the volume * * Set the bits in @flags in the volume information flags on the volume @vol. * * Return 0 on success and -errno on error. */

⌨️ 快捷键说明

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