Statistics
| Branch: | Revision:

root / hw / 9pfs / virtio-9p-xattr.c @ 353ac78d

History | View | Annotate | Download (3.8 kB)

1
/*
2
 * Virtio 9p  xattr callback
3
 *
4
 * Copyright IBM, Corp. 2010
5
 *
6
 * Authors:
7
 * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
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 "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
    void *ovalue = value;
70
    XattrOperations *xops;
71
    char *orig_value, *orig_value_start;
72
    ssize_t xattr_len, parsed_len = 0, attr_len;
73

    
74
    /* Get the actual len */
75
    xattr_len = llistxattr(rpath(ctx, path), value, 0);
76
    if (xattr_len <= 0) {
77
        return xattr_len;
78
    }
79

    
80
    /* Now fetch the xattr and find the actual size */
81
    orig_value = qemu_malloc(xattr_len);
82
    xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
83

    
84
    /* store the orig pointer */
85
    orig_value_start = orig_value;
86
    while (xattr_len > parsed_len) {
87
        xops = get_xattr_operations(ctx->xops, orig_value);
88
        if (!xops) {
89
            goto next_entry;
90
        }
91

    
92
        if (!value) {
93
            size += xops->listxattr(ctx, path, orig_value, value, vsize);
94
        } else {
95
            size = xops->listxattr(ctx, path, orig_value, value, vsize);
96
            if (size < 0) {
97
                goto err_out;
98
            }
99
            value += size;
100
            vsize -= size;
101
        }
102
next_entry:
103
        /* Got the next entry */
104
        attr_len = strlen(orig_value) + 1;
105
        parsed_len += attr_len;
106
        orig_value += attr_len;
107
    }
108
    if (value) {
109
        size = value - ovalue;
110
    }
111

    
112
err_out:
113
    qemu_free(orig_value_start);
114
    return size;
115
}
116

    
117
int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
118
                   void *value, size_t size, int flags)
119
{
120
    XattrOperations *xops = get_xattr_operations(ctx->xops, name);
121
    if (xops) {
122
        return xops->setxattr(ctx, path, name, value, size, flags);
123
    }
124
    errno = -EOPNOTSUPP;
125
    return -1;
126

    
127
}
128

    
129
int v9fs_remove_xattr(FsContext *ctx,
130
                      const char *path, const char *name)
131
{
132
    XattrOperations *xops = get_xattr_operations(ctx->xops, name);
133
    if (xops) {
134
        return xops->removexattr(ctx, path, name);
135
    }
136
    errno = -EOPNOTSUPP;
137
    return -1;
138

    
139
}
140

    
141
XattrOperations *mapped_xattr_ops[] = {
142
    &mapped_user_xattr,
143
    &mapped_pacl_xattr,
144
    &mapped_dacl_xattr,
145
    NULL,
146
};
147

    
148
XattrOperations *passthrough_xattr_ops[] = {
149
    &passthrough_user_xattr,
150
    &passthrough_acl_xattr,
151
    NULL,
152
};
153

    
154
/* for .user none model should be same as passthrough */
155
XattrOperations *none_xattr_ops[] = {
156
    &passthrough_user_xattr,
157
    &none_acl_xattr,
158
    NULL,
159
};