diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
commit | 03dd4cb26d967f9588437b0fc9cc0e8353322bb7 (patch) | |
tree | fa581f6dc1c0596391690d1f67eceef3af8246dc /fs/aufs/sysfs.c | |
parent | d4e493caf788ef44982e131ff9c786546904d934 (diff) |
Linux-libre 4.5-gnu
Diffstat (limited to 'fs/aufs/sysfs.c')
-rw-r--r-- | fs/aufs/sysfs.c | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c deleted file mode 100644 index ed42f53d0..000000000 --- a/fs/aufs/sysfs.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2005-2016 Junjiro R. Okajima - */ - -/* - * sysfs interface - */ - -#include <linux/compat.h> -#include <linux/seq_file.h> -#include "aufs.h" - -static struct attribute *au_attr[] = { - NULL, /* need to NULL terminate the list of attributes */ -}; - -static struct attribute_group sysaufs_attr_group_body = { - .attrs = au_attr -}; - -struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; - -/* ---------------------------------------------------------------------- */ - -int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) -{ - int err; - - SiMustAnyLock(sb); - - err = 0; - if (au_opt_test(au_mntflags(sb), XINO)) { - err = au_xino_path(seq, au_sbi(sb)->si_xib); - seq_putc(seq, '\n'); - } - return err; -} - -/* - * the lifetime of branch is independent from the entry under sysfs. - * sysfs handles the lifetime of the entry, and never call ->show() after it is - * unlinked. - */ -static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, - aufs_bindex_t bindex, int idx) -{ - int err; - struct path path; - struct dentry *root; - struct au_branch *br; - au_br_perm_str_t perm; - - AuDbg("b%d\n", bindex); - - err = 0; - root = sb->s_root; - di_read_lock_parent(root, !AuLock_IR); - br = au_sbr(sb, bindex); - - switch (idx) { - case AuBrSysfs_BR: - path.mnt = au_br_mnt(br); - path.dentry = au_h_dptr(root, bindex); - err = au_seq_path(seq, &path); - if (!err) { - au_optstr_br_perm(&perm, br->br_perm); - seq_printf(seq, "=%s\n", perm.a); - } - break; - case AuBrSysfs_BRID: - seq_printf(seq, "%d\n", br->br_id); - break; - } - di_read_unlock(root, !AuLock_IR); - if (unlikely(err || seq_has_overflowed(seq))) - err = -E2BIG; - - return err; -} - -/* ---------------------------------------------------------------------- */ - -static struct seq_file *au_seq(char *p, ssize_t len) -{ - struct seq_file *seq; - - seq = kzalloc(sizeof(*seq), GFP_NOFS); - if (seq) { - /* mutex_init(&seq.lock); */ - seq->buf = p; - seq->size = len; - return seq; /* success */ - } - - seq = ERR_PTR(-ENOMEM); - return seq; -} - -#define SysaufsBr_PREFIX "br" -#define SysaufsBrid_PREFIX "brid" - -/* todo: file size may exceed PAGE_SIZE */ -ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - ssize_t err; - int idx; - long l; - aufs_bindex_t bend; - struct au_sbinfo *sbinfo; - struct super_block *sb; - struct seq_file *seq; - char *name; - struct attribute **cattr; - - sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); - sb = sbinfo->si_sb; - - /* - * prevent a race condition between sysfs and aufs. - * for instance, sysfs_file_read() calls sysfs_get_active_two() which - * prohibits maintaining the sysfs entries. - * hew we acquire read lock after sysfs_get_active_two(). - * on the other hand, the remount process may maintain the sysfs/aufs - * entries after acquiring write lock. - * it can cause a deadlock. - * simply we gave up processing read here. - */ - err = -EBUSY; - if (unlikely(!si_noflush_read_trylock(sb))) - goto out; - - seq = au_seq(buf, PAGE_SIZE); - err = PTR_ERR(seq); - if (IS_ERR(seq)) - goto out_unlock; - - name = (void *)attr->name; - cattr = sysaufs_si_attrs; - while (*cattr) { - if (!strcmp(name, (*cattr)->name)) { - err = container_of(*cattr, struct sysaufs_si_attr, attr) - ->show(seq, sb); - goto out_seq; - } - cattr++; - } - - if (!strncmp(name, SysaufsBrid_PREFIX, - sizeof(SysaufsBrid_PREFIX) - 1)) { - idx = AuBrSysfs_BRID; - name += sizeof(SysaufsBrid_PREFIX) - 1; - } else if (!strncmp(name, SysaufsBr_PREFIX, - sizeof(SysaufsBr_PREFIX) - 1)) { - idx = AuBrSysfs_BR; - name += sizeof(SysaufsBr_PREFIX) - 1; - } else - BUG(); - - err = kstrtol(name, 10, &l); - if (!err) { - bend = au_sbend(sb); - if (l <= bend) - err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx); - else - err = -ENOENT; - } - -out_seq: - if (!err) { - err = seq->count; - /* sysfs limit */ - if (unlikely(err == PAGE_SIZE)) - err = -EFBIG; - } - kfree(seq); -out_unlock: - si_read_unlock(sb); -out: - return err; -} - -/* ---------------------------------------------------------------------- */ - -static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg) -{ - int err; - int16_t brid; - aufs_bindex_t bindex, bend; - size_t sz; - char *buf; - struct seq_file *seq; - struct au_branch *br; - - si_read_lock(sb, AuLock_FLUSH); - bend = au_sbend(sb); - err = bend + 1; - if (!arg) - goto out; - - err = -ENOMEM; - buf = (void *)__get_free_page(GFP_NOFS); - if (unlikely(!buf)) - goto out; - - seq = au_seq(buf, PAGE_SIZE); - err = PTR_ERR(seq); - if (IS_ERR(seq)) - goto out_buf; - - sz = sizeof(*arg) - offsetof(union aufs_brinfo, path); - for (bindex = 0; bindex <= bend; bindex++, arg++) { - err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg)); - if (unlikely(err)) - break; - - br = au_sbr(sb, bindex); - brid = br->br_id; - BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id)); - err = __put_user(brid, &arg->id); - if (unlikely(err)) - break; - - BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm)); - err = __put_user(br->br_perm, &arg->perm); - if (unlikely(err)) - break; - - err = au_seq_path(seq, &br->br_path); - if (unlikely(err)) - break; - seq_putc(seq, '\0'); - if (!seq_has_overflowed(seq)) { - err = copy_to_user(arg->path, seq->buf, seq->count); - seq->count = 0; - if (unlikely(err)) - break; - } else { - err = -E2BIG; - goto out_seq; - } - } - if (unlikely(err)) - err = -EFAULT; - -out_seq: - kfree(seq); -out_buf: - free_page((unsigned long)buf); -out: - si_read_unlock(sb); - return err; -} - -long au_brinfo_ioctl(struct file *file, unsigned long arg) -{ - return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg); -} - -#ifdef CONFIG_COMPAT -long au_brinfo_compat_ioctl(struct file *file, unsigned long arg) -{ - return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg)); -} -#endif - -/* ---------------------------------------------------------------------- */ - -void sysaufs_br_init(struct au_branch *br) -{ - int i; - struct au_brsysfs *br_sysfs; - struct attribute *attr; - - br_sysfs = br->br_sysfs; - for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { - attr = &br_sysfs->attr; - sysfs_attr_init(attr); - attr->name = br_sysfs->name; - attr->mode = S_IRUGO; - br_sysfs++; - } -} - -void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) -{ - struct au_branch *br; - struct kobject *kobj; - struct au_brsysfs *br_sysfs; - int i; - aufs_bindex_t bend; - - dbgaufs_brs_del(sb, bindex); - - if (!sysaufs_brs) - return; - - kobj = &au_sbi(sb)->si_kobj; - bend = au_sbend(sb); - for (; bindex <= bend; bindex++) { - br = au_sbr(sb, bindex); - br_sysfs = br->br_sysfs; - for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { - sysfs_remove_file(kobj, &br_sysfs->attr); - br_sysfs++; - } - } -} - -void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) -{ - int err, i; - aufs_bindex_t bend; - struct kobject *kobj; - struct au_branch *br; - struct au_brsysfs *br_sysfs; - - dbgaufs_brs_add(sb, bindex); - - if (!sysaufs_brs) - return; - - kobj = &au_sbi(sb)->si_kobj; - bend = au_sbend(sb); - for (; bindex <= bend; bindex++) { - br = au_sbr(sb, bindex); - br_sysfs = br->br_sysfs; - snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name), - SysaufsBr_PREFIX "%d", bindex); - snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name), - SysaufsBrid_PREFIX "%d", bindex); - for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { - err = sysfs_create_file(kobj, &br_sysfs->attr); - if (unlikely(err)) - pr_warn("failed %s under sysfs(%d)\n", - br_sysfs->name, err); - br_sysfs++; - } - } -} |