Blame view

fs/orangefs/xattr.c 12.4 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1182fca3b   Mike Marshall   Orangefs: kernel ...
2
3
4
5
6
7
8
9
10
11
12
  /*
   * (C) 2001 Clemson University and The University of Chicago
   *
   * See COPYING in top-level directory.
   */
  
  /*
   *  Linux VFS extended attribute operations.
   */
  
  #include "protocol.h"
575e94612   Mike Marshall   Orangefs: change ...
13
14
  #include "orangefs-kernel.h"
  #include "orangefs-bufmap.h"
1182fca3b   Mike Marshall   Orangefs: kernel ...
15
16
  #include <linux/posix_acl_xattr.h>
  #include <linux/xattr.h>
8bb8aefd5   Yi Liu   OrangeFS: Change ...
17
18
  #define SYSTEM_ORANGEFS_KEY "system.pvfs2."
  #define SYSTEM_ORANGEFS_KEY_LEN 13
1182fca3b   Mike Marshall   Orangefs: kernel ...
19
20
21
22
23
24
25
  
  /*
   * this function returns
   *   0 if the key corresponding to name is not meant to be printed as part
   *     of a listxattr.
   *   1 if the key corresponding to name is meant to be returned as part of
   *     a listxattr.
8bb8aefd5   Yi Liu   OrangeFS: Change ...
26
   * The ones that start SYSTEM_ORANGEFS_KEY are the ones to avoid printing.
1182fca3b   Mike Marshall   Orangefs: kernel ...
27
28
29
   */
  static int is_reserved_key(const char *key, size_t size)
  {
8bb8aefd5   Yi Liu   OrangeFS: Change ...
30
  	if (size < SYSTEM_ORANGEFS_KEY_LEN)
1182fca3b   Mike Marshall   Orangefs: kernel ...
31
  		return 1;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
32
  	return strncmp(key, SYSTEM_ORANGEFS_KEY, SYSTEM_ORANGEFS_KEY_LEN) ?  1 : 0;
1182fca3b   Mike Marshall   Orangefs: kernel ...
33
34
35
36
37
38
39
40
  }
  
  static inline int convert_to_internal_xattr_flags(int setxattr_flags)
  {
  	int internal_flag = 0;
  
  	if (setxattr_flags & XATTR_REPLACE) {
  		/* Attribute must exist! */
8bb8aefd5   Yi Liu   OrangeFS: Change ...
41
  		internal_flag = ORANGEFS_XATTR_REPLACE;
1182fca3b   Mike Marshall   Orangefs: kernel ...
42
43
  	} else if (setxattr_flags & XATTR_CREATE) {
  		/* Attribute must not exist */
8bb8aefd5   Yi Liu   OrangeFS: Change ...
44
  		internal_flag = ORANGEFS_XATTR_CREATE;
1182fca3b   Mike Marshall   Orangefs: kernel ...
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  	}
  	return internal_flag;
  }
  
  
  /*
   * Tries to get a specified key's attributes of a given
   * file into a user-specified buffer. Note that the getxattr
   * interface allows for the users to probe the size of an
   * extended attribute by passing in a value of 0 to size.
   * Thus our return value is always the size of the attribute
   * unless the key does not exist for the file and/or if
   * there were errors in fetching the attribute value.
   */
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
59
60
  ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name,
  				void *buffer, size_t size)
1182fca3b   Mike Marshall   Orangefs: kernel ...
61
  {
8bb8aefd5   Yi Liu   OrangeFS: Change ...
62
63
  	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  	struct orangefs_kernel_op_s *new_op = NULL;
1182fca3b   Mike Marshall   Orangefs: kernel ...
64
65
66
67
68
69
  	ssize_t ret = -ENOMEM;
  	ssize_t length = 0;
  	int fsuid;
  	int fsgid;
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
70
71
72
  		     "%s: name %s, buffer_size %zd
  ",
  		     __func__, name, size);
1182fca3b   Mike Marshall   Orangefs: kernel ...
73

6c6ef9f26   Andreas Gruenbacher   xattr: Stop calli...
74
75
  	if (S_ISLNK(inode->i_mode))
  		return -EOPNOTSUPP;
5f13e5876   Dan Carpenter   orangefs: off by ...
76
  	if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN)
1182fca3b   Mike Marshall   Orangefs: kernel ...
77
  		return -EINVAL;
1182fca3b   Mike Marshall   Orangefs: kernel ...
78

78fee0b68   Jann Horn   orangefs: fix nam...
79
80
  	fsuid = from_kuid(&init_user_ns, current_fsuid());
  	fsgid = from_kgid(&init_user_ns, current_fsgid());
1182fca3b   Mike Marshall   Orangefs: kernel ...
81
82
83
84
85
86
87
88
89
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
  		     "getxattr on inode %pU, name %s "
  		     "(uid %o, gid %o)
  ",
  		     get_khandle_from_ino(inode),
  		     name,
  		     fsuid,
  		     fsgid);
8bb8aefd5   Yi Liu   OrangeFS: Change ...
90
  	down_read(&orangefs_inode->xattr_sem);
1182fca3b   Mike Marshall   Orangefs: kernel ...
91

8bb8aefd5   Yi Liu   OrangeFS: Change ...
92
  	new_op = op_alloc(ORANGEFS_VFS_OP_GETXATTR);
1182fca3b   Mike Marshall   Orangefs: kernel ...
93
94
  	if (!new_op)
  		goto out_unlock;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
95
  	new_op->upcall.req.getxattr.refn = orangefs_inode->refn;
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
96
  	strcpy(new_op->upcall.req.getxattr.key, name);
1182fca3b   Mike Marshall   Orangefs: kernel ...
97
98
99
100
101
102
  
  	/*
  	 * NOTE: Although keys are meant to be NULL terminated textual
  	 * strings, I am going to explicitly pass the length just in case
  	 * we change this later on...
  	 */
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
103
  	new_op->upcall.req.getxattr.key_sz = strlen(name) + 1;
1182fca3b   Mike Marshall   Orangefs: kernel ...
104

8bb8aefd5   Yi Liu   OrangeFS: Change ...
105
  	ret = service_operation(new_op, "orangefs_inode_getxattr",
1182fca3b   Mike Marshall   Orangefs: kernel ...
106
107
108
109
110
  				get_interruptible_flag(inode));
  	if (ret != 0) {
  		if (ret == -ENOENT) {
  			ret = -ENODATA;
  			gossip_debug(GOSSIP_XATTR_DEBUG,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
111
  				     "orangefs_inode_getxattr: inode %pU key %s"
1182fca3b   Mike Marshall   Orangefs: kernel ...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  				     " does not exist!
  ",
  				     get_khandle_from_ino(inode),
  				     (char *)new_op->upcall.req.getxattr.key);
  		}
  		goto out_release_op;
  	}
  
  	/*
  	 * Length returned includes null terminator.
  	 */
  	length = new_op->downcall.resp.getxattr.val_sz;
  
  	/*
  	 * Just return the length of the queried attribute.
  	 */
  	if (size == 0) {
  		ret = length;
  		goto out_release_op;
  	}
  
  	/*
  	 * Check to see if key length is > provided buffer size.
  	 */
  	if (length > size) {
  		ret = -ERANGE;
  		goto out_release_op;
  	}
1182fca3b   Mike Marshall   Orangefs: kernel ...
140
  	memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
a9bb3ba81   Mike Marshall   Orangefs: optimiz...
141
  	memset(buffer + length, 0, size - length);
1182fca3b   Mike Marshall   Orangefs: kernel ...
142
  	gossip_debug(GOSSIP_XATTR_DEBUG,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
143
  	     "orangefs_inode_getxattr: inode %pU "
1182fca3b   Mike Marshall   Orangefs: kernel ...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  	     "key %s key_sz %d, val_len %d
  ",
  	     get_khandle_from_ino(inode),
  	     (char *)new_op->
  		upcall.req.getxattr.key,
  		     (int)new_op->
  		upcall.req.getxattr.key_sz,
  	     (int)ret);
  
  	ret = length;
  
  out_release_op:
  	op_release(new_op);
  out_unlock:
8bb8aefd5   Yi Liu   OrangeFS: Change ...
158
  	up_read(&orangefs_inode->xattr_sem);
1182fca3b   Mike Marshall   Orangefs: kernel ...
159
160
  	return ret;
  }
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
161
162
  static int orangefs_inode_removexattr(struct inode *inode, const char *name,
  				      int flags)
1182fca3b   Mike Marshall   Orangefs: kernel ...
163
  {
8bb8aefd5   Yi Liu   OrangeFS: Change ...
164
165
  	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  	struct orangefs_kernel_op_s *new_op = NULL;
1182fca3b   Mike Marshall   Orangefs: kernel ...
166
  	int ret = -ENOMEM;
5f13e5876   Dan Carpenter   orangefs: off by ...
167
  	if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN)
e675c5ec5   Martin Brandenburg   orangefs: clean u...
168
  		return -EINVAL;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
169
170
  	down_write(&orangefs_inode->xattr_sem);
  	new_op = op_alloc(ORANGEFS_VFS_OP_REMOVEXATTR);
1182fca3b   Mike Marshall   Orangefs: kernel ...
171
172
  	if (!new_op)
  		goto out_unlock;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
173
  	new_op->upcall.req.removexattr.refn = orangefs_inode->refn;
1182fca3b   Mike Marshall   Orangefs: kernel ...
174
175
176
177
178
  	/*
  	 * NOTE: Although keys are meant to be NULL terminated
  	 * textual strings, I am going to explicitly pass the
  	 * length just in case we change this later on...
  	 */
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
179
180
  	strcpy(new_op->upcall.req.removexattr.key, name);
  	new_op->upcall.req.removexattr.key_sz = strlen(name) + 1;
1182fca3b   Mike Marshall   Orangefs: kernel ...
181
182
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
183
184
  		     "orangefs_inode_removexattr: key %s, key_sz %d
  ",
1182fca3b   Mike Marshall   Orangefs: kernel ...
185
186
187
188
  		     (char *)new_op->upcall.req.removexattr.key,
  		     (int)new_op->upcall.req.removexattr.key_sz);
  
  	ret = service_operation(new_op,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
189
  				"orangefs_inode_removexattr",
1182fca3b   Mike Marshall   Orangefs: kernel ...
190
191
192
193
194
195
196
197
198
199
200
201
  				get_interruptible_flag(inode));
  	if (ret == -ENOENT) {
  		/*
  		 * Request to replace a non-existent attribute is an error.
  		 */
  		if (flags & XATTR_REPLACE)
  			ret = -ENODATA;
  		else
  			ret = 0;
  	}
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
202
203
  		     "orangefs_inode_removexattr: returning %d
  ", ret);
1182fca3b   Mike Marshall   Orangefs: kernel ...
204
205
206
  
  	op_release(new_op);
  out_unlock:
8bb8aefd5   Yi Liu   OrangeFS: Change ...
207
  	up_write(&orangefs_inode->xattr_sem);
1182fca3b   Mike Marshall   Orangefs: kernel ...
208
209
210
211
212
213
214
215
216
  	return ret;
  }
  
  /*
   * Tries to set an attribute for a given key on a file.
   *
   * Returns a -ve number on error and 0 on success.  Key is text, but value
   * can be binary!
   */
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
217
218
  int orangefs_inode_setxattr(struct inode *inode, const char *name,
  			    const void *value, size_t size, int flags)
1182fca3b   Mike Marshall   Orangefs: kernel ...
219
  {
8bb8aefd5   Yi Liu   OrangeFS: Change ...
220
221
  	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  	struct orangefs_kernel_op_s *new_op;
1182fca3b   Mike Marshall   Orangefs: kernel ...
222
223
224
225
  	int internal_flag = 0;
  	int ret = -ENOMEM;
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
226
227
228
  		     "%s: name %s, buffer_size %zd
  ",
  		     __func__, name, size);
1182fca3b   Mike Marshall   Orangefs: kernel ...
229

e675c5ec5   Martin Brandenburg   orangefs: clean u...
230
231
  	if (size > ORANGEFS_MAX_XATTR_VALUELEN)
  		return -EINVAL;
5f13e5876   Dan Carpenter   orangefs: off by ...
232
  	if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN)
1182fca3b   Mike Marshall   Orangefs: kernel ...
233
  		return -EINVAL;
1182fca3b   Mike Marshall   Orangefs: kernel ...
234

1182fca3b   Mike Marshall   Orangefs: kernel ...
235
  	internal_flag = convert_to_internal_xattr_flags(flags);
1182fca3b   Mike Marshall   Orangefs: kernel ...
236
  	/* This is equivalent to a removexattr */
0b08273c8   Markus Elfring   orangefs: Adjust ...
237
  	if (size == 0 && !value) {
1182fca3b   Mike Marshall   Orangefs: kernel ...
238
  		gossip_debug(GOSSIP_XATTR_DEBUG,
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
239
240
  			     "removing xattr (%s)
  ",
1182fca3b   Mike Marshall   Orangefs: kernel ...
241
  			     name);
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
242
  		return orangefs_inode_removexattr(inode, name, flags);
1182fca3b   Mike Marshall   Orangefs: kernel ...
243
244
245
246
247
248
249
  	}
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
  		     "setxattr on inode %pU, name %s
  ",
  		     get_khandle_from_ino(inode),
  		     name);
8bb8aefd5   Yi Liu   OrangeFS: Change ...
250
251
  	down_write(&orangefs_inode->xattr_sem);
  	new_op = op_alloc(ORANGEFS_VFS_OP_SETXATTR);
1182fca3b   Mike Marshall   Orangefs: kernel ...
252
253
  	if (!new_op)
  		goto out_unlock;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
254
  	new_op->upcall.req.setxattr.refn = orangefs_inode->refn;
1182fca3b   Mike Marshall   Orangefs: kernel ...
255
256
257
258
259
260
  	new_op->upcall.req.setxattr.flags = internal_flag;
  	/*
  	 * NOTE: Although keys are meant to be NULL terminated textual
  	 * strings, I am going to explicitly pass the length just in
  	 * case we change this later on...
  	 */
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
261
262
  	strcpy(new_op->upcall.req.setxattr.keyval.key, name);
  	new_op->upcall.req.setxattr.keyval.key_sz = strlen(name) + 1;
1182fca3b   Mike Marshall   Orangefs: kernel ...
263
264
265
266
  	memcpy(new_op->upcall.req.setxattr.keyval.val, value, size);
  	new_op->upcall.req.setxattr.keyval.val_sz = size;
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
267
  		     "orangefs_inode_setxattr: key %s, key_sz %d "
1182fca3b   Mike Marshall   Orangefs: kernel ...
268
269
270
271
272
273
274
  		     " value size %zd
  ",
  		     (char *)new_op->upcall.req.setxattr.keyval.key,
  		     (int)new_op->upcall.req.setxattr.keyval.key_sz,
  		     size);
  
  	ret = service_operation(new_op,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
275
  				"orangefs_inode_setxattr",
1182fca3b   Mike Marshall   Orangefs: kernel ...
276
277
278
  				get_interruptible_flag(inode));
  
  	gossip_debug(GOSSIP_XATTR_DEBUG,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
279
280
  		     "orangefs_inode_setxattr: returning %d
  ",
1182fca3b   Mike Marshall   Orangefs: kernel ...
281
282
283
284
285
  		     ret);
  
  	/* when request is serviced properly, free req op struct */
  	op_release(new_op);
  out_unlock:
8bb8aefd5   Yi Liu   OrangeFS: Change ...
286
  	up_write(&orangefs_inode->xattr_sem);
1182fca3b   Mike Marshall   Orangefs: kernel ...
287
288
289
290
291
292
293
294
295
296
  	return ret;
  }
  
  /*
   * Tries to get a specified object's keys into a user-specified buffer of a
   * given size.  Note that like the previous instances of xattr routines, this
   * also allows you to pass in a NULL pointer and 0 size to probe the size for
   * subsequent memory allocations. Thus our return value is always the size of
   * all the keys unless there were errors in fetching the keys!
   */
8bb8aefd5   Yi Liu   OrangeFS: Change ...
297
  ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size)
1182fca3b   Mike Marshall   Orangefs: kernel ...
298
299
  {
  	struct inode *inode = dentry->d_inode;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
300
301
302
  	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  	struct orangefs_kernel_op_s *new_op;
  	__u64 token = ORANGEFS_ITERATE_START;
1182fca3b   Mike Marshall   Orangefs: kernel ...
303
304
  	ssize_t ret = -ENOMEM;
  	ssize_t total = 0;
1182fca3b   Mike Marshall   Orangefs: kernel ...
305
306
307
  	int count_keys = 0;
  	int key_size;
  	int i = 0;
62441fa53   Mike Marshall   Orangefs: validat...
308
  	int returned_count = 0;
1182fca3b   Mike Marshall   Orangefs: kernel ...
309

0b08273c8   Markus Elfring   orangefs: Adjust ...
310
  	if (size > 0 && !buffer) {
1182fca3b   Mike Marshall   Orangefs: kernel ...
311
312
313
314
  		gossip_err("%s: bogus NULL pointers
  ", __func__);
  		return -EINVAL;
  	}
1182fca3b   Mike Marshall   Orangefs: kernel ...
315

8bb8aefd5   Yi Liu   OrangeFS: Change ...
316
317
  	down_read(&orangefs_inode->xattr_sem);
  	new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR);
1182fca3b   Mike Marshall   Orangefs: kernel ...
318
319
320
321
322
323
324
325
  	if (!new_op)
  		goto out_unlock;
  
  	if (buffer && size > 0)
  		memset(buffer, 0, size);
  
  try_again:
  	key_size = 0;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
326
  	new_op->upcall.req.listxattr.refn = orangefs_inode->refn;
1182fca3b   Mike Marshall   Orangefs: kernel ...
327
328
  	new_op->upcall.req.listxattr.token = token;
  	new_op->upcall.req.listxattr.requested_count =
8bb8aefd5   Yi Liu   OrangeFS: Change ...
329
  	    (size == 0) ? 0 : ORANGEFS_MAX_XATTR_LISTLEN;
1182fca3b   Mike Marshall   Orangefs: kernel ...
330
331
332
333
334
335
336
337
338
339
340
341
  	ret = service_operation(new_op, __func__,
  				get_interruptible_flag(inode));
  	if (ret != 0)
  		goto done;
  
  	if (size == 0) {
  		/*
  		 * This is a bit of a big upper limit, but I did not want to
  		 * spend too much time getting this correct, since users end
  		 * up allocating memory rather than us...
  		 */
  		total = new_op->downcall.resp.listxattr.returned_count *
8bb8aefd5   Yi Liu   OrangeFS: Change ...
342
  			ORANGEFS_MAX_XATTR_NAMELEN;
1182fca3b   Mike Marshall   Orangefs: kernel ...
343
344
  		goto done;
  	}
62441fa53   Mike Marshall   Orangefs: validat...
345
346
  	returned_count = new_op->downcall.resp.listxattr.returned_count;
  	if (returned_count < 0 ||
a956af337   Martin Brandenburg   orangefs: fix bou...
347
  	    returned_count > ORANGEFS_MAX_XATTR_LISTLEN) {
62441fa53   Mike Marshall   Orangefs: validat...
348
349
350
351
  		gossip_err("%s: impossible value for returned_count:%d:
  ",
  		__func__,
  		returned_count);
02a5cc537   Martin Brandenburg   orangefs: sanitiz...
352
  		ret = -EIO;
62441fa53   Mike Marshall   Orangefs: validat...
353
354
  		goto done;
  	}
1182fca3b   Mike Marshall   Orangefs: kernel ...
355
356
357
  	/*
  	 * Check to see how much can be fit in the buffer. Fit only whole keys.
  	 */
62441fa53   Mike Marshall   Orangefs: validat...
358
  	for (i = 0; i < returned_count; i++) {
02a5cc537   Martin Brandenburg   orangefs: sanitiz...
359
360
361
362
363
364
365
366
367
368
  		if (new_op->downcall.resp.listxattr.lengths[i] < 0 ||
  		    new_op->downcall.resp.listxattr.lengths[i] >
  		    ORANGEFS_MAX_XATTR_NAMELEN) {
  			gossip_err("%s: impossible value for lengths[%d]
  ",
  			    __func__,
  			    new_op->downcall.resp.listxattr.lengths[i]);
  			ret = -EIO;
  			goto done;
  		}
1182fca3b   Mike Marshall   Orangefs: kernel ...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  		if (total + new_op->downcall.resp.listxattr.lengths[i] > size)
  			goto done;
  
  		/*
  		 * Since many dumb programs try to setxattr() on our reserved
  		 * xattrs this is a feeble attempt at defeating those by not
  		 * listing them in the output of listxattr.. sigh
  		 */
  		if (is_reserved_key(new_op->downcall.resp.listxattr.key +
  				    key_size,
  				    new_op->downcall.resp.
  					listxattr.lengths[i])) {
  			gossip_debug(GOSSIP_XATTR_DEBUG, "Copying key %d -> %s
  ",
  					i, new_op->downcall.resp.listxattr.key +
  						key_size);
  			memcpy(buffer + total,
  				new_op->downcall.resp.listxattr.key + key_size,
  				new_op->downcall.resp.listxattr.lengths[i]);
  			total += new_op->downcall.resp.listxattr.lengths[i];
  			count_keys++;
  		} else {
  			gossip_debug(GOSSIP_XATTR_DEBUG, "[RESERVED] key %d -> %s
  ",
  					i, new_op->downcall.resp.listxattr.key +
  						key_size);
  		}
  		key_size += new_op->downcall.resp.listxattr.lengths[i];
  	}
  
  	/*
  	 * Since the buffer was large enough, we might have to continue
  	 * fetching more keys!
  	 */
  	token = new_op->downcall.resp.listxattr.token;
8bb8aefd5   Yi Liu   OrangeFS: Change ...
404
  	if (token != ORANGEFS_ITERATE_END)
1182fca3b   Mike Marshall   Orangefs: kernel ...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
  		goto try_again;
  
  done:
  	gossip_debug(GOSSIP_XATTR_DEBUG, "%s: returning %d"
  		     " [size of buffer %ld] (filled in %d keys)
  ",
  		     __func__,
  		     ret ? (int)ret : (int)total,
  		     (long)size,
  		     count_keys);
  	op_release(new_op);
  	if (ret == 0)
  		ret = total;
  out_unlock:
8bb8aefd5   Yi Liu   OrangeFS: Change ...
419
  	up_read(&orangefs_inode->xattr_sem);
1182fca3b   Mike Marshall   Orangefs: kernel ...
420
421
  	return ret;
  }
8bb8aefd5   Yi Liu   OrangeFS: Change ...
422
  static int orangefs_xattr_set_default(const struct xattr_handler *handler,
593012268   Al Viro   switch xattr_hand...
423
424
  				      struct dentry *unused,
  				      struct inode *inode,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
425
426
427
428
  				      const char *name,
  				      const void *buffer,
  				      size_t size,
  				      int flags)
1182fca3b   Mike Marshall   Orangefs: kernel ...
429
  {
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
430
  	return orangefs_inode_setxattr(inode, name, buffer, size, flags);
1182fca3b   Mike Marshall   Orangefs: kernel ...
431
  }
8bb8aefd5   Yi Liu   OrangeFS: Change ...
432
  static int orangefs_xattr_get_default(const struct xattr_handler *handler,
b296821a7   Al Viro   xattr_handler: pa...
433
434
  				      struct dentry *unused,
  				      struct inode *inode,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
435
436
437
  				      const char *name,
  				      void *buffer,
  				      size_t size)
1182fca3b   Mike Marshall   Orangefs: kernel ...
438
  {
d373a712c   Andreas Gruenbacher   orangefs: Remove ...
439
  	return orangefs_inode_getxattr(inode, name, buffer, size);
1182fca3b   Mike Marshall   Orangefs: kernel ...
440
441
  
  }
121744440   Julia Lawall   orangefs: constif...
442
  static const struct xattr_handler orangefs_xattr_default_handler = {
972a7344f   Andreas Gruenbacher   orangefs: Remove ...
443
  	.prefix = "",  /* match any name => handlers called with full name */
8bb8aefd5   Yi Liu   OrangeFS: Change ...
444
445
  	.get = orangefs_xattr_get_default,
  	.set = orangefs_xattr_set_default,
1182fca3b   Mike Marshall   Orangefs: kernel ...
446
  };
8bb8aefd5   Yi Liu   OrangeFS: Change ...
447
  const struct xattr_handler *orangefs_xattr_handlers[] = {
1182fca3b   Mike Marshall   Orangefs: kernel ...
448
449
  	&posix_acl_access_xattr_handler,
  	&posix_acl_default_xattr_handler,
8bb8aefd5   Yi Liu   OrangeFS: Change ...
450
  	&orangefs_xattr_default_handler,
1182fca3b   Mike Marshall   Orangefs: kernel ...
451
452
  	NULL
  };