|
|
1.1 ! root 1: /* ! 2: * Virtio 9p xattr callback ! 3: * ! 4: * Copyright IBM, Corp. 2010 ! 5: * ! 6: * Authors: ! 7: * Aneesh Kumar K.V <[email protected]> ! 8: * ! 9: * This work is licensed under the terms of the GNU GPL, version 2. See ! 10: * the COPYING file in the top-level directory. ! 11: * ! 12: */ ! 13: ! 14: #include "hw/virtio.h" ! 15: #include "virtio-9p.h" ! 16: #include "fsdev/file-op-9p.h" ! 17: #include "virtio-9p-xattr.h" ! 18: ! 19: ! 20: static XattrOperations *get_xattr_operations(XattrOperations **h, ! 21: const char *name) ! 22: { ! 23: XattrOperations *xops; ! 24: for (xops = *(h)++; xops != NULL; xops = *(h)++) { ! 25: if (!strncmp(name, xops->name, strlen(xops->name))) { ! 26: return xops; ! 27: } ! 28: } ! 29: return NULL; ! 30: } ! 31: ! 32: ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, ! 33: const char *name, void *value, size_t size) ! 34: { ! 35: XattrOperations *xops = get_xattr_operations(ctx->xops, name); ! 36: if (xops) { ! 37: return xops->getxattr(ctx, path, name, value, size); ! 38: } ! 39: errno = -EOPNOTSUPP; ! 40: return -1; ! 41: } ! 42: ! 43: ssize_t pt_listxattr(FsContext *ctx, const char *path, ! 44: char *name, void *value, size_t size) ! 45: { ! 46: int name_size = strlen(name) + 1; ! 47: if (!value) { ! 48: return name_size; ! 49: } ! 50: ! 51: if (size < name_size) { ! 52: errno = ERANGE; ! 53: return -1; ! 54: } ! 55: ! 56: strncpy(value, name, name_size); ! 57: return name_size; ! 58: } ! 59: ! 60: ! 61: /* ! 62: * Get the list and pass to each layer to find out whether ! 63: * to send the data or not ! 64: */ ! 65: ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, ! 66: void *value, size_t vsize) ! 67: { ! 68: ssize_t size = 0; ! 69: char buffer[PATH_MAX]; ! 70: void *ovalue = value; ! 71: XattrOperations *xops; ! 72: char *orig_value, *orig_value_start; ! 73: ssize_t xattr_len, parsed_len = 0, attr_len; ! 74: ! 75: /* Get the actual len */ ! 76: xattr_len = llistxattr(rpath(ctx, path, buffer), value, 0); ! 77: if (xattr_len <= 0) { ! 78: return xattr_len; ! 79: } ! 80: ! 81: /* Now fetch the xattr and find the actual size */ ! 82: orig_value = qemu_malloc(xattr_len); ! 83: xattr_len = llistxattr(rpath(ctx, path, buffer), orig_value, xattr_len); ! 84: ! 85: /* store the orig pointer */ ! 86: orig_value_start = orig_value; ! 87: while (xattr_len > parsed_len) { ! 88: xops = get_xattr_operations(ctx->xops, orig_value); ! 89: if (!xops) { ! 90: goto next_entry; ! 91: } ! 92: ! 93: if (!value) { ! 94: size += xops->listxattr(ctx, path, orig_value, value, vsize); ! 95: } else { ! 96: size = xops->listxattr(ctx, path, orig_value, value, vsize); ! 97: if (size < 0) { ! 98: goto err_out; ! 99: } ! 100: value += size; ! 101: vsize -= size; ! 102: } ! 103: next_entry: ! 104: /* Got the next entry */ ! 105: attr_len = strlen(orig_value) + 1; ! 106: parsed_len += attr_len; ! 107: orig_value += attr_len; ! 108: } ! 109: if (value) { ! 110: size = value - ovalue; ! 111: } ! 112: ! 113: err_out: ! 114: qemu_free(orig_value_start); ! 115: return size; ! 116: } ! 117: ! 118: int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, ! 119: void *value, size_t size, int flags) ! 120: { ! 121: XattrOperations *xops = get_xattr_operations(ctx->xops, name); ! 122: if (xops) { ! 123: return xops->setxattr(ctx, path, name, value, size, flags); ! 124: } ! 125: errno = -EOPNOTSUPP; ! 126: return -1; ! 127: ! 128: } ! 129: ! 130: int v9fs_remove_xattr(FsContext *ctx, ! 131: const char *path, const char *name) ! 132: { ! 133: XattrOperations *xops = get_xattr_operations(ctx->xops, name); ! 134: if (xops) { ! 135: return xops->removexattr(ctx, path, name); ! 136: } ! 137: errno = -EOPNOTSUPP; ! 138: return -1; ! 139: ! 140: } ! 141: ! 142: XattrOperations *mapped_xattr_ops[] = { ! 143: &mapped_user_xattr, ! 144: &mapped_pacl_xattr, ! 145: &mapped_dacl_xattr, ! 146: NULL, ! 147: }; ! 148: ! 149: XattrOperations *passthrough_xattr_ops[] = { ! 150: &passthrough_user_xattr, ! 151: &passthrough_acl_xattr, ! 152: NULL, ! 153: }; ! 154: ! 155: /* for .user none model should be same as passthrough */ ! 156: XattrOperations *none_xattr_ops[] = { ! 157: &passthrough_user_xattr, ! 158: &none_acl_xattr, ! 159: NULL, ! 160: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.