Skip to content

Commit b17500a

Browse files
Gao Xianggregkh
Gao Xiang
authored andcommitted
staging: erofs: introduce xattr & acl support
This implements xattr and acl functionalities. Inline and shared xattrs are introduced for flexibility. Specifically, if the same xattr occurs for many times in a large number of inodes or the value of a xattr is so large that it isn't suitable to be inlined, a shared xattr kept in the xattr meta will be used instead. Signed-off-by: Miao Xie <[email protected]> Signed-off-by: Chao Yu <[email protected]> Signed-off-by: Gao Xiang <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent fd68c6a commit b17500a

File tree

8 files changed

+835
-1
lines changed

8 files changed

+835
-1
lines changed

drivers/staging/erofs/Kconfig

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,43 @@ config EROFS_FS_DEBUG
2626

2727
For daily use, say N.
2828

29+
config EROFS_FS_XATTR
30+
bool "EROFS extended attributes"
31+
depends on EROFS_FS
32+
default y
33+
help
34+
Extended attributes are name:value pairs associated with inodes by
35+
the kernel or by users (see the attr(5) manual page, or visit
36+
<http://acl.bestbits.at/> for details).
37+
38+
If unsure, say N.
39+
40+
config EROFS_FS_POSIX_ACL
41+
bool "EROFS Access Control Lists"
42+
depends on EROFS_FS_XATTR
43+
select FS_POSIX_ACL
44+
default y
45+
help
46+
Posix Access Control Lists (ACLs) support permissions for users and
47+
groups beyond the owner/group/world scheme.
48+
49+
To learn more about Access Control Lists, visit the POSIX ACLs for
50+
Linux website <http://acl.bestbits.at/>.
51+
52+
If you don't know what Access Control Lists are, say N.
53+
54+
config EROFS_FS_SECURITY
55+
bool "EROFS Security Labels"
56+
depends on EROFS_FS_XATTR
57+
help
58+
Security labels provide an access control facility to support Linux
59+
Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO
60+
Linux. This option enables an extended attribute handler for file
61+
security labels in the erofs filesystem, so that it requires enabling
62+
the extended attribute support in advance.
63+
64+
If you are not using a security module, say N.
65+
2966
config EROFS_FS_USE_VM_MAP_RAM
3067
bool "EROFS VM_MAP_RAM Support"
3168
depends on EROFS_FS

drivers/staging/erofs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ obj-$(CONFIG_EROFS_FS) += erofs.o
88
# staging requirement: to be self-contained in its own directory
99
ccflags-y += -I$(src)/include
1010
erofs-objs := super.o inode.o data.o namei.o dir.o
11+
erofs-$(CONFIG_EROFS_FS_XATTR) += xattr.o
1112

drivers/staging/erofs/inode.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* License. See the file COPYING in the main directory of the Linux
1111
* distribution for more details.
1212
*/
13-
#include "internal.h"
13+
#include "xattr.h"
1414

1515
/* no locking */
1616
static int read_inode(struct inode *inode, void *data)
@@ -152,15 +152,26 @@ static int fill_inode(struct inode *inode, int isdir)
152152
if (!err) {
153153
/* setup the new inode */
154154
if (S_ISREG(inode->i_mode)) {
155+
#ifdef CONFIG_EROFS_FS_XATTR
156+
if (vi->xattr_isize)
157+
inode->i_op = &erofs_generic_xattr_iops;
158+
#endif
155159
inode->i_fop = &generic_ro_fops;
156160
} else if (S_ISDIR(inode->i_mode)) {
157161
inode->i_op =
162+
#ifdef CONFIG_EROFS_FS_XATTR
163+
vi->xattr_isize ? &erofs_dir_xattr_iops :
164+
#endif
158165
&erofs_dir_iops;
159166
inode->i_fop = &erofs_dir_fops;
160167
} else if (S_ISLNK(inode->i_mode)) {
161168
/* by default, page_get_link is used for symlink */
162169
inode->i_op =
170+
#ifdef CONFIG_EROFS_FS_XATTR
171+
&erofs_symlink_xattr_iops,
172+
#else
163173
&page_symlink_inode_operations;
174+
#endif
164175
inode_nohighmem(inode);
165176
} else {
166177
err = -EIO;
@@ -208,3 +219,23 @@ struct inode *erofs_iget(struct super_block *sb,
208219
return inode;
209220
}
210221

222+
#ifdef CONFIG_EROFS_FS_XATTR
223+
const struct inode_operations erofs_generic_xattr_iops = {
224+
.listxattr = erofs_listxattr,
225+
};
226+
#endif
227+
228+
#ifdef CONFIG_EROFS_FS_XATTR
229+
const struct inode_operations erofs_symlink_xattr_iops = {
230+
.get_link = page_get_link,
231+
.listxattr = erofs_listxattr,
232+
};
233+
#endif
234+
235+
#ifdef CONFIG_EROFS_FS_XATTR
236+
const struct inode_operations erofs_fast_symlink_xattr_iops = {
237+
.get_link = simple_get_link,
238+
.listxattr = erofs_listxattr,
239+
};
240+
#endif
241+

drivers/staging/erofs/internal.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ typedef u64 erofs_nid_t;
5050
struct erofs_sb_info {
5151
u32 blocks;
5252
u32 meta_blkaddr;
53+
#ifdef CONFIG_EROFS_FS_XATTR
54+
u32 xattr_blkaddr;
55+
#endif
5356

5457
/* inode slot unit size in bit shift */
5558
unsigned char islotbits;
@@ -72,6 +75,10 @@ struct erofs_sb_info {
7275
#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
7376
#define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info)
7477

78+
/* Mount flags set via mount options or defaults */
79+
#define EROFS_MOUNT_XATTR_USER 0x00000010
80+
#define EROFS_MOUNT_POSIX_ACL 0x00000020
81+
7582
#define clear_opt(sbi, option) ((sbi)->mount_opt &= ~EROFS_MOUNT_##option)
7683
#define set_opt(sbi, option) ((sbi)->mount_opt |= EROFS_MOUNT_##option)
7784
#define test_opt(sbi, option) ((sbi)->mount_opt & EROFS_MOUNT_##option)
@@ -237,17 +244,32 @@ int erofs_namei(struct inode *dir, struct qstr *name,
237244
erofs_nid_t *nid, unsigned *d_type);
238245

239246
/* xattr.c */
247+
#ifdef CONFIG_EROFS_FS_XATTR
240248
extern const struct xattr_handler *erofs_xattr_handlers[];
249+
#endif
241250

242251
/* symlink */
252+
#ifdef CONFIG_EROFS_FS_XATTR
253+
extern const struct inode_operations erofs_symlink_xattr_iops;
254+
extern const struct inode_operations erofs_fast_symlink_xattr_iops;
255+
#endif
256+
243257
static inline void set_inode_fast_symlink(struct inode *inode)
244258
{
259+
#ifdef CONFIG_EROFS_FS_XATTR
260+
inode->i_op = &erofs_fast_symlink_xattr_iops;
261+
#else
245262
inode->i_op = &simple_symlink_inode_operations;
263+
#endif
246264
}
247265

248266
static inline bool is_inode_fast_symlink(struct inode *inode)
249267
{
268+
#ifdef CONFIG_EROFS_FS_XATTR
269+
return inode->i_op == &erofs_fast_symlink_xattr_iops;
270+
#else
250271
return inode->i_op == &simple_symlink_inode_operations;
272+
#endif
251273
}
252274

253275
static inline void *erofs_vmap(struct page **pages, unsigned int count)

drivers/staging/erofs/namei.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* distribution for more details.
1212
*/
1313
#include "internal.h"
14+
#include "xattr.h"
1415

1516
/* based on the value of qn->len is accurate */
1617
static inline int dirnamecmp(struct qstr *qn,
@@ -239,5 +240,8 @@ const struct inode_operations erofs_dir_iops = {
239240

240241
const struct inode_operations erofs_dir_xattr_iops = {
241242
.lookup = erofs_lookup,
243+
#ifdef CONFIG_EROFS_FS_XATTR
244+
.listxattr = erofs_listxattr,
245+
#endif
242246
};
243247

drivers/staging/erofs/super.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/buffer_head.h>
1515
#include <linux/statfs.h>
1616
#include <linux/parser.h>
17+
#include <linux/seq_file.h>
1718
#include "internal.h"
1819

1920
static struct kmem_cache *erofs_inode_cachep __read_mostly;
@@ -107,6 +108,9 @@ static int superblock_read(struct super_block *sb)
107108

108109
sbi->blocks = le32_to_cpu(layout->blocks);
109110
sbi->meta_blkaddr = le32_to_cpu(layout->meta_blkaddr);
111+
#ifdef CONFIG_EROFS_FS_XATTR
112+
sbi->xattr_blkaddr = le32_to_cpu(layout->xattr_blkaddr);
113+
#endif
110114
sbi->islotbits = ffs(sizeof(struct erofs_inode_v1)) - 1;
111115

112116
sbi->root_nid = le16_to_cpu(layout->root_nid);
@@ -127,13 +131,28 @@ static int superblock_read(struct super_block *sb)
127131

128132
static void default_options(struct erofs_sb_info *sbi)
129133
{
134+
#ifdef CONFIG_EROFS_FS_XATTR
135+
set_opt(sbi, XATTR_USER);
136+
#endif
137+
138+
#ifdef CONFIG_EROFS_FS_POSIX_ACL
139+
set_opt(sbi, POSIX_ACL);
140+
#endif
130141
}
131142

132143
enum {
144+
Opt_user_xattr,
145+
Opt_nouser_xattr,
146+
Opt_acl,
147+
Opt_noacl,
133148
Opt_err
134149
};
135150

136151
static match_table_t erofs_tokens = {
152+
{Opt_user_xattr, "user_xattr"},
153+
{Opt_nouser_xattr, "nouser_xattr"},
154+
{Opt_acl, "acl"},
155+
{Opt_noacl, "noacl"},
137156
{Opt_err, NULL}
138157
};
139158

@@ -155,6 +174,36 @@ static int parse_options(struct super_block *sb, char *options)
155174
token = match_token(p, erofs_tokens, args);
156175

157176
switch (token) {
177+
#ifdef CONFIG_EROFS_FS_XATTR
178+
case Opt_user_xattr:
179+
set_opt(EROFS_SB(sb), XATTR_USER);
180+
break;
181+
case Opt_nouser_xattr:
182+
clear_opt(EROFS_SB(sb), XATTR_USER);
183+
break;
184+
#else
185+
case Opt_user_xattr:
186+
infoln("user_xattr options not supported");
187+
break;
188+
case Opt_nouser_xattr:
189+
infoln("nouser_xattr options not supported");
190+
break;
191+
#endif
192+
#ifdef CONFIG_EROFS_FS_POSIX_ACL
193+
case Opt_acl:
194+
set_opt(EROFS_SB(sb), POSIX_ACL);
195+
break;
196+
case Opt_noacl:
197+
clear_opt(EROFS_SB(sb), POSIX_ACL);
198+
break;
199+
#else
200+
case Opt_acl:
201+
infoln("acl options not supported");
202+
break;
203+
case Opt_noacl:
204+
infoln("noacl options not supported");
205+
break;
206+
#endif
158207
default:
159208
errln("Unrecognized mount option \"%s\" "
160209
"or missing value", p);
@@ -197,6 +246,10 @@ static int erofs_read_super(struct super_block *sb,
197246

198247
sb->s_op = &erofs_sops;
199248

249+
#ifdef CONFIG_EROFS_FS_XATTR
250+
sb->s_xattr = erofs_xattr_handlers;
251+
#endif
252+
200253
/* set erofs default mount options */
201254
default_options(sbi);
202255

@@ -386,6 +439,20 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
386439

387440
static int erofs_show_options(struct seq_file *seq, struct dentry *root)
388441
{
442+
struct erofs_sb_info *sbi __maybe_unused = EROFS_SB(root->d_sb);
443+
444+
#ifdef CONFIG_EROFS_FS_XATTR
445+
if (test_opt(sbi, XATTR_USER))
446+
seq_puts(seq, ",user_xattr");
447+
else
448+
seq_puts(seq, ",nouser_xattr");
449+
#endif
450+
#ifdef CONFIG_EROFS_FS_POSIX_ACL
451+
if (test_opt(sbi, POSIX_ACL))
452+
seq_puts(seq, ",acl");
453+
else
454+
seq_puts(seq, ",noacl");
455+
#endif
389456
return 0;
390457
}
391458

0 commit comments

Comments
 (0)