Statistics
| Branch: | Revision:

root / hw / virtio-9p-xattr.c @ fc22118d

History | View | Annotate | Download (3.6 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 "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

    
77
    /* Now fetch the xattr and find the actual size */
78
    orig_value = qemu_malloc(xattr_len);
79
    xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
80

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

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

    
109
err_out:
110
    qemu_free(orig_value_start);
111
    return size;
112
}
113

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

    
124
}
125

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

    
136
}
137

    
138
XattrOperations *mapped_xattr_ops[] = {
139
    &mapped_user_xattr,
140
    NULL,
141
};
142

    
143
XattrOperations *passthrough_xattr_ops[] = {
144
    &passthrough_user_xattr,
145
    NULL,
146
};
147

    
148
/* for .user none model should be same as passthrough */
149
XattrOperations *none_xattr_ops[] = {
150
    &passthrough_user_xattr,
151
    NULL,
152
};