📄 xfs_vfsops.c
字号:
*/ 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 + -