^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * JFFS2 -- Journalling Flash File System, Version 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright © 2006 NEC Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * For licensing information, see the file 'LICENCE' in this directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/jffs2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/posix_acl_xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mtd/mtd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "nodelist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static size_t jffs2_acl_size(int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (count <= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return sizeof(struct jffs2_acl_header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) + count * sizeof(struct jffs2_acl_entry_short);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return sizeof(struct jffs2_acl_header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) + 4 * sizeof(struct jffs2_acl_entry_short)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) + (count - 4) * sizeof(struct jffs2_acl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int jffs2_acl_count(size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) size_t s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) size -= sizeof(struct jffs2_acl_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (size < 4 * sizeof(struct jffs2_acl_entry_short)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (size % sizeof(struct jffs2_acl_entry_short))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return size / sizeof(struct jffs2_acl_entry_short);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) s = size - 4 * sizeof(struct jffs2_acl_entry_short);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (s % sizeof(struct jffs2_acl_entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return s / sizeof(struct jffs2_acl_entry) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static struct posix_acl *jffs2_acl_from_medium(void *value, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void *end = value + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct jffs2_acl_header *header = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct jffs2_acl_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct posix_acl *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) uint32_t ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int i, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (size < sizeof(struct jffs2_acl_header))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ver = je32_to_cpu(header->a_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (ver != JFFS2_ACL_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) JFFS2_WARNING("Invalid ACL version. (=%u)\n", ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) value += sizeof(struct jffs2_acl_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) count = jffs2_acl_count(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) acl = posix_acl_alloc(count, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) for (i=0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) entry = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (value + sizeof(struct jffs2_acl_entry_short) > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) acl->a_entries[i].e_tag = je16_to_cpu(entry->e_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) acl->a_entries[i].e_perm = je16_to_cpu(entry->e_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) switch (acl->a_entries[i].e_tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case ACL_USER_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case ACL_GROUP_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case ACL_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case ACL_OTHER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) value += sizeof(struct jffs2_acl_entry_short);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) case ACL_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) value += sizeof(struct jffs2_acl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (value > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) acl->a_entries[i].e_uid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) make_kuid(&init_user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) je32_to_cpu(entry->e_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case ACL_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) value += sizeof(struct jffs2_acl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (value > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) acl->a_entries[i].e_gid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) make_kgid(&init_user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) je32_to_cpu(entry->e_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (value != end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) posix_acl_release(acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct jffs2_acl_header *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct jffs2_acl_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) void *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *size = jffs2_acl_size(acl->a_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) header = kmalloc(struct_size(header, a_entries, acl->a_count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (!header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) header->a_version = cpu_to_je32(JFFS2_ACL_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) e = header + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) for (i=0; i < acl->a_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) const struct posix_acl_entry *acl_e = &acl->a_entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) entry = e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) entry->e_tag = cpu_to_je16(acl_e->e_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) entry->e_perm = cpu_to_je16(acl_e->e_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) switch(acl_e->e_tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case ACL_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) entry->e_id = cpu_to_je32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) from_kuid(&init_user_ns, acl_e->e_uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) e += sizeof(struct jffs2_acl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case ACL_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) entry->e_id = cpu_to_je32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) from_kgid(&init_user_ns, acl_e->e_gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) e += sizeof(struct jffs2_acl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case ACL_USER_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case ACL_GROUP_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case ACL_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case ACL_OTHER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) e += sizeof(struct jffs2_acl_entry_short);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) kfree(header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct posix_acl *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) char *value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int rc, xprefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case ACL_TYPE_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) xprefix = JFFS2_XPREFIX_ACL_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case ACL_TYPE_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (rc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) value = kmalloc(rc, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) rc = do_jffs2_getxattr(inode, xprefix, "", value, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (rc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) acl = jffs2_acl_from_medium(value, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) } else if (rc == -ENODATA || rc == -ENOSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) acl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) acl = ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) kfree(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) char *value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) size_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) value = jffs2_acl_to_medium(acl, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (IS_ERR(value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return PTR_ERR(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (!value && rc == -ENODATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) kfree(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int rc, xprefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case ACL_TYPE_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) xprefix = JFFS2_XPREFIX_ACL_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) umode_t mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rc = posix_acl_update_mode(inode, &mode, &acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (inode->i_mode != mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct iattr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) attr.ia_valid = ATTR_MODE | ATTR_CTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) attr.ia_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) attr.ia_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rc = jffs2_do_setattr(inode, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case ACL_TYPE_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return acl ? -EACCES : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) rc = __jffs2_set_acl(inode, xprefix, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) set_cached_acl(inode, type, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct posix_acl *default_acl, *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) cache_no_acl(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) rc = posix_acl_create(dir_i, i_mode, &default_acl, &acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (default_acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) posix_acl_release(default_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) posix_acl_release(acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int jffs2_init_acl_post(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (inode->i_default_acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (inode->i_acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }