Commit 629cbe32 authored by J. R. Okajima's avatar J. R. Okajima
Browse files

aufs: native/real readonly branch



Some filesystems are natively readonly. And aufs can make a few
optimization for them. This new attribute tells aufs.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent 0ba3f959
......@@ -14,6 +14,7 @@
#include <linux/fs.h>
#include <linux/magic.h>
#include <linux/romfs_fs.h>
static inline int au_test_aufs(struct super_block *sb)
{
......@@ -25,6 +26,32 @@ static inline const char *au_sbtype(struct super_block *sb)
return sb->s_type->name;
}
static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
{
#if IS_ENABLED(CONFIG_ISO9660_FS)
return sb->s_magic == ISOFS_SUPER_MAGIC;
#else
return 0;
#endif
}
static inline int au_test_romfs(struct super_block *sb __maybe_unused)
{
#if IS_ENABLED(CONFIG_ROMFS_FS)
return sb->s_magic == ROMFS_MAGIC;
#else
return 0;
#endif
}
static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
{
#if IS_ENABLED(CONFIG_CRAMFS)
return sb->s_magic == CRAMFS_MAGIC;
#endif
return 0;
}
static inline int au_test_nfs(struct super_block *sb __maybe_unused)
{
#if IS_ENABLED(CONFIG_NFS_FS)
......@@ -124,6 +151,15 @@ static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
#endif
}
static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
{
#if IS_ENABLED(CONFIG_SQUASHFS)
return sb->s_magic == SQUASHFS_MAGIC;
#else
return 0;
#endif
}
static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
{
#if IS_ENABLED(CONFIG_BTRFS_FS)
......@@ -233,5 +269,16 @@ static inline int au_test_fs_trunc_xino(struct super_block *sb)
|| au_test_ramfs(sb);
}
/*
* test if the @sb is real-readonly.
*/
static inline int au_test_fs_rr(struct super_block *sb)
{
return au_test_squashfs(sb)
|| au_test_iso9660(sb)
|| au_test_cramfs(sb)
|| au_test_romfs(sb);
}
#endif /* __KERNEL__ */
#endif /* __AUFS_FSTYPE_H__ */
......@@ -90,8 +90,8 @@ out:
static match_table_t brperm = {
{AuBrPerm_RO, AUFS_BRPERM_RO},
{AuBrPerm_RR, AUFS_BRPERM_RR},
{AuBrPerm_RW, AUFS_BRPERM_RW},
/* add more later */
{0, NULL}
};
......@@ -188,6 +188,7 @@ static int noinline_for_stack br_perm_val(char *perm)
bad = 0;
switch (val & AuBrPerm_Mask) {
case AuBrPerm_RO:
case AuBrPerm_RR:
bad = val & AuBrWAttr_Mask;
val &= ~AuBrWAttr_Mask;
break;
......@@ -333,7 +334,9 @@ static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
if (!err) {
if (!p) {
add->perm = AuBrPerm_RO;
if (!bindex && !(sb_flags & SB_RDONLY))
if (au_test_fs_rr(add->path.dentry->d_sb))
add->perm = AuBrPerm_RR;
else if (!bindex && !(sb_flags & SB_RDONLY))
add->perm = AuBrPerm_RW;
}
opt->type = Opt_add;
......
......@@ -96,12 +96,14 @@ typedef int16_t aufs_bindex_t;
/* branch permissions and attributes */
#define AUFS_BRPERM_RW "rw"
#define AUFS_BRPERM_RO "ro"
#define AUFS_BRPERM_RR "rr"
#define AUFS_BRRATTR_WH "wh"
#define AUFS_BRWATTR_NLWH "nolwh"
#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
#define AuBrPerm_RO (1 << 1) /* readonly */
#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO)
#define AuBrPerm_RR (1 << 2) /* natively readonly */
#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
#define AuBrRAttr_WH (1 << 7) /* whiteout-able */
#define AuBrRAttr_Mask AuBrRAttr_WH
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment