~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to hw/9pfs/virtio-9p-xattr.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "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 = g_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
    g_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
};