2 * Copyright (C) 2005-2012 Junjiro R. Okajima
4 * This program, aufs is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <linux/seq_file.h>
26 #ifdef CONFIG_AUFS_FS_MODULE
27 /* this entry violates the "one line per file" policy of sysfs */
28 static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
33 /* this file is generated at compiling */
37 err = snprintf(buf, PAGE_SIZE, conf);
38 if (unlikely(err >= PAGE_SIZE))
43 static struct kobj_attribute au_config_attr = __ATTR_RO(config);
46 static struct attribute *au_attr[] = {
47 #ifdef CONFIG_AUFS_FS_MODULE
50 NULL, /* need to NULL terminate the list of attributes */
53 static struct attribute_group sysaufs_attr_group_body = {
57 struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
59 /* ---------------------------------------------------------------------- */
61 int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
68 if (au_opt_test(au_mntflags(sb), XINO)) {
69 err = au_xino_path(seq, au_sbi(sb)->si_xib);
76 * the lifetime of branch is independent from the entry under sysfs.
77 * sysfs handles the lifetime of the entry, and never call ->show() after it is
80 static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
89 AuDbg("b%d\n", bindex);
93 di_read_lock_parent(root, !AuLock_IR);
94 br = au_sbr(sb, bindex);
95 path.mnt = br->br_mnt;
96 path.dentry = au_h_dptr(root, bindex);
97 au_seq_path(seq, &path);
98 di_read_unlock(root, !AuLock_IR);
99 perm = au_optstr_br_perm(br->br_perm);
101 err = seq_printf(seq, "=%s\n", perm);
110 /* ---------------------------------------------------------------------- */
112 static struct seq_file *au_seq(char *p, ssize_t len)
114 struct seq_file *seq;
116 seq = kzalloc(sizeof(*seq), GFP_NOFS);
118 /* mutex_init(&seq.lock); */
121 return seq; /* success */
124 seq = ERR_PTR(-ENOMEM);
128 #define SysaufsBr_PREFIX "br"
130 /* todo: file size may exceed PAGE_SIZE */
131 ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
137 struct au_sbinfo *sbinfo;
138 struct super_block *sb;
139 struct seq_file *seq;
141 struct attribute **cattr;
143 sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
147 * prevent a race condition between sysfs and aufs.
148 * for instance, sysfs_file_read() calls sysfs_get_active_two() which
149 * prohibits maintaining the sysfs entries.
150 * hew we acquire read lock after sysfs_get_active_two().
151 * on the other hand, the remount process may maintain the sysfs/aufs
152 * entries after acquiring write lock.
153 * it can cause a deadlock.
154 * simply we gave up processing read here.
157 if (unlikely(!si_noflush_read_trylock(sb)))
160 seq = au_seq(buf, PAGE_SIZE);
165 name = (void *)attr->name;
166 cattr = sysaufs_si_attrs;
168 if (!strcmp(name, (*cattr)->name)) {
169 err = container_of(*cattr, struct sysaufs_si_attr, attr)
177 if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
178 name += sizeof(SysaufsBr_PREFIX) - 1;
179 err = kstrtol(name, 10, &l);
182 err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
194 if (unlikely(err == PAGE_SIZE))
204 /* ---------------------------------------------------------------------- */
206 void sysaufs_br_init(struct au_branch *br)
208 struct attribute *attr = &br->br_attr;
210 sysfs_attr_init(attr);
211 attr->name = br->br_name;
212 attr->mode = S_IRUGO;
215 void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
217 struct au_branch *br;
218 struct kobject *kobj;
221 dbgaufs_brs_del(sb, bindex);
226 kobj = &au_sbi(sb)->si_kobj;
228 for (; bindex <= bend; bindex++) {
229 br = au_sbr(sb, bindex);
230 sysfs_remove_file(kobj, &br->br_attr);
234 void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
238 struct kobject *kobj;
239 struct au_branch *br;
241 dbgaufs_brs_add(sb, bindex);
246 kobj = &au_sbi(sb)->si_kobj;
248 for (; bindex <= bend; bindex++) {
249 br = au_sbr(sb, bindex);
250 snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
252 err = sysfs_create_file(kobj, &br->br_attr);
254 pr_warning("failed %s under sysfs(%d)\n",