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

📄 xfs_vfsops.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		 */		tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);		if ((error = xfs_trans_reserve(tp, 0,				XFS_ICHANGE_LOG_RES(mp),				0, 0, 0)))  {			xfs_trans_cancel(tp, 0);			return error;		}		ip = mp->m_rootip;		xfs_ilock(ip, XFS_ILOCK_EXCL);		xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);		xfs_trans_ihold(tp, ip);		xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);		error = xfs_trans_commit(tp, 0);		xfs_iunlock(ip, XFS_ILOCK_EXCL);		xfs_log_force(mp, (xfs_lsn_t)0, log_flags);	}	/*	 * When shutting down, we need to insure that the AIL is pushed	 * to disk or the filesystem can appear corrupt from the PROM.	 */	if ((flags & (SYNC_CLOSE|SYNC_WAIT)) == (SYNC_CLOSE|SYNC_WAIT)) {		XFS_bflush(mp->m_ddev_targp);		if (mp->m_rtdev_targp) {			XFS_bflush(mp->m_rtdev_targp);		}	}	return XFS_ERROR(last_error);}/* * xfs_vget - called by DMAPI and NFSD to get vnode from file handle */intxfs_vget(	xfs_mount_t	*mp,	bhv_vnode_t	**vpp,	xfs_fid_t	*xfid){	xfs_inode_t	*ip;	int		error;	xfs_ino_t	ino;	unsigned int	igen;	/*	 * Invalid.  Since handles can be created in user space and passed in	 * via gethandle(), this is not cause for a panic.	 */	if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len))		return XFS_ERROR(EINVAL);	ino  = xfid->fid_ino;	igen = xfid->fid_gen;	/*	 * NFS can sometimes send requests for ino 0.  Fail them gracefully.	 */	if (ino == 0)		return XFS_ERROR(ESTALE);	error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);	if (error) {		*vpp = NULL;		return error;	}	if (ip == NULL) {		*vpp = NULL;		return XFS_ERROR(EIO);	}	if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {		xfs_iput_new(ip, XFS_ILOCK_SHARED);		*vpp = NULL;		return XFS_ERROR(ENOENT);	}	*vpp = XFS_ITOV(ip);	xfs_iunlock(ip, XFS_ILOCK_SHARED);	return 0;}#define MNTOPT_LOGBUFS	"logbufs"	/* number of XFS log buffers */#define MNTOPT_LOGBSIZE	"logbsize"	/* size of XFS log buffers */#define MNTOPT_LOGDEV	"logdev"	/* log device */#define MNTOPT_RTDEV	"rtdev"		/* realtime I/O device */#define MNTOPT_BIOSIZE	"biosize"	/* log2 of preferred buffered io size */#define MNTOPT_WSYNC	"wsync"		/* safe-mode nfs compatible mount */#define MNTOPT_INO64	"ino64"		/* force inodes into 64-bit range */#define MNTOPT_NOALIGN	"noalign"	/* turn off stripe alignment */#define MNTOPT_SWALLOC	"swalloc"	/* turn on stripe width allocation */#define MNTOPT_SUNIT	"sunit"		/* data volume stripe unit */#define MNTOPT_SWIDTH	"swidth"	/* data volume stripe width */#define MNTOPT_NOUUID	"nouuid"	/* ignore filesystem UUID */#define MNTOPT_MTPT	"mtpt"		/* filesystem mount point */#define MNTOPT_GRPID	"grpid"		/* group-ID from parent directory */#define MNTOPT_NOGRPID	"nogrpid"	/* group-ID from current process */#define MNTOPT_BSDGROUPS    "bsdgroups"    /* group-ID from parent directory */#define MNTOPT_SYSVGROUPS   "sysvgroups"   /* group-ID from current process */#define MNTOPT_ALLOCSIZE    "allocsize"    /* preferred allocation size */#define MNTOPT_NORECOVERY   "norecovery"   /* don't run XFS recovery */#define MNTOPT_BARRIER	"barrier"	/* use writer barriers for log write and					 * unwritten extent conversion */#define MNTOPT_NOBARRIER "nobarrier"	/* .. disable */#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */#define MNTOPT_64BITINODE   "inode64"	/* inodes can be allocated anywhere */#define MNTOPT_IKEEP	"ikeep"		/* do not free empty inode clusters */#define MNTOPT_NOIKEEP	"noikeep"	/* free empty inode clusters */#define MNTOPT_LARGEIO	   "largeio"	/* report large I/O sizes in stat() */#define MNTOPT_NOLARGEIO   "nolargeio"	/* do not report large I/O sizes					 * in stat(). */#define MNTOPT_ATTR2	"attr2"		/* do use attr2 attribute format */#define MNTOPT_NOATTR2	"noattr2"	/* do not use attr2 attribute format */#define MNTOPT_FILESTREAM  "filestreams" /* use filestreams allocator */#define MNTOPT_QUOTA	"quota"		/* disk quotas (user) */#define MNTOPT_NOQUOTA	"noquota"	/* no quotas */#define MNTOPT_USRQUOTA	"usrquota"	/* user quota enabled */#define MNTOPT_GRPQUOTA	"grpquota"	/* group quota enabled */#define MNTOPT_PRJQUOTA	"prjquota"	/* project quota enabled */#define MNTOPT_UQUOTA	"uquota"	/* user quota (IRIX variant) */#define MNTOPT_GQUOTA	"gquota"	/* group quota (IRIX variant) */#define MNTOPT_PQUOTA	"pquota"	/* project quota (IRIX variant) */#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */#define MNTOPT_QUOTANOENF  "qnoenforce"	/* same as uqnoenforce */#define MNTOPT_DMAPI	"dmapi"		/* DMI enabled (DMAPI / XDSM) */#define MNTOPT_XDSM	"xdsm"		/* DMI enabled (DMAPI / XDSM) */#define MNTOPT_DMI	"dmi"		/* DMI enabled (DMAPI / XDSM) */STATIC unsigned longsuffix_strtoul(char *s, char **endp, unsigned int base){	int	last, shift_left_factor = 0;	char	*value = s;	last = strlen(value) - 1;	if (value[last] == 'K' || value[last] == 'k') {		shift_left_factor = 10;		value[last] = '\0';	}	if (value[last] == 'M' || value[last] == 'm') {		shift_left_factor = 20;		value[last] = '\0';	}	if (value[last] == 'G' || value[last] == 'g') {		shift_left_factor = 30;		value[last] = '\0';	}	return simple_strtoul((const char *)s, endp, base) << shift_left_factor;}intxfs_parseargs(	struct xfs_mount	*mp,	char			*options,	struct xfs_mount_args	*args,	int			update){	char			*this_char, *value, *eov;	int			dsunit, dswidth, vol_dsunit, vol_dswidth;	int			iosize;	int			ikeep = 0;	args->flags |= XFSMNT_BARRIER;	args->flags2 |= XFSMNT2_COMPAT_IOSIZE;	if (!options)		goto done;	iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;	while ((this_char = strsep(&options, ",")) != NULL) {		if (!*this_char)			continue;		if ((value = strchr(this_char, '=')) != NULL)			*value++ = 0;		if (!strcmp(this_char, MNTOPT_LOGBUFS)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			args->logbufs = simple_strtoul(value, &eov, 10);		} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			args->logbufsize = suffix_strtoul(value, &eov, 10);		} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			strncpy(args->logname, value, MAXNAMELEN);		} else if (!strcmp(this_char, MNTOPT_MTPT)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			strncpy(args->mtpt, value, MAXNAMELEN);		} else if (!strcmp(this_char, MNTOPT_RTDEV)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			strncpy(args->rtname, value, MAXNAMELEN);		} else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			iosize = simple_strtoul(value, &eov, 10);			args->flags |= XFSMNT_IOSIZE;			args->iosizelog = (uint8_t) iosize;		} else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			iosize = suffix_strtoul(value, &eov, 10);			args->flags |= XFSMNT_IOSIZE;			args->iosizelog = ffs(iosize) - 1;		} else if (!strcmp(this_char, MNTOPT_GRPID) ||			   !strcmp(this_char, MNTOPT_BSDGROUPS)) {			mp->m_flags |= XFS_MOUNT_GRPID;		} else if (!strcmp(this_char, MNTOPT_NOGRPID) ||			   !strcmp(this_char, MNTOPT_SYSVGROUPS)) {			mp->m_flags &= ~XFS_MOUNT_GRPID;		} else if (!strcmp(this_char, MNTOPT_WSYNC)) {			args->flags |= XFSMNT_WSYNC;		} else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {			args->flags |= XFSMNT_OSYNCISOSYNC;		} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {			args->flags |= XFSMNT_NORECOVERY;		} else if (!strcmp(this_char, MNTOPT_INO64)) {			args->flags |= XFSMNT_INO64;#if !XFS_BIG_INUMS			cmn_err(CE_WARN,				"XFS: %s option not allowed on this system",				this_char);			return EINVAL;#endif		} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {			args->flags |= XFSMNT_NOALIGN;		} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {			args->flags |= XFSMNT_SWALLOC;		} else if (!strcmp(this_char, MNTOPT_SUNIT)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			dsunit = simple_strtoul(value, &eov, 10);		} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {			if (!value || !*value) {				cmn_err(CE_WARN,					"XFS: %s option requires an argument",					this_char);				return EINVAL;			}			dswidth = simple_strtoul(value, &eov, 10);		} else if (!strcmp(this_char, MNTOPT_64BITINODE)) {			args->flags &= ~XFSMNT_32BITINODES;#if !XFS_BIG_INUMS			cmn_err(CE_WARN,				"XFS: %s option not allowed on this system",				this_char);			return EINVAL;#endif		} else if (!strcmp(this_char, MNTOPT_NOUUID)) {			args->flags |= XFSMNT_NOUUID;		} else if (!strcmp(this_char, MNTOPT_BARRIER)) {			args->flags |= XFSMNT_BARRIER;		} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {			args->flags &= ~XFSMNT_BARRIER;		} else if (!strcmp(this_char, MNTOPT_IKEEP)) {			ikeep = 1;			args->flags &= ~XFSMNT_IDELETE;		} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {			args->flags |= XFSMNT_IDELETE;		} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {			args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;		} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {			args->flags2 |= XFSMNT2_COMPAT_IOSIZE;		} else if (!strcmp(this_char, MNTOPT_ATTR2)) {			args->flags |= XFSMNT_ATTR2;		} else if (!strcmp(this_char, MNTOPT_NOATTR2)) {			args->flags &= ~XFSMNT_ATTR2;		} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {			args->flags2 |= XFSMNT2_FILESTREAMS;		} else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {			args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);			args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);		} else if (!strcmp(this_char, MNTOPT_QUOTA) ||			   !strcmp(this_char, MNTOPT_UQUOTA) ||			   !strcmp(this_char, MNTOPT_USRQUOTA)) {			args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;		} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||			   !strcmp(this_char, MNTOPT_UQUOTANOENF)) {			args->flags |= XFSMNT_UQUOTA;			args->flags &= ~XFSMNT_UQUOTAENF;		} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||			   !strcmp(this_char, MNTOPT_PRJQUOTA)) {			args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;		} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {			args->flags |= XFSMNT_PQUOTA;			args->flags &= ~XFSMNT_PQUOTAENF;		} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||			   !strcmp(this_char, MNTOPT_GRPQUOTA)) {			args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;		} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {			args->flags |= XFSMNT_GQUOTA;			args->flags &= ~XFSMNT_GQUOTAENF;		} else if (!strcmp(this_char, MNTOPT_DMAPI)) {			args->flags |= XFSMNT_DMAPI;		} else if (!strcmp(this_char, MNTOPT_XDSM)) {			args->flags |= XFSMNT_DMAPI;		} else if (!strcmp(this_char, MNTOPT_DMI)) {			args->flags |= XFSMNT_DMAPI;		} else if (!strcmp(this_char, "ihashsize")) {			cmn_err(CE_WARN,	"XFS: ihashsize no longer used, option is deprecated.");		} else if (!strcmp(this_char, "osyncisdsync")) {			/* no-op, this is now the default */			cmn_err(CE_WARN,	"XFS: osyncisdsync is now the default, option is deprecated.");		} else if (!strcmp(this_char, "irixsgid")) {			cmn_err(CE_WARN,	"XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");		} else {			cmn_err(CE_WARN,				"XFS: unknown mount option [%s].", this_char);			return EINVAL;		}	}	if (args->flags & XFSMNT_NORECOVERY) {		if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) {			cmn_err(CE_WARN,				"XFS: no-recovery mounts must be read-only.");			return EINVAL;		}	}	if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {		cmn_err(CE_WARN,	"XFS: sunit and swidth options incompatible with the noalign option");		return EINVAL;	}	if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {		cmn_err(CE_WARN,			"XFS: cannot mount with both project and group quota");		return EINVAL;	}	if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {		printk("XFS: %s option needs the mount point option as well\n",			MNTOPT_DMAPI);		return EINVAL;	}	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {		cmn_err(CE_WARN,			"XFS: sunit and swidth must be specified together");		return EINVAL;	}	if (dsunit && (dswidth % dsunit != 0)) {		cmn_err(CE_WARN,	"XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",			dswidth, dsunit);		return EINVAL;	}	/*	 * Applications using DMI filesystems often expect the	 * inode generation number to be monotonically increasing.	 * If we delete inode chunks we break this assumption, so	 * keep unused inode chunks on disk for DMI filesystems	 * until we come up with a better solution.	 * Note that if "ikeep" or "noikeep" mount options are	 * supplied, then they are honored.	 */	if (!(args->flags & XFSMNT_DMAPI) && !ikeep)		args->flags |= XFSMNT_IDELETE;	if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {		if (dsunit) {			args->sunit = dsunit;			args->flags |= XFSMNT_RETERR;		} else {			args->sunit = vol_dsunit;		}		dswidth ? (args->swidth = dswidth) :			  (args->swidth = vol_dswidth);	} else {		args->sunit = args->swidth = 0;	}done:	if (args->flags & XFSMNT_32BITINODES)		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;	if (args->flags2)		args->flags |= XFSMNT_FLAGS2;	return 0;}intxfs_showargs(	struct xfs_mount	*mp,	struct seq_file		*m){	static struct proc_xfs_info {		int	flag;		char	*str;	} xfs_info[] = {		/* the few simple ones we can get from the mount struct */		{ XFS_MOUNT_WSYNC,		"," MNTOPT_WSYNC },		{ XFS_MOUNT_INO64,		"," MNTOPT_INO64 },		{ XFS_MOUNT_NOALIGN,		"," MNTOPT_NOALIGN },		{ XFS_MOUNT_SWALLOC,		"," MNTOPT_SWALLOC },		{ XFS_MOUNT_NOUUID,		"," MNTOPT_NOUUID },		{ XFS_MOUNT_NORECOVERY,		"," MNTOPT_NORECOVERY },		{ XFS_MOUNT_OSYNCISOSYNC,	"," MNTOPT_OSYNCISOSYNC },		{ 0, NULL }	};	struct proc_xfs_info	*xfs_infop;	for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {		if (mp->m_flags & xfs_infop->flag)			seq_puts(m, xfs_infop->str);	}	if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)		seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",				(int)(1 << mp->m_writeio_log) >> 10);	if (mp->m_logbufs > 0)		seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);	if (mp->m_logbsize > 0)		seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);	if (mp->m_logname)		seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);	if (mp->m_rtname)		seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);	if (mp->m_dalign > 0)		seq_printf(m, "," MNTOPT_SUNIT "=%d",				(int)XFS_FSB_TO_BB(mp, mp->m_dalign));	if (mp->m_swidth > 0)		seq_printf(m, "," MNTOPT_SWIDTH "=%d",				(int)XFS_FSB_TO_BB(mp, mp->m_swidth));	if (!(mp->m_flags & XFS_MOUNT_IDELETE))		seq_printf(m, "," MNTOPT_IKEEP);	if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))		seq_printf(m, "," MNTOPT_LARGEIO);	if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS))		seq_printf(m, "," MNTOPT_64BITINODE);	if (mp->m_flags & XFS_MOUNT_GRPID)		seq_printf(m, "," MNTOPT_GRPID);	if (mp->m_qflags & XFS_UQUOTA_ACCT) {		if (mp->m_qflags & XFS_UQUOTA_ENFD)			seq_puts(m, "," MNTOPT_USRQUOTA);		else			seq_puts(m, "," MNTOPT_UQUOTANOENF);	}	if (mp->m_qflags & XFS_PQUOTA_ACCT) {		if (mp->m_qflags & XFS_OQUOTA_ENFD)			seq_puts(m, "," MNTOPT_PRJQUOTA);		else			seq_puts(m, "," MNTOPT_PQUOTANOENF);	}	if (mp->m_qflags & XFS_GQUOTA_ACCT) {		if (mp->m_qflags & XFS_OQUOTA_ENFD)			seq_puts(m, "," MNTOPT_GRPQUOTA);		else			seq_puts(m, "," MNTOPT_GQUOTANOENF);	}	if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))		seq_puts(m, "," MNTOPT_NOQUOTA);	if (mp->m_flags & XFS_MOUNT_DMAPI)		seq_puts(m, "," MNTOPT_DMAPI);	return 0;}/* * Second stage of a freeze. The data is already frozen so we only * need to take care of themetadata. Once that's done write a dummy * record to dirty the log in case of a crash while frozen. */voidxfs_freeze(	xfs_mount_t	*mp){	xfs_attr_quiesce(mp);	xfs_fs_log_dummy(mp);}

⌨️ 快捷键说明

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