Commit 40b78a322365aa1d87770200f7fc7de3b361c11a

Authored by Steven Whitehouse
1 parent b6ed2e03df

GFS2: Clean up of extended attribute support

This has been on my list for some time. We need to change the way
in which we handle extended attributes to allow faster file creation
times (by reducing the number of transactions required) and the
extended attribute code is the main obstacle to this.

In addition to that, the VFS provides a way to demultiplex the xattr
calls which we ought to be using, rather than rolling our own. This
patch changes the GFS2 code to use that VFS feature and as a result
the code shrinks by a couple of hundred lines or so, and becomes
easier to read.

I'm planning on doing further clean up work in this area, but this
patch is a good start. The cleaned up code also uses the more usual
"xattr" shorthand, I plan to eliminate the use of "eattr" eventually
and in the mean time it serves as a flag as to which bits of the code
have been updated.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

Showing 11 changed files with 333 additions and 526 deletions Side-by-side Diff

1 1 EXTRA_CFLAGS := -I$(src)
2 2 obj-$(CONFIG_GFS2_FS) += gfs2.o
3   -gfs2-y := acl.o bmap.o dir.o eaops.o eattr.o glock.o \
  3 +gfs2-y := acl.o bmap.o dir.o eattr.o glock.o \
4 4 glops.o inode.o log.o lops.o main.o meta_io.o \
5 5 aops.o dentry.o export.o file.o \
6 6 ops_fstype.o ops_inode.o quota.o \
... ... @@ -19,7 +19,6 @@
19 19 #include "gfs2.h"
20 20 #include "incore.h"
21 21 #include "acl.h"
22   -#include "eaops.h"
23 22 #include "eattr.h"
24 23 #include "glock.h"
25 24 #include "inode.h"
... ... @@ -31,8 +30,7 @@
31 30 #define ACL_DEFAULT 0
32 31  
33 32 int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
34   - struct gfs2_ea_request *er,
35   - int *remove, mode_t *mode)
  33 + struct gfs2_ea_request *er, int *remove, mode_t *mode)
36 34 {
37 35 struct posix_acl *acl;
38 36 int error;
39 37  
40 38  
41 39  
... ... @@ -83,30 +81,20 @@
83 81 return 0;
84 82 }
85 83  
86   -static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl,
87   - struct gfs2_ea_location *el, char **data, unsigned int *len)
  84 +static int acl_get(struct gfs2_inode *ip, const char *name,
  85 + struct posix_acl **acl, struct gfs2_ea_location *el,
  86 + char **datap, unsigned int *lenp)
88 87 {
89   - struct gfs2_ea_request er;
90   - struct gfs2_ea_location el_this;
  88 + char *data;
  89 + unsigned int len;
91 90 int error;
92 91  
  92 + el->el_bh = NULL;
  93 +
93 94 if (!ip->i_eattr)
94 95 return 0;
95 96  
96   - memset(&er, 0, sizeof(struct gfs2_ea_request));
97   - if (access) {
98   - er.er_name = GFS2_POSIX_ACL_ACCESS;
99   - er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN;
100   - } else {
101   - er.er_name = GFS2_POSIX_ACL_DEFAULT;
102   - er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN;
103   - }
104   - er.er_type = GFS2_EATYPE_SYS;
105   -
106   - if (!el)
107   - el = &el_this;
108   -
109   - error = gfs2_ea_find(ip, &er, el);
  97 + error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, el);
110 98 if (error)
111 99 return error;
112 100 if (!el->el_ea)
113 101  
114 102  
115 103  
116 104  
117 105  
118 106  
... ... @@ -114,32 +102,31 @@
114 102 if (!GFS2_EA_DATA_LEN(el->el_ea))
115 103 goto out;
116 104  
117   - er.er_data_len = GFS2_EA_DATA_LEN(el->el_ea);
118   - er.er_data = kmalloc(er.er_data_len, GFP_NOFS);
  105 + len = GFS2_EA_DATA_LEN(el->el_ea);
  106 + data = kmalloc(len, GFP_NOFS);
119 107 error = -ENOMEM;
120   - if (!er.er_data)
  108 + if (!data)
121 109 goto out;
122 110  
123   - error = gfs2_ea_get_copy(ip, el, er.er_data);
124   - if (error)
  111 + error = gfs2_ea_get_copy(ip, el, data, len);
  112 + if (error < 0)
125 113 goto out_kfree;
  114 + error = 0;
126 115  
127 116 if (acl) {
128   - *acl = posix_acl_from_xattr(er.er_data, er.er_data_len);
  117 + *acl = posix_acl_from_xattr(data, len);
129 118 if (IS_ERR(*acl))
130 119 error = PTR_ERR(*acl);
131 120 }
132 121  
133 122 out_kfree:
134   - if (error || !data)
135   - kfree(er.er_data);
136   - else {
137   - *data = er.er_data;
138   - *len = er.er_data_len;
  123 + if (error || !datap) {
  124 + kfree(data);
  125 + } else {
  126 + *datap = data;
  127 + *lenp = len;
139 128 }
140 129 out:
141   - if (error || el == &el_this)
142   - brelse(el->el_bh);
143 130 return error;
144 131 }
145 132  
146 133  
... ... @@ -153,10 +140,12 @@
153 140  
154 141 int gfs2_check_acl(struct inode *inode, int mask)
155 142 {
  143 + struct gfs2_ea_location el;
156 144 struct posix_acl *acl = NULL;
157 145 int error;
158 146  
159   - error = acl_get(GFS2_I(inode), ACL_ACCESS, &acl, NULL, NULL, NULL);
  147 + error = acl_get(GFS2_I(inode), GFS2_POSIX_ACL_ACCESS, &acl, &el, NULL, NULL);
  148 + brelse(el.el_bh);
160 149 if (error)
161 150 return error;
162 151  
163 152  
164 153  
... ... @@ -196,10 +185,12 @@
196 185  
197 186 int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
198 187 {
  188 + struct gfs2_ea_location el;
199 189 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
200 190 struct posix_acl *acl = NULL, *clone;
201   - struct gfs2_ea_request er;
202 191 mode_t mode = ip->i_inode.i_mode;
  192 + char *data = NULL;
  193 + unsigned int len;
203 194 int error;
204 195  
205 196 if (!sdp->sd_args.ar_posix_acl)
... ... @@ -207,11 +198,8 @@
207 198 if (S_ISLNK(ip->i_inode.i_mode))
208 199 return 0;
209 200  
210   - memset(&er, 0, sizeof(struct gfs2_ea_request));
211   - er.er_type = GFS2_EATYPE_SYS;
212   -
213   - error = acl_get(dip, ACL_DEFAULT, &acl, NULL,
214   - &er.er_data, &er.er_data_len);
  201 + error = acl_get(dip, GFS2_POSIX_ACL_DEFAULT, &acl, &el, &data, &len);
  202 + brelse(el.el_bh);
215 203 if (error)
216 204 return error;
217 205 if (!acl) {
... ... @@ -229,9 +217,8 @@
229 217 acl = clone;
230 218  
231 219 if (S_ISDIR(ip->i_inode.i_mode)) {
232   - er.er_name = GFS2_POSIX_ACL_DEFAULT;
233   - er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN;
234   - error = gfs2_system_eaops.eo_set(ip, &er);
  220 + error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
  221 + GFS2_POSIX_ACL_DEFAULT, data, len, 0);
235 222 if (error)
236 223 goto out;
237 224 }
238 225  
239 226  
... ... @@ -239,21 +226,19 @@
239 226 error = posix_acl_create_masq(acl, &mode);
240 227 if (error < 0)
241 228 goto out;
242   - if (error > 0) {
243   - er.er_name = GFS2_POSIX_ACL_ACCESS;
244   - er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN;
245   - posix_acl_to_xattr(acl, er.er_data, er.er_data_len);
246   - er.er_mode = mode;
247   - er.er_flags = GFS2_ERF_MODE;
248   - error = gfs2_system_eaops.eo_set(ip, &er);
249   - if (error)
250   - goto out;
251   - } else
252   - munge_mode(ip, mode);
  229 + if (error == 0)
  230 + goto munge;
253 231  
  232 + posix_acl_to_xattr(acl, data, len);
  233 + error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
  234 + GFS2_POSIX_ACL_ACCESS, data, len, 0);
  235 + if (error)
  236 + goto out;
  237 +munge:
  238 + error = munge_mode(ip, mode);
254 239 out:
255 240 posix_acl_release(acl);
256   - kfree(er.er_data);
  241 + kfree(data);
257 242 return error;
258 243 }
259 244  
260 245  
... ... @@ -265,9 +250,9 @@
265 250 unsigned int len;
266 251 int error;
267 252  
268   - error = acl_get(ip, ACL_ACCESS, &acl, &el, &data, &len);
  253 + error = acl_get(ip, GFS2_POSIX_ACL_ACCESS, &acl, &el, &data, &len);
269 254 if (error)
270   - return error;
  255 + goto out_brelse;
271 256 if (!acl)
272 257 return gfs2_setattr_simple(ip, attr);
273 258  
274 259  
... ... @@ -286,8 +271,9 @@
286 271  
287 272 out:
288 273 posix_acl_release(acl);
289   - brelse(el.el_bh);
290 274 kfree(data);
  275 +out_brelse:
  276 + brelse(el.el_bh);
291 277 return error;
292 278 }
fs/gfs2/eaops.c
1   -/*
2   - * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3   - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4   - *
5   - * This copyrighted material is made available to anyone wishing to use,
6   - * modify, copy, or redistribute it subject to the terms and conditions
7   - * of the GNU General Public License version 2.
8   - */
9   -
10   -#include <linux/slab.h>
11   -#include <linux/spinlock.h>
12   -#include <linux/completion.h>
13   -#include <linux/buffer_head.h>
14   -#include <linux/capability.h>
15   -#include <linux/xattr.h>
16   -#include <linux/gfs2_ondisk.h>
17   -#include <asm/uaccess.h>
18   -
19   -#include "gfs2.h"
20   -#include "incore.h"
21   -#include "acl.h"
22   -#include "eaops.h"
23   -#include "eattr.h"
24   -#include "util.h"
25   -
26   -/**
27   - * gfs2_ea_name2type - get the type of the ea, and truncate type from the name
28   - * @namep: ea name, possibly with type appended
29   - *
30   - * Returns: GFS2_EATYPE_XXX
31   - */
32   -
33   -unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name)
34   -{
35   - unsigned int type;
36   -
37   - if (strncmp(name, "system.", 7) == 0) {
38   - type = GFS2_EATYPE_SYS;
39   - if (truncated_name)
40   - *truncated_name = name + sizeof("system.") - 1;
41   - } else if (strncmp(name, "user.", 5) == 0) {
42   - type = GFS2_EATYPE_USR;
43   - if (truncated_name)
44   - *truncated_name = name + sizeof("user.") - 1;
45   - } else if (strncmp(name, "security.", 9) == 0) {
46   - type = GFS2_EATYPE_SECURITY;
47   - if (truncated_name)
48   - *truncated_name = name + sizeof("security.") - 1;
49   - } else {
50   - type = GFS2_EATYPE_UNUSED;
51   - if (truncated_name)
52   - *truncated_name = NULL;
53   - }
54   -
55   - return type;
56   -}
57   -
58   -static int system_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
59   -{
60   - if (!GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) &&
61   - !GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len) &&
62   - !capable(CAP_SYS_ADMIN))
63   - return -EPERM;
64   -
65   - if (GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl == 0 &&
66   - (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
67   - GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
68   - return -EOPNOTSUPP;
69   -
70   - return gfs2_ea_get_i(ip, er);
71   -}
72   -
73   -static int system_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
74   -{
75   - int remove = 0;
76   - int error;
77   -
78   - if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
79   - if (!(er->er_flags & GFS2_ERF_MODE)) {
80   - er->er_mode = ip->i_inode.i_mode;
81   - er->er_flags |= GFS2_ERF_MODE;
82   - }
83   - error = gfs2_acl_validate_set(ip, 1, er,
84   - &remove, &er->er_mode);
85   - if (error)
86   - return error;
87   - error = gfs2_ea_set_i(ip, er);
88   - if (error)
89   - return error;
90   - if (remove)
91   - gfs2_ea_remove_i(ip, er);
92   - return 0;
93   -
94   - } else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
95   - error = gfs2_acl_validate_set(ip, 0, er,
96   - &remove, NULL);
97   - if (error)
98   - return error;
99   - if (!remove)
100   - error = gfs2_ea_set_i(ip, er);
101   - else {
102   - error = gfs2_ea_remove_i(ip, er);
103   - if (error == -ENODATA)
104   - error = 0;
105   - }
106   - return error;
107   - }
108   -
109   - return -EPERM;
110   -}
111   -
112   -static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
113   -{
114   - if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
115   - int error = gfs2_acl_validate_remove(ip, 1);
116   - if (error)
117   - return error;
118   -
119   - } else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
120   - int error = gfs2_acl_validate_remove(ip, 0);
121   - if (error)
122   - return error;
123   -
124   - } else
125   - return -EPERM;
126   -
127   - return gfs2_ea_remove_i(ip, er);
128   -}
129   -
130   -static const struct gfs2_eattr_operations gfs2_user_eaops = {
131   - .eo_get = gfs2_ea_get_i,
132   - .eo_set = gfs2_ea_set_i,
133   - .eo_remove = gfs2_ea_remove_i,
134   - .eo_name = "user",
135   -};
136   -
137   -const struct gfs2_eattr_operations gfs2_system_eaops = {
138   - .eo_get = system_eo_get,
139   - .eo_set = system_eo_set,
140   - .eo_remove = system_eo_remove,
141   - .eo_name = "system",
142   -};
143   -
144   -static const struct gfs2_eattr_operations gfs2_security_eaops = {
145   - .eo_get = gfs2_ea_get_i,
146   - .eo_set = gfs2_ea_set_i,
147   - .eo_remove = gfs2_ea_remove_i,
148   - .eo_name = "security",
149   -};
150   -
151   -const struct gfs2_eattr_operations *gfs2_ea_ops[] = {
152   - NULL,
153   - &gfs2_user_eaops,
154   - &gfs2_system_eaops,
155   - &gfs2_security_eaops,
156   -};
fs/gfs2/eaops.h
1   -/*
2   - * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3   - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4   - *
5   - * This copyrighted material is made available to anyone wishing to use,
6   - * modify, copy, or redistribute it subject to the terms and conditions
7   - * of the GNU General Public License version 2.
8   - */
9   -
10   -#ifndef __EAOPS_DOT_H__
11   -#define __EAOPS_DOT_H__
12   -
13   -struct gfs2_ea_request;
14   -struct gfs2_inode;
15   -
16   -struct gfs2_eattr_operations {
17   - int (*eo_get) (struct gfs2_inode *ip, struct gfs2_ea_request *er);
18   - int (*eo_set) (struct gfs2_inode *ip, struct gfs2_ea_request *er);
19   - int (*eo_remove) (struct gfs2_inode *ip, struct gfs2_ea_request *er);
20   - char *eo_name;
21   -};
22   -
23   -unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name);
24   -
25   -extern const struct gfs2_eattr_operations gfs2_system_eaops;
26   -
27   -extern const struct gfs2_eattr_operations *gfs2_ea_ops[];
28   -
29   -#endif /* __EAOPS_DOT_H__ */
... ... @@ -18,7 +18,6 @@
18 18 #include "gfs2.h"
19 19 #include "incore.h"
20 20 #include "acl.h"
21   -#include "eaops.h"
22 21 #include "eattr.h"
23 22 #include "glock.h"
24 23 #include "inode.h"
25 24  
26 25  
27 26  
28 27  
29 28  
... ... @@ -38,26 +37,32 @@
38 37 * Returns: 1 if the EA should be stuffed
39 38 */
40 39  
41   -static int ea_calc_size(struct gfs2_sbd *sdp, struct gfs2_ea_request *er,
  40 +static int ea_calc_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize,
42 41 unsigned int *size)
43 42 {
44   - *size = GFS2_EAREQ_SIZE_STUFFED(er);
45   - if (*size <= sdp->sd_jbsize)
  43 + unsigned int jbsize = sdp->sd_jbsize;
  44 +
  45 + /* Stuffed */
  46 + *size = ALIGN(sizeof(struct gfs2_ea_header) + nsize + dsize, 8);
  47 +
  48 + if (*size <= jbsize)
46 49 return 1;
47 50  
48   - *size = GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er);
  51 + /* Unstuffed */
  52 + *size = ALIGN(sizeof(struct gfs2_ea_header) + nsize +
  53 + (sizeof(__be64) * DIV_ROUND_UP(dsize, jbsize)), 8);
49 54  
50 55 return 0;
51 56 }
52 57  
53   -static int ea_check_size(struct gfs2_sbd *sdp, struct gfs2_ea_request *er)
  58 +static int ea_check_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize)
54 59 {
55 60 unsigned int size;
56 61  
57   - if (er->er_data_len > GFS2_EA_MAX_DATA_LEN)
  62 + if (dsize > GFS2_EA_MAX_DATA_LEN)
58 63 return -ERANGE;
59 64  
60   - ea_calc_size(sdp, er, &size);
  65 + ea_calc_size(sdp, nsize, dsize, &size);
61 66  
62 67 /* This can only happen with 512 byte blocks */
63 68 if (size > sdp->sd_jbsize)
... ... @@ -151,7 +156,9 @@
151 156 }
152 157  
153 158 struct ea_find {
154   - struct gfs2_ea_request *ef_er;
  159 + int type;
  160 + const char *name;
  161 + size_t namel;
155 162 struct gfs2_ea_location *ef_el;
156 163 };
157 164  
158 165  
... ... @@ -160,14 +167,13 @@
160 167 void *private)
161 168 {
162 169 struct ea_find *ef = private;
163   - struct gfs2_ea_request *er = ef->ef_er;
164 170  
165 171 if (ea->ea_type == GFS2_EATYPE_UNUSED)
166 172 return 0;
167 173  
168   - if (ea->ea_type == er->er_type) {
169   - if (ea->ea_name_len == er->er_name_len &&
170   - !memcmp(GFS2_EA2NAME(ea), er->er_name, ea->ea_name_len)) {
  174 + if (ea->ea_type == ef->type) {
  175 + if (ea->ea_name_len == ef->namel &&
  176 + !memcmp(GFS2_EA2NAME(ea), ef->name, ea->ea_name_len)) {
171 177 struct gfs2_ea_location *el = ef->ef_el;
172 178 get_bh(bh);
173 179 el->el_bh = bh;
174 180  
... ... @@ -180,13 +186,15 @@
180 186 return 0;
181 187 }
182 188  
183   -int gfs2_ea_find(struct gfs2_inode *ip, struct gfs2_ea_request *er,
  189 +int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
184 190 struct gfs2_ea_location *el)
185 191 {
186 192 struct ea_find ef;
187 193 int error;
188 194  
189   - ef.ef_er = er;
  195 + ef.type = type;
  196 + ef.name = name;
  197 + ef.namel = strlen(name);
190 198 ef.ef_el = el;
191 199  
192 200 memset(el, 0, sizeof(struct gfs2_ea_location));
... ... @@ -344,6 +352,20 @@
344 352 unsigned int ei_size;
345 353 };
346 354  
  355 +static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea)
  356 +{
  357 + switch (ea->ea_type) {
  358 + case GFS2_EATYPE_USR:
  359 + return 5 + ea->ea_name_len + 1;
  360 + case GFS2_EATYPE_SYS:
  361 + return 7 + ea->ea_name_len + 1;
  362 + case GFS2_EATYPE_SECURITY:
  363 + return 9 + ea->ea_name_len + 1;
  364 + default:
  365 + return 0;
  366 + }
  367 +}
  368 +
347 369 static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
348 370 struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
349 371 void *private)
350 372  
351 373  
352 374  
... ... @@ -392,21 +414,25 @@
392 414 }
393 415  
394 416 /**
395   - * gfs2_ea_list -
396   - * @ip:
397   - * @er:
  417 + * gfs2_listxattr - List gfs2 extended attributes
  418 + * @dentry: The dentry whose inode we are interested in
  419 + * @buffer: The buffer to write the results
  420 + * @size: The size of the buffer
398 421 *
399 422 * Returns: actual size of data on success, -errno on error
400 423 */
401 424  
402   -int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er)
  425 +ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
403 426 {
  427 + struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
  428 + struct gfs2_ea_request er;
404 429 struct gfs2_holder i_gh;
405 430 int error;
406 431  
407   - if (!er->er_data || !er->er_data_len) {
408   - er->er_data = NULL;
409   - er->er_data_len = 0;
  432 + memset(&er, 0, sizeof(struct gfs2_ea_request));
  433 + if (size) {
  434 + er.er_data = buffer;
  435 + er.er_data_len = size;
410 436 }
411 437  
412 438 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
... ... @@ -414,7 +440,7 @@
414 440 return error;
415 441  
416 442 if (ip->i_eattr) {
417   - struct ea_list ei = { .ei_er = er, .ei_size = 0 };
  443 + struct ea_list ei = { .ei_er = &er, .ei_size = 0 };
418 444  
419 445 error = ea_foreach(ip, ea_list_i, &ei);
420 446 if (!error)
421 447  
422 448  
423 449  
424 450  
425 451  
426 452  
427 453  
428 454  
429 455  
430 456  
... ... @@ -491,84 +517,61 @@
491 517 }
492 518  
493 519 int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
494   - char *data)
  520 + char *data, size_t size)
495 521 {
  522 + int ret;
  523 + size_t len = GFS2_EA_DATA_LEN(el->el_ea);
  524 + if (len > size)
  525 + return -ERANGE;
  526 +
496 527 if (GFS2_EA_IS_STUFFED(el->el_ea)) {
497   - memcpy(data, GFS2_EA2DATA(el->el_ea), GFS2_EA_DATA_LEN(el->el_ea));
498   - return 0;
499   - } else
500   - return ea_get_unstuffed(ip, el->el_ea, data);
  528 + memcpy(data, GFS2_EA2DATA(el->el_ea), len);
  529 + return len;
  530 + }
  531 + ret = ea_get_unstuffed(ip, el->el_ea, data);
  532 + if (ret < 0)
  533 + return ret;
  534 + return len;
501 535 }
502 536  
503 537 /**
504   - * gfs2_ea_get_i -
505   - * @ip: The GFS2 inode
506   - * @er: The request structure
  538 + * gfs2_xattr_get - Get a GFS2 extended attribute
  539 + * @inode: The inode
  540 + * @type: The type of extended attribute
  541 + * @name: The name of the extended attribute
  542 + * @buffer: The buffer to write the result into
  543 + * @size: The size of the buffer
507 544 *
508 545 * Returns: actual size of data on success, -errno on error
509 546 */
510 547  
511   -int gfs2_ea_get_i(struct gfs2_inode *ip, struct gfs2_ea_request *er)
  548 +int gfs2_xattr_get(struct inode *inode, int type, const char *name,
  549 + void *buffer, size_t size)
512 550 {
  551 + struct gfs2_inode *ip = GFS2_I(inode);
513 552 struct gfs2_ea_location el;
514 553 int error;
515 554  
516 555 if (!ip->i_eattr)
517 556 return -ENODATA;
  557 + if (strlen(name) > GFS2_EA_MAX_NAME_LEN)
  558 + return -EINVAL;
518 559  
519   - error = gfs2_ea_find(ip, er, &el);
  560 + error = gfs2_ea_find(ip, type, name, &el);
520 561 if (error)
521 562 return error;
522 563 if (!el.el_ea)
523 564 return -ENODATA;
524   -
525   - if (er->er_data_len) {
526   - if (GFS2_EA_DATA_LEN(el.el_ea) > er->er_data_len)
527   - error = -ERANGE;
528   - else
529   - error = gfs2_ea_get_copy(ip, &el, er->er_data);
530   - }
531   - if (!error)
  565 + if (size)
  566 + error = gfs2_ea_get_copy(ip, &el, buffer, size);
  567 + else
532 568 error = GFS2_EA_DATA_LEN(el.el_ea);
533   -
534 569 brelse(el.el_bh);
535 570  
536 571 return error;
537 572 }
538 573  
539 574 /**
540   - * gfs2_ea_get -
541   - * @ip: The GFS2 inode
542   - * @er: The request structure
543   - *
544   - * Returns: actual size of data on success, -errno on error
545   - */
546   -
547   -int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
548   -{
549   - struct gfs2_holder i_gh;
550   - int error;
551   -
552   - if (!er->er_name_len ||
553   - er->er_name_len > GFS2_EA_MAX_NAME_LEN)
554   - return -EINVAL;
555   - if (!er->er_data || !er->er_data_len) {
556   - er->er_data = NULL;
557   - er->er_data_len = 0;
558   - }
559   -
560   - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
561   - if (error)
562   - return error;
563   -
564   - error = gfs2_ea_ops[er->er_type]->eo_get(ip, er);
565   -
566   - gfs2_glock_dq_uninit(&i_gh);
567   -
568   - return error;
569   -}
570   -
571   -/**
572 575 * ea_alloc_blk - allocates a new block for extended attributes.
573 576 * @ip: A pointer to the inode that's getting extended attributes
574 577 * @bhp: Pointer to pointer to a struct buffer_head
... ... @@ -713,12 +716,6 @@
713 716  
714 717 error = gfs2_meta_inode_buffer(ip, &dibh);
715 718 if (!error) {
716   - if (er->er_flags & GFS2_ERF_MODE) {
717   - gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
718   - (ip->i_inode.i_mode & S_IFMT) ==
719   - (er->er_mode & S_IFMT));
720   - ip->i_inode.i_mode = er->er_mode;
721   - }
722 719 ip->i_inode.i_ctime = CURRENT_TIME;
723 720 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
724 721 gfs2_dinode_out(ip, dibh->b_data);
725 722  
726 723  
727 724  
... ... @@ -762,15 +759,23 @@
762 759 * Returns: errno
763 760 */
764 761  
765   -static int ea_init(struct gfs2_inode *ip, struct gfs2_ea_request *er)
  762 +static int ea_init(struct gfs2_inode *ip, int type, const char *name,
  763 + const void *data, size_t size)
766 764 {
  765 + struct gfs2_ea_request er;
767 766 unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
768 767 unsigned int blks = 1;
769 768  
770   - if (GFS2_EAREQ_SIZE_STUFFED(er) > jbsize)
771   - blks += DIV_ROUND_UP(er->er_data_len, jbsize);
  769 + er.er_type = type;
  770 + er.er_name = name;
  771 + er.er_name_len = strlen(name);
  772 + er.er_data = (void *)data;
  773 + er.er_data_len = size;
772 774  
773   - return ea_alloc_skeleton(ip, er, blks, ea_init_i, NULL);
  775 + if (GFS2_EAREQ_SIZE_STUFFED(&er) > jbsize)
  776 + blks += DIV_ROUND_UP(er.er_data_len, jbsize);
  777 +
  778 + return ea_alloc_skeleton(ip, &er, blks, ea_init_i, NULL);
774 779 }
775 780  
776 781 static struct gfs2_ea_header *ea_split_ea(struct gfs2_ea_header *ea)
... ... @@ -848,12 +853,6 @@
848 853 error = gfs2_meta_inode_buffer(ip, &dibh);
849 854 if (error)
850 855 goto out;
851   -
852   - if (er->er_flags & GFS2_ERF_MODE) {
853   - gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
854   - (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT));
855   - ip->i_inode.i_mode = er->er_mode;
856   - }
857 856 ip->i_inode.i_ctime = CURRENT_TIME;
858 857 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
859 858 gfs2_dinode_out(ip, dibh->b_data);
... ... @@ -894,7 +893,8 @@
894 893 int stuffed;
895 894 int error;
896 895  
897   - stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er, &size);
  896 + stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er->er_name_len,
  897 + es->es_er->er_data_len, &size);
898 898  
899 899 if (ea->ea_type == GFS2_EATYPE_UNUSED) {
900 900 if (GFS2_EA_REC_LEN(ea) < size)
901 901  
902 902  
903 903  
... ... @@ -1005,15 +1005,22 @@
1005 1005 return error;
1006 1006 }
1007 1007  
1008   -static int ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
1009   - struct gfs2_ea_location *el)
  1008 +static int ea_set_i(struct gfs2_inode *ip, int type, const char *name,
  1009 + const void *value, size_t size, struct gfs2_ea_location *el)
1010 1010 {
  1011 + struct gfs2_ea_request er;
1011 1012 struct ea_set es;
1012 1013 unsigned int blks = 2;
1013 1014 int error;
1014 1015  
  1016 + er.er_type = type;
  1017 + er.er_name = name;
  1018 + er.er_data = (void *)value;
  1019 + er.er_name_len = strlen(name);
  1020 + er.er_data_len = size;
  1021 +
1015 1022 memset(&es, 0, sizeof(struct ea_set));
1016   - es.es_er = er;
  1023 + es.es_er = &er;
1017 1024 es.es_el = el;
1018 1025  
1019 1026 error = ea_foreach(ip, ea_set_simple, &es);
1020 1027  
... ... @@ -1024,10 +1031,10 @@
1024 1031  
1025 1032 if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT))
1026 1033 blks++;
1027   - if (GFS2_EAREQ_SIZE_STUFFED(er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
1028   - blks += DIV_ROUND_UP(er->er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
  1034 + if (GFS2_EAREQ_SIZE_STUFFED(&er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
  1035 + blks += DIV_ROUND_UP(er.er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
1029 1036  
1030   - return ea_alloc_skeleton(ip, er, blks, ea_set_block, el);
  1037 + return ea_alloc_skeleton(ip, &er, blks, ea_set_block, el);
1031 1038 }
1032 1039  
1033 1040 static int ea_set_remove_unstuffed(struct gfs2_inode *ip,
... ... @@ -1042,74 +1049,6 @@
1042 1049 return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev,0);
1043 1050 }
1044 1051  
1045   -int gfs2_ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er)
1046   -{
1047   - struct gfs2_ea_location el;
1048   - int error;
1049   -
1050   - if (!ip->i_eattr) {
1051   - if (er->er_flags & XATTR_REPLACE)
1052   - return -ENODATA;
1053   - return ea_init(ip, er);
1054   - }
1055   -
1056   - error = gfs2_ea_find(ip, er, &el);
1057   - if (error)
1058   - return error;
1059   -
1060   - if (el.el_ea) {
1061   - if (ip->i_diskflags & GFS2_DIF_APPENDONLY) {
1062   - brelse(el.el_bh);
1063   - return -EPERM;
1064   - }
1065   -
1066   - error = -EEXIST;
1067   - if (!(er->er_flags & XATTR_CREATE)) {
1068   - int unstuffed = !GFS2_EA_IS_STUFFED(el.el_ea);
1069   - error = ea_set_i(ip, er, &el);
1070   - if (!error && unstuffed)
1071   - ea_set_remove_unstuffed(ip, &el);
1072   - }
1073   -
1074   - brelse(el.el_bh);
1075   - } else {
1076   - error = -ENODATA;
1077   - if (!(er->er_flags & XATTR_REPLACE))
1078   - error = ea_set_i(ip, er, NULL);
1079   - }
1080   -
1081   - return error;
1082   -}
1083   -
1084   -int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
1085   -{
1086   - struct gfs2_holder i_gh;
1087   - int error;
1088   -
1089   - if (!er->er_name_len || er->er_name_len > GFS2_EA_MAX_NAME_LEN)
1090   - return -EINVAL;
1091   - if (!er->er_data || !er->er_data_len) {
1092   - er->er_data = NULL;
1093   - er->er_data_len = 0;
1094   - }
1095   - error = ea_check_size(GFS2_SB(&ip->i_inode), er);
1096   - if (error)
1097   - return error;
1098   -
1099   - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
1100   - if (error)
1101   - return error;
1102   -
1103   - if (IS_IMMUTABLE(&ip->i_inode))
1104   - error = -EPERM;
1105   - else
1106   - error = gfs2_ea_ops[er->er_type]->eo_set(ip, er);
1107   -
1108   - gfs2_glock_dq_uninit(&i_gh);
1109   -
1110   - return error;
1111   -}
1112   -
1113 1052 static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
1114 1053 {
1115 1054 struct gfs2_ea_header *ea = el->el_ea;
1116 1055  
... ... @@ -1131,8 +1070,9 @@
1131 1070  
1132 1071 if (GFS2_EA_IS_LAST(ea))
1133 1072 prev->ea_flags |= GFS2_EAFLAG_LAST;
1134   - } else
  1073 + } else {
1135 1074 ea->ea_type = GFS2_EATYPE_UNUSED;
  1075 + }
1136 1076  
1137 1077 error = gfs2_meta_inode_buffer(ip, &dibh);
1138 1078 if (!error) {
1139 1079  
1140 1080  
... ... @@ -1147,15 +1087,29 @@
1147 1087 return error;
1148 1088 }
1149 1089  
1150   -int gfs2_ea_remove_i(struct gfs2_inode *ip, struct gfs2_ea_request *er)
  1090 +/**
  1091 + * gfs2_xattr_remove - Remove a GFS2 extended attribute
  1092 + * @inode: The inode
  1093 + * @type: The type of the extended attribute
  1094 + * @name: The name of the extended attribute
  1095 + *
  1096 + * This is not called directly by the VFS since we use the (common)
  1097 + * scheme of making a "set with NULL data" mean a remove request. Note
  1098 + * that this is different from a set with zero length data.
  1099 + *
  1100 + * Returns: 0, or errno on failure
  1101 + */
  1102 +
  1103 +static int gfs2_xattr_remove(struct inode *inode, int type, const char *name)
1151 1104 {
  1105 + struct gfs2_inode *ip = GFS2_I(inode);
1152 1106 struct gfs2_ea_location el;
1153 1107 int error;
1154 1108  
1155 1109 if (!ip->i_eattr)
1156 1110 return -ENODATA;
1157 1111  
1158   - error = gfs2_ea_find(ip, er, &el);
  1112 + error = gfs2_ea_find(ip, type, name, &el);
1159 1113 if (error)
1160 1114 return error;
1161 1115 if (!el.el_ea)
... ... @@ -1164,8 +1118,7 @@
1164 1118 if (GFS2_EA_IS_STUFFED(el.el_ea))
1165 1119 error = ea_remove_stuffed(ip, &el);
1166 1120 else
1167   - error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev,
1168   - 0);
  1121 + error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, 0);
1169 1122  
1170 1123 brelse(el.el_bh);
1171 1124  
1172 1125  
1173 1126  
1174 1127  
1175 1128  
1176 1129  
1177 1130  
1178 1131  
1179 1132  
... ... @@ -1173,32 +1126,71 @@
1173 1126 }
1174 1127  
1175 1128 /**
1176   - * gfs2_ea_remove - sets (or creates or replaces) an extended attribute
1177   - * @ip: pointer to the inode of the target file
1178   - * @er: request information
  1129 + * gfs2_xattr_set - Set (or remove) a GFS2 extended attribute
  1130 + * @inode: The inode
  1131 + * @type: The type of the extended attribute
  1132 + * @name: The name of the extended attribute
  1133 + * @value: The value of the extended attribute (NULL for remove)
  1134 + * @size: The size of the @value argument
  1135 + * @flags: Create or Replace
1179 1136 *
1180   - * Returns: errno
  1137 + * See gfs2_xattr_remove() for details of the removal of xattrs.
  1138 + *
  1139 + * Returns: 0 or errno on failure
1181 1140 */
1182 1141  
1183   -int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
  1142 +int gfs2_xattr_set(struct inode *inode, int type, const char *name,
  1143 + const void *value, size_t size, int flags)
1184 1144 {
1185   - struct gfs2_holder i_gh;
  1145 + struct gfs2_sbd *sdp = GFS2_SB(inode);
  1146 + struct gfs2_inode *ip = GFS2_I(inode);
  1147 + struct gfs2_ea_location el;
  1148 + unsigned int namel = strlen(name);
1186 1149 int error;
1187 1150  
1188   - if (!er->er_name_len || er->er_name_len > GFS2_EA_MAX_NAME_LEN)
1189   - return -EINVAL;
  1151 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  1152 + return -EPERM;
  1153 + if (namel > GFS2_EA_MAX_NAME_LEN)
  1154 + return -ERANGE;
1190 1155  
1191   - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
  1156 + if (value == NULL)
  1157 + return gfs2_xattr_remove(inode, type, name);
  1158 +
  1159 + if (ea_check_size(sdp, namel, size))
  1160 + return -ERANGE;
  1161 +
  1162 + if (!ip->i_eattr) {
  1163 + if (flags & XATTR_REPLACE)
  1164 + return -ENODATA;
  1165 + return ea_init(ip, type, name, value, size);
  1166 + }
  1167 +
  1168 + error = gfs2_ea_find(ip, type, name, &el);
1192 1169 if (error)
1193 1170 return error;
1194 1171  
1195   - if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
1196   - error = -EPERM;
1197   - else
1198   - error = gfs2_ea_ops[er->er_type]->eo_remove(ip, er);
  1172 + if (el.el_ea) {
  1173 + if (ip->i_diskflags & GFS2_DIF_APPENDONLY) {
  1174 + brelse(el.el_bh);
  1175 + return -EPERM;
  1176 + }
1199 1177  
1200   - gfs2_glock_dq_uninit(&i_gh);
  1178 + error = -EEXIST;
  1179 + if (!(flags & XATTR_CREATE)) {
  1180 + int unstuffed = !GFS2_EA_IS_STUFFED(el.el_ea);
  1181 + error = ea_set_i(ip, type, name, value, size, &el);
  1182 + if (!error && unstuffed)
  1183 + ea_set_remove_unstuffed(ip, &el);
  1184 + }
1201 1185  
  1186 + brelse(el.el_bh);
  1187 + return error;
  1188 + }
  1189 +
  1190 + error = -ENODATA;
  1191 + if (!(flags & XATTR_REPLACE))
  1192 + error = ea_set_i(ip, type, name, value, size, NULL);
  1193 +
1202 1194 return error;
1203 1195 }
1204 1196  
... ... @@ -1502,4 +1494,65 @@
1502 1494 gfs2_alloc_put(ip);
1503 1495 return error;
1504 1496 }
  1497 +
  1498 +static int gfs2_xattr_user_get(struct inode *inode, const char *name,
  1499 + void *buffer, size_t size)
  1500 +{
  1501 + return gfs2_xattr_get(inode, GFS2_EATYPE_USR, name, buffer, size);
  1502 +}
  1503 +
  1504 +static int gfs2_xattr_user_set(struct inode *inode, const char *name,
  1505 + const void *value, size_t size, int flags)
  1506 +{
  1507 + return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags);
  1508 +}
  1509 +
  1510 +static int gfs2_xattr_system_get(struct inode *inode, const char *name,
  1511 + void *buffer, size_t size)
  1512 +{
  1513 + return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
  1514 +}
  1515 +
  1516 +static int gfs2_xattr_system_set(struct inode *inode, const char *name,
  1517 + const void *value, size_t size, int flags)
  1518 +{
  1519 + return gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, flags);
  1520 +}
  1521 +
  1522 +static int gfs2_xattr_security_get(struct inode *inode, const char *name,
  1523 + void *buffer, size_t size)
  1524 +{
  1525 + return gfs2_xattr_get(inode, GFS2_EATYPE_SECURITY, name, buffer, size);
  1526 +}
  1527 +
  1528 +static int gfs2_xattr_security_set(struct inode *inode, const char *name,
  1529 + const void *value, size_t size, int flags)
  1530 +{
  1531 + return gfs2_xattr_set(inode, GFS2_EATYPE_SECURITY, name, value, size, flags);
  1532 +}
  1533 +
  1534 +static struct xattr_handler gfs2_xattr_user_handler = {
  1535 + .prefix = XATTR_USER_PREFIX,
  1536 + .get = gfs2_xattr_user_get,
  1537 + .set = gfs2_xattr_user_set,
  1538 +};
  1539 +
  1540 +static struct xattr_handler gfs2_xattr_security_handler = {
  1541 + .prefix = XATTR_SECURITY_PREFIX,
  1542 + .get = gfs2_xattr_security_get,
  1543 + .set = gfs2_xattr_security_set,
  1544 +};
  1545 +
  1546 +static struct xattr_handler gfs2_xattr_system_handler = {
  1547 + .prefix = XATTR_SYSTEM_PREFIX,
  1548 + .get = gfs2_xattr_system_get,
  1549 + .set = gfs2_xattr_system_set,
  1550 +};
  1551 +
  1552 +struct xattr_handler *gfs2_xattr_handlers[] = {
  1553 + &gfs2_xattr_user_handler,
  1554 + &gfs2_xattr_security_handler,
  1555 + &gfs2_xattr_system_handler,
  1556 + NULL,
  1557 +};
... ... @@ -27,10 +27,6 @@
27 27 #define GFS2_EAREQ_SIZE_STUFFED(er) \
28 28 ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + (er)->er_data_len, 8)
29 29  
30   -#define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \
31   -ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \
32   - sizeof(__be64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8)
33   -
34 30 #define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1))
35 31 #define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len)
36 32  
37 33  
... ... @@ -43,16 +39,12 @@
43 39 #define GFS2_EA_BH2FIRST(bh) \
44 40 ((struct gfs2_ea_header *)((bh)->b_data + sizeof(struct gfs2_meta_header)))
45 41  
46   -#define GFS2_ERF_MODE 0x80000000
47   -
48 42 struct gfs2_ea_request {
49 43 const char *er_name;
50 44 char *er_data;
51 45 unsigned int er_name_len;
52 46 unsigned int er_data_len;
53 47 unsigned int er_type; /* GFS2_EATYPE_... */
54   - int er_flags;
55   - mode_t er_mode;
56 48 };
57 49  
58 50 struct gfs2_ea_location {
59 51  
60 52  
... ... @@ -61,41 +53,21 @@
61 53 struct gfs2_ea_header *el_prev;
62 54 };
63 55  
64   -int gfs2_ea_get_i(struct gfs2_inode *ip, struct gfs2_ea_request *er);
65   -int gfs2_ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er);
66   -int gfs2_ea_remove_i(struct gfs2_inode *ip, struct gfs2_ea_request *er);
  56 +extern int gfs2_xattr_get(struct inode *inode, int type, const char *name,
  57 + void *buffer, size_t size);
  58 +extern int gfs2_xattr_set(struct inode *inode, int type, const char *name,
  59 + const void *value, size_t size, int flags);
  60 +extern ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size);
  61 +extern int gfs2_ea_dealloc(struct gfs2_inode *ip);
67 62  
68   -int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er);
69   -int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er);
70   -int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er);
71   -int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er);
72   -
73   -int gfs2_ea_dealloc(struct gfs2_inode *ip);
74   -
75 63 /* Exported to acl.c */
76 64  
77   -int gfs2_ea_find(struct gfs2_inode *ip,
78   - struct gfs2_ea_request *er,
79   - struct gfs2_ea_location *el);
80   -int gfs2_ea_get_copy(struct gfs2_inode *ip,
81   - struct gfs2_ea_location *el,
82   - char *data);
83   -int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
84   - struct iattr *attr, char *data);
85   -
86   -static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea)
87   -{
88   - switch (ea->ea_type) {
89   - case GFS2_EATYPE_USR:
90   - return 5 + ea->ea_name_len + 1;
91   - case GFS2_EATYPE_SYS:
92   - return 7 + ea->ea_name_len + 1;
93   - case GFS2_EATYPE_SECURITY:
94   - return 9 + ea->ea_name_len + 1;
95   - default:
96   - return 0;
97   - }
98   -}
  65 +extern int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
  66 + struct gfs2_ea_location *el);
  67 +extern int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
  68 + char *data, size_t size);
  69 +extern int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
  70 + struct iattr *attr, char *data);
99 71  
100 72 #endif /* __EATTR_DOT_H__ */
... ... @@ -38,7 +38,6 @@
38 38 #include "rgrp.h"
39 39 #include "trans.h"
40 40 #include "util.h"
41   -#include "eaops.h"
42 41  
43 42 /**
44 43 * gfs2_llseek - seek to a location in a file
... ... @@ -924,7 +924,6 @@
924 924 size_t len;
925 925 void *value;
926 926 char *name;
927   - struct gfs2_ea_request er;
928 927  
929 928 err = security_inode_init_security(&ip->i_inode, &dip->i_inode,
930 929 &name, &value, &len);
... ... @@ -935,16 +934,7 @@
935 934 return err;
936 935 }
937 936  
938   - memset(&er, 0, sizeof(struct gfs2_ea_request));
939   -
940   - er.er_type = GFS2_EATYPE_SECURITY;
941   - er.er_name = name;
942   - er.er_data = value;
943   - er.er_name_len = strlen(name);
944   - er.er_data_len = len;
945   -
946   - err = gfs2_ea_set_i(ip, &er);
947   -
  937 + err = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SECURITY, name, value, len, 0);
948 938 kfree(value);
949 939 kfree(name);
950 940  
fs/gfs2/ops_fstype.c
... ... @@ -1186,6 +1186,7 @@
1186 1186 sb->s_magic = GFS2_MAGIC;
1187 1187 sb->s_op = &gfs2_super_ops;
1188 1188 sb->s_export_op = &gfs2_export_ops;
  1189 + sb->s_xattr = gfs2_xattr_handlers;
1189 1190 sb->s_time_gran = 1;
1190 1191 sb->s_maxbytes = MAX_LFS_FILESIZE;
1191 1192  
... ... @@ -26,7 +26,6 @@
26 26 #include "acl.h"
27 27 #include "bmap.h"
28 28 #include "dir.h"
29   -#include "eaops.h"
30 29 #include "eattr.h"
31 30 #include "glock.h"
32 31 #include "inode.h"
33 32  
34 33  
35 34  
36 35  
37 36  
38 37  
... ... @@ -1302,60 +1301,53 @@
1302 1301 const void *data, size_t size, int flags)
1303 1302 {
1304 1303 struct inode *inode = dentry->d_inode;
1305   - struct gfs2_ea_request er;
  1304 + struct gfs2_inode *ip = GFS2_I(inode);
  1305 + struct gfs2_holder gh;
  1306 + int ret;
1306 1307  
1307   - memset(&er, 0, sizeof(struct gfs2_ea_request));
1308   - er.er_type = gfs2_ea_name2type(name, &er.er_name);
1309   - if (er.er_type == GFS2_EATYPE_UNUSED)
1310   - return -EOPNOTSUPP;
1311   - er.er_data = (char *)data;
1312   - er.er_name_len = strlen(er.er_name);
1313   - er.er_data_len = size;
1314   - er.er_flags = flags;
1315   -
1316   - gfs2_assert_warn(GFS2_SB(inode), !(er.er_flags & GFS2_ERF_MODE));
1317   -
1318   - return gfs2_ea_set(GFS2_I(inode), &er);
  1308 + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  1309 + ret = gfs2_glock_nq(&gh);
  1310 + if (ret == 0) {
  1311 + ret = generic_setxattr(dentry, name, data, size, flags);
  1312 + gfs2_glock_dq(&gh);
  1313 + }
  1314 + gfs2_holder_uninit(&gh);
  1315 + return ret;
1319 1316 }
1320 1317  
1321 1318 static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
1322 1319 void *data, size_t size)
1323 1320 {
1324   - struct gfs2_ea_request er;
  1321 + struct inode *inode = dentry->d_inode;
  1322 + struct gfs2_inode *ip = GFS2_I(inode);
  1323 + struct gfs2_holder gh;
  1324 + int ret;
1325 1325  
1326   - memset(&er, 0, sizeof(struct gfs2_ea_request));
1327   - er.er_type = gfs2_ea_name2type(name, &er.er_name);
1328   - if (er.er_type == GFS2_EATYPE_UNUSED)
1329   - return -EOPNOTSUPP;
1330   - er.er_data = data;
1331   - er.er_name_len = strlen(er.er_name);
1332   - er.er_data_len = size;
1333   -
1334   - return gfs2_ea_get(GFS2_I(dentry->d_inode), &er);
  1326 + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
  1327 + ret = gfs2_glock_nq(&gh);
  1328 + if (ret == 0) {
  1329 + ret = generic_getxattr(dentry, name, data, size);
  1330 + gfs2_glock_dq(&gh);
  1331 + }
  1332 + gfs2_holder_uninit(&gh);
  1333 + return ret;
1335 1334 }
1336 1335  
1337   -static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
1338   -{
1339   - struct gfs2_ea_request er;
1340   -
1341   - memset(&er, 0, sizeof(struct gfs2_ea_request));
1342   - er.er_data = (size) ? buffer : NULL;
1343   - er.er_data_len = size;
1344   -
1345   - return gfs2_ea_list(GFS2_I(dentry->d_inode), &er);
1346   -}
1347   -
1348 1336 static int gfs2_removexattr(struct dentry *dentry, const char *name)
1349 1337 {
1350   - struct gfs2_ea_request er;
  1338 + struct inode *inode = dentry->d_inode;
  1339 + struct gfs2_inode *ip = GFS2_I(inode);
  1340 + struct gfs2_holder gh;
  1341 + int ret;
1351 1342  
1352   - memset(&er, 0, sizeof(struct gfs2_ea_request));
1353   - er.er_type = gfs2_ea_name2type(name, &er.er_name);
1354   - if (er.er_type == GFS2_EATYPE_UNUSED)
1355   - return -EOPNOTSUPP;
1356   - er.er_name_len = strlen(er.er_name);
1357   -
1358   - return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er);
  1343 + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  1344 + ret = gfs2_glock_nq(&gh);
  1345 + if (ret == 0) {
  1346 + ret = generic_removexattr(dentry, name);
  1347 + gfs2_glock_dq(&gh);
  1348 + }
  1349 + gfs2_holder_uninit(&gh);
  1350 + return ret;
1359 1351 }
1360 1352  
1361 1353 static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
... ... @@ -54,6 +54,7 @@
54 54 extern const struct export_operations gfs2_export_ops;
55 55 extern const struct super_operations gfs2_super_ops;
56 56 extern const struct dentry_operations gfs2_dops;
  57 +extern struct xattr_handler *gfs2_xattr_handlers[];
57 58  
58 59 #endif /* __SUPER_DOT_H__ */