mountオプション
mountのオプションは、super_block構造体とmount構造体とに分けて設定されます。階層的にsuper_block下に複数のmountを有することになります。super_blockは実際の読み書き等の同期操作の物理的依存するオプション群(sbをベースに取得するinodeに掛かるロックの処理も影響します。)で、mountはvfsのアクセスタイム等の物理的読み書きに依存しないオプションとなります。
実装しているオプションは以下の通りです。なおMS_BIND/MS_MOVE/MS_REC /MS_UNBINDABLE/MS_PRIVATE/MS_SLAVE/MS_SHARED/MS_KERNMOUNTは、他の属性オプションと異なり、mount操作自身のオプションとなります。
通常mount操作do_new_mount()で、スーパブロックが取得済みの場合(既にマウント済み)、たぶんmntフラグしか有効とならないようです。(file_system_type構造体にスーパブロックはリスト管理されています。)
もし、sbフラグにかかるオプションを設定する場合、MS_REMOUNTで再マウントする必要があります。ただしこの時ファイルシステム依存のスーパブロックオペレーションのremount_fsコールバック関数がコールされ、ファイルシステム依存の処理で設定されます。
do_change_type()は、MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLEのみで、他のオプションは無効です。do_move_mount()はマウント先の移動では、属性の引数は必要ない。と言うことのようです。(有ってもいいのかもしれませんが。)
実装しているオプションは以下の通りです。なおMS_BIND/MS_MOVE/MS_REC /MS_UNBINDABLE/MS_PRIVATE/MS_SLAVE/MS_SHARED/MS_KERNMOUNTは、他の属性オプションと異なり、mount操作自身のオプションとなります。
#define MS_RDONLY 1 /* Mount read-only */ #define MS_NOSUID 2 /* Ignore suid and sgid bits */ #define MS_NODEV 4 /* Disallow access to device special files */ #define MS_NOEXEC 8 /* Disallow program execution */ #define MS_SYNCHRONOUS 16 /* Writes are synced at once */ #define MS_REMOUNT 32 /* Alter flags of a mounted FS */ #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ #define MS_DIRSYNC 128 /* Directory modifications are synchronous */ #define MS_NOATIME 1024 /* Do not update access times. */ #define MS_NODIRATIME 2048 /* Do not update directory access times */ #define MS_BIND 4096 #define MS_MOVE 8192 #define MS_REC 16384 #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. MS_VERBOSE is deprecated. */ #define MS_SILENT 32768 #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ #define MS_UNBINDABLE (1<<17) /* change to unbindable */ #define MS_PRIVATE (1<<18) /* change to private */ #define MS_SLAVE (1<<19) /* change to slave */ #define MS_SHARED (1<<20) /* change to shared */ #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ #define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ #define MS_NOSEC (1<<28) #define MS_BORN (1<<29) #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31)mountコマンドオプションは、flagsで、このフラグからmntフラグ(mnt_flags)とsbフラグ(flags)を分割取得し、MS_NOATIME/MS_NOSUID/MS_NODEV/MS_NOEXEC/MS_NOATIME/MS_NODIRATIME/MS_STRICTATIME/MS_RDONLYは、mntフラグとなり、他はsbフラグとなります。
通常mount操作do_new_mount()で、スーパブロックが取得済みの場合(既にマウント済み)、たぶんmntフラグしか有効とならないようです。(file_system_type構造体にスーパブロックはリスト管理されています。)
もし、sbフラグにかかるオプションを設定する場合、MS_REMOUNTで再マウントする必要があります。ただしこの時ファイルシステム依存のスーパブロックオペレーションのremount_fsコールバック関数がコールされ、ファイルシステム依存の処理で設定されます。
long do_mount(char *dev_name, char *dir_name, char *type_page, unsigned long flags, void *data_page) { struct path path; int retval = 0; int mnt_flags = 0; /* Discard magic */ if ((flags & MS_MGC_MSK) == MS_MGC_VAL) flags &= ~MS_MGC_MSK; if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) return -EINVAL; if (data_page) ((char *)data_page)[PAGE_SIZE - 1] = 0; /* ... and get the mountpoint */ retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); if (retval) return retval; retval = security_sb_mount(dev_name, &path, type_page, flags, data_page); if (retval) goto dput_out; /* Default to relatime unless overriden */ if (!(flags & MS_NOATIME)) mnt_flags |= MNT_RELATIME; /* Separate the per-mountpoint flags */ if (flags & MS_NOSUID) mnt_flags |= MNT_NOSUID; if (flags & MS_NODEV) mnt_flags |= MNT_NODEV; if (flags & MS_NOEXEC) mnt_flags |= MNT_NOEXEC; if (flags & MS_NOATIME) mnt_flags |= MNT_NOATIME; if (flags & MS_NODIRATIME) mnt_flags |= MNT_NODIRATIME; if (flags & MS_STRICTATIME) mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME); if (flags & MS_RDONLY) mnt_flags |= MNT_READONLY; flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | MS_STRICTATIME); if (flags & MS_REMOUNT) retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, data_page); else if (flags & MS_BIND) retval = do_loopback(&path, dev_name, flags & MS_REC); else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) retval = do_change_type(&path, flags); else if (flags & MS_MOVE) retval = do_move_mount(&path, dev_name); else retval = do_new_mount(&path, type_page, flags, mnt_flags, dev_name, data_page); dput_out: path_put(&path); return retval; }バインドマウントのdo_loopback()は、オプションの設定はできません。(flags & MS_RECはMS_REC:リカーシブルが設定されているかどうかだけ。)マウント元は、そのパスの属するファイルシステムのスーパブロック/マウント構造体を使用するからです。
do_change_type()は、MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLEのみで、他のオプションは無効です。do_move_mount()はマウント先の移動では、属性の引数は必要ない。と言うことのようです。(有ってもいいのかもしれませんが。)