blob: e11f77f080a080635d6f6a564a506e1189244062 [file] [log] [blame]
David Teiglandb3b94fa2006-01-16 16:50:04 +00001/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
Steven Whitehouse3a8a9a12006-05-18 15:09:15 -04003 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
David Teiglandb3b94fa2006-01-16 16:50:04 +00004 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
Steven Whitehousee9fc2aa2006-09-01 11:05:15 -04007 * of the GNU General Public License version 2.
David Teiglandb3b94fa2006-01-16 16:50:04 +00008 */
9
David Teiglandb3b94fa2006-01-16 16:50:04 +000010#include <linux/slab.h>
11#include <linux/spinlock.h>
12#include <linux/completion.h>
13#include <linux/buffer_head.h>
14#include <linux/xattr.h>
Steven Whitehouse5c676f62006-02-27 17:23:27 -050015#include <linux/gfs2_ondisk.h>
Christoph Hellwige01580b2013-12-20 05:16:52 -080016#include <linux/posix_acl_xattr.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080017#include <linux/uaccess.h>
David Teiglandb3b94fa2006-01-16 16:50:04 +000018
19#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050020#include "incore.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000021#include "acl.h"
Steven Whitehouse307cf6e2009-08-26 18:51:04 +010022#include "xattr.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000023#include "glock.h"
24#include "inode.h"
25#include "meta_io.h"
26#include "quota.h"
27#include "rgrp.h"
Bob Peterson27c3b412017-08-18 09:15:13 -050028#include "super.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000029#include "trans.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050030#include "util.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000031
32/**
33 * ea_calc_size - returns the acutal number of bytes the request will take up
34 * (not counting any unstuffed data blocks)
35 * @sdp:
36 * @er:
37 * @size:
38 *
39 * Returns: 1 if the EA should be stuffed
40 */
41
Steven Whitehouse40b78a32009-08-26 18:41:32 +010042static int ea_calc_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize,
David Teiglandb3b94fa2006-01-16 16:50:04 +000043 unsigned int *size)
44{
Steven Whitehouse40b78a32009-08-26 18:41:32 +010045 unsigned int jbsize = sdp->sd_jbsize;
46
47 /* Stuffed */
48 *size = ALIGN(sizeof(struct gfs2_ea_header) + nsize + dsize, 8);
49
50 if (*size <= jbsize)
David Teiglandb3b94fa2006-01-16 16:50:04 +000051 return 1;
52
Steven Whitehouse40b78a32009-08-26 18:41:32 +010053 /* Unstuffed */
54 *size = ALIGN(sizeof(struct gfs2_ea_header) + nsize +
55 (sizeof(__be64) * DIV_ROUND_UP(dsize, jbsize)), 8);
David Teiglandb3b94fa2006-01-16 16:50:04 +000056
57 return 0;
58}
59
Steven Whitehouse40b78a32009-08-26 18:41:32 +010060static int ea_check_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize)
David Teiglandb3b94fa2006-01-16 16:50:04 +000061{
62 unsigned int size;
63
Steven Whitehouse40b78a32009-08-26 18:41:32 +010064 if (dsize > GFS2_EA_MAX_DATA_LEN)
David Teiglandb3b94fa2006-01-16 16:50:04 +000065 return -ERANGE;
66
Steven Whitehouse40b78a32009-08-26 18:41:32 +010067 ea_calc_size(sdp, nsize, dsize, &size);
David Teiglandb3b94fa2006-01-16 16:50:04 +000068
69 /* This can only happen with 512 byte blocks */
70 if (size > sdp->sd_jbsize)
71 return -ERANGE;
72
73 return 0;
74}
75
Steven Whitehousecca195c2006-09-05 13:15:18 -040076typedef int (*ea_call_t) (struct gfs2_inode *ip, struct buffer_head *bh,
David Teiglandb3b94fa2006-01-16 16:50:04 +000077 struct gfs2_ea_header *ea,
Steven Whitehousecca195c2006-09-05 13:15:18 -040078 struct gfs2_ea_header *prev, void *private);
David Teiglandb3b94fa2006-01-16 16:50:04 +000079
80static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
81 ea_call_t ea_call, void *data)
82{
83 struct gfs2_ea_header *ea, *prev = NULL;
84 int error = 0;
85
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -040086 if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_EA))
David Teiglandb3b94fa2006-01-16 16:50:04 +000087 return -EIO;
88
89 for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
90 if (!GFS2_EA_REC_LEN(ea))
91 goto fail;
Steven Whitehousecca195c2006-09-05 13:15:18 -040092 if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
93 bh->b_data + bh->b_size))
David Teiglandb3b94fa2006-01-16 16:50:04 +000094 goto fail;
95 if (!GFS2_EATYPE_VALID(ea->ea_type))
96 goto fail;
97
98 error = ea_call(ip, bh, ea, prev, data);
99 if (error)
100 return error;
101
102 if (GFS2_EA_IS_LAST(ea)) {
103 if ((char *)GFS2_EA2NEXT(ea) !=
104 bh->b_data + bh->b_size)
105 goto fail;
106 break;
107 }
108 }
109
110 return error;
111
Steven Whitehousea91ea692006-09-04 12:04:26 -0400112fail:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000113 gfs2_consist_inode(ip);
114 return -EIO;
115}
116
117static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
118{
119 struct buffer_head *bh, *eabh;
Al Virob44b84d2006-10-14 10:46:30 -0400120 __be64 *eablk, *end;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000121 int error;
122
Andreas Gruenbacherc8d57702015-11-11 15:00:35 -0600123 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000124 if (error)
125 return error;
126
Steven Whitehouse383f01f2008-11-04 10:05:22 +0000127 if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT)) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000128 error = ea_foreach_i(ip, bh, ea_call, data);
129 goto out;
130 }
131
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400132 if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_IN)) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000133 error = -EIO;
134 goto out;
135 }
136
Al Virob44b84d2006-10-14 10:46:30 -0400137 eablk = (__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header));
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400138 end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000139
140 for (; eablk < end; eablk++) {
Steven Whitehousecd915492006-09-04 12:49:07 -0400141 u64 bn;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000142
143 if (!*eablk)
144 break;
145 bn = be64_to_cpu(*eablk);
146
Andreas Gruenbacherc8d57702015-11-11 15:00:35 -0600147 error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, 0, &eabh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000148 if (error)
149 break;
150 error = ea_foreach_i(ip, eabh, ea_call, data);
151 brelse(eabh);
152 if (error)
153 break;
154 }
Steven Whitehousea91ea692006-09-04 12:04:26 -0400155out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000156 brelse(bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000157 return error;
158}
159
160struct ea_find {
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100161 int type;
162 const char *name;
163 size_t namel;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000164 struct gfs2_ea_location *ef_el;
165};
166
167static int ea_find_i(struct gfs2_inode *ip, struct buffer_head *bh,
168 struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
169 void *private)
170{
171 struct ea_find *ef = private;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000172
173 if (ea->ea_type == GFS2_EATYPE_UNUSED)
174 return 0;
175
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100176 if (ea->ea_type == ef->type) {
177 if (ea->ea_name_len == ef->namel &&
178 !memcmp(GFS2_EA2NAME(ea), ef->name, ea->ea_name_len)) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000179 struct gfs2_ea_location *el = ef->ef_el;
180 get_bh(bh);
181 el->el_bh = bh;
182 el->el_ea = ea;
183 el->el_prev = prev;
184 return 1;
185 }
186 }
187
David Teiglandb3b94fa2006-01-16 16:50:04 +0000188 return 0;
189}
190
Steven Whitehouse479c4272009-10-02 12:00:00 +0100191static int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
192 struct gfs2_ea_location *el)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000193{
194 struct ea_find ef;
195 int error;
196
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100197 ef.type = type;
198 ef.name = name;
199 ef.namel = strlen(name);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000200 ef.ef_el = el;
201
202 memset(el, 0, sizeof(struct gfs2_ea_location));
203
204 error = ea_foreach(ip, ea_find_i, &ef);
205 if (error > 0)
206 return 0;
207
208 return error;
209}
210
211/**
212 * ea_dealloc_unstuffed -
213 * @ip:
214 * @bh:
215 * @ea:
216 * @prev:
217 * @private:
218 *
219 * Take advantage of the fact that all unstuffed blocks are
220 * allocated from the same RG. But watch, this may not always
221 * be true.
222 *
223 * Returns: errno
224 */
225
226static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
227 struct gfs2_ea_header *ea,
228 struct gfs2_ea_header *prev, void *private)
229{
230 int *leave = private;
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400231 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000232 struct gfs2_rgrpd *rgd;
233 struct gfs2_holder rg_gh;
Al Virob44b84d2006-10-14 10:46:30 -0400234 __be64 *dataptrs;
235 u64 bn = 0;
Steven Whitehousecd915492006-09-04 12:49:07 -0400236 u64 bstart = 0;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000237 unsigned int blen = 0;
238 unsigned int blks = 0;
239 unsigned int x;
240 int error;
241
Bob Peterson5e2f7d62012-04-04 22:11:16 -0400242 error = gfs2_rindex_update(sdp);
243 if (error)
244 return error;
245
David Teiglandb3b94fa2006-01-16 16:50:04 +0000246 if (GFS2_EA_IS_STUFFED(ea))
247 return 0;
248
249 dataptrs = GFS2_EA2DATAPTRS(ea);
Steven Whitehousecca195c2006-09-05 13:15:18 -0400250 for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000251 if (*dataptrs) {
252 blks++;
253 bn = be64_to_cpu(*dataptrs);
254 }
Steven Whitehousecca195c2006-09-05 13:15:18 -0400255 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000256 if (!blks)
257 return 0;
258
Steven Whitehouse66fc0612012-02-08 12:58:32 +0000259 rgd = gfs2_blk2rgrpd(sdp, bn, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000260 if (!rgd) {
261 gfs2_consist_inode(ip);
262 return -EIO;
263 }
264
265 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
266 if (error)
267 return error;
268
Steven Whitehousebb8d8a62007-06-01 14:11:58 +0100269 error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE +
Steven Whitehousecca195c2006-09-05 13:15:18 -0400270 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000271 if (error)
272 goto out_gunlock;
273
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000274 gfs2_trans_add_meta(ip->i_gl, bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000275
276 dataptrs = GFS2_EA2DATAPTRS(ea);
277 for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
278 if (!*dataptrs)
279 break;
280 bn = be64_to_cpu(*dataptrs);
281
282 if (bstart + blen == bn)
283 blen++;
284 else {
285 if (bstart)
286 gfs2_free_meta(ip, bstart, blen);
287 bstart = bn;
288 blen = 1;
289 }
290
291 *dataptrs = 0;
Steven Whitehouse77658aa2008-02-12 14:17:27 +0000292 gfs2_add_inode_blocks(&ip->i_inode, -1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000293 }
294 if (bstart)
295 gfs2_free_meta(ip, bstart, blen);
296
297 if (prev && !leave) {
Steven Whitehousecd915492006-09-04 12:49:07 -0400298 u32 len;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000299
300 len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
301 prev->ea_rec_len = cpu_to_be32(len);
302
303 if (GFS2_EA_IS_LAST(ea))
304 prev->ea_flags |= GFS2_EAFLAG_LAST;
305 } else {
306 ea->ea_type = GFS2_EATYPE_UNUSED;
307 ea->ea_num_ptrs = 0;
308 }
309
Andreas Gruenbacher6862c442017-10-04 16:21:19 +0200310 ip->i_inode.i_ctime = current_time(&ip->i_inode);
Christoph Hellwig937d3302018-02-21 07:54:46 -0800311 __mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000312
313 gfs2_trans_end(sdp);
314
Steven Whitehousea91ea692006-09-04 12:04:26 -0400315out_gunlock:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000316 gfs2_glock_dq_uninit(&rg_gh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000317 return error;
318}
319
320static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
321 struct gfs2_ea_header *ea,
322 struct gfs2_ea_header *prev, int leave)
323{
David Teiglandb3b94fa2006-01-16 16:50:04 +0000324 int error;
325
Bob Peterson8e2e0042012-07-19 08:12:40 -0400326 error = gfs2_rindex_update(GFS2_SB(&ip->i_inode));
327 if (error)
328 return error;
329
Eric W. Biedermanf4108a62013-01-31 17:49:26 -0800330 error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000331 if (error)
332 goto out_alloc;
333
Steven Whitehousecca195c2006-09-05 13:15:18 -0400334 error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000335
David Teiglandb3b94fa2006-01-16 16:50:04 +0000336 gfs2_quota_unhold(ip);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400337out_alloc:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000338 return error;
339}
340
David Teiglandb3b94fa2006-01-16 16:50:04 +0000341struct ea_list {
342 struct gfs2_ea_request *ei_er;
343 unsigned int ei_size;
344};
345
346static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
347 struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
348 void *private)
349{
350 struct ea_list *ei = private;
351 struct gfs2_ea_request *er = ei->ei_er;
Andreas Gruenbacher21e21562018-08-03 10:57:52 +0100352 unsigned int ea_size;
353 char *prefix;
354 unsigned int l;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000355
356 if (ea->ea_type == GFS2_EATYPE_UNUSED)
357 return 0;
358
Andreas Gruenbacher21e21562018-08-03 10:57:52 +0100359 switch (ea->ea_type) {
360 case GFS2_EATYPE_USR:
361 prefix = "user.";
362 l = 5;
363 break;
364 case GFS2_EATYPE_SYS:
365 prefix = "system.";
366 l = 7;
367 break;
368 case GFS2_EATYPE_SECURITY:
369 prefix = "security.";
370 l = 9;
371 break;
372 default:
373 BUG();
374 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000375
Andreas Gruenbacher21e21562018-08-03 10:57:52 +0100376 ea_size = l + ea->ea_name_len + 1;
377 if (er->er_data_len) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000378 if (ei->ei_size + ea_size > er->er_data_len)
379 return -ERANGE;
380
Steven Whitehouse90cdd202006-05-22 10:36:25 -0400381 memcpy(er->er_data + ei->ei_size, prefix, l);
382 memcpy(er->er_data + ei->ei_size + l, GFS2_EA2NAME(ea),
David Teiglandb3b94fa2006-01-16 16:50:04 +0000383 ea->ea_name_len);
Andreas Gruenbacher21e21562018-08-03 10:57:52 +0100384 er->er_data[ei->ei_size + ea_size - 1] = 0;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000385 }
386
387 ei->ei_size += ea_size;
388
389 return 0;
390}
391
392/**
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100393 * gfs2_listxattr - List gfs2 extended attributes
394 * @dentry: The dentry whose inode we are interested in
395 * @buffer: The buffer to write the results
396 * @size: The size of the buffer
David Teiglandb3b94fa2006-01-16 16:50:04 +0000397 *
398 * Returns: actual size of data on success, -errno on error
399 */
400
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100401ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000402{
David Howells2b0143b2015-03-17 22:25:59 +0000403 struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100404 struct gfs2_ea_request er;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000405 struct gfs2_holder i_gh;
406 int error;
407
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100408 memset(&er, 0, sizeof(struct gfs2_ea_request));
409 if (size) {
410 er.er_data = buffer;
411 er.er_data_len = size;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000412 }
413
Steven Whitehousecca195c2006-09-05 13:15:18 -0400414 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000415 if (error)
416 return error;
417
Steven Whitehouse3767ac22008-11-03 14:28:42 +0000418 if (ip->i_eattr) {
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100419 struct ea_list ei = { .ei_er = &er, .ei_size = 0 };
David Teiglandb3b94fa2006-01-16 16:50:04 +0000420
421 error = ea_foreach(ip, ea_list_i, &ei);
422 if (!error)
423 error = ei.ei_size;
424 }
425
426 gfs2_glock_dq_uninit(&i_gh);
427
428 return error;
429}
430
431/**
Steven Whitehouse1f981692012-07-26 11:26:36 +0100432 * ea_iter_unstuffed - copies the unstuffed xattr data to/from the
433 * request buffer
Steven Whitehousecca195c2006-09-05 13:15:18 -0400434 * @ip: The GFS2 inode
435 * @ea: The extended attribute header structure
Steven Whitehouse1f981692012-07-26 11:26:36 +0100436 * @din: The data to be copied in
437 * @dout: The data to be copied out (one of din,dout will be NULL)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000438 *
439 * Returns: errno
440 */
441
Steven Whitehouse1f981692012-07-26 11:26:36 +0100442static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
443 const char *din, char *dout)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000444{
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400445 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000446 struct buffer_head **bh;
447 unsigned int amount = GFS2_EA_DATA_LEN(ea);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500448 unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
Al Virob44b84d2006-10-14 10:46:30 -0400449 __be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000450 unsigned int x;
451 int error = 0;
Steven Whitehouse1f981692012-07-26 11:26:36 +0100452 unsigned char *pos;
453 unsigned cp_size;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000454
Josef Bacik16c5f062008-04-09 09:33:41 -0400455 bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000456 if (!bh)
457 return -ENOMEM;
458
459 for (x = 0; x < nptrs; x++) {
Andreas Gruenbacherc8d57702015-11-11 15:00:35 -0600460 error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0, 0,
Steven Whitehouse7276b3b2006-09-21 17:05:23 -0400461 bh + x);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000462 if (error) {
463 while (x--)
464 brelse(bh[x]);
465 goto out;
466 }
467 dataptrs++;
468 }
469
470 for (x = 0; x < nptrs; x++) {
Steven Whitehouse7276b3b2006-09-21 17:05:23 -0400471 error = gfs2_meta_wait(sdp, bh[x]);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000472 if (error) {
473 for (; x < nptrs; x++)
474 brelse(bh[x]);
475 goto out;
476 }
477 if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
478 for (; x < nptrs; x++)
479 brelse(bh[x]);
480 error = -EIO;
481 goto out;
482 }
483
Steven Whitehouse1f981692012-07-26 11:26:36 +0100484 pos = bh[x]->b_data + sizeof(struct gfs2_meta_header);
485 cp_size = (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize;
486
487 if (dout) {
488 memcpy(dout, pos, cp_size);
489 dout += sdp->sd_jbsize;
490 }
491
492 if (din) {
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000493 gfs2_trans_add_meta(ip->i_gl, bh[x]);
Steven Whitehouse1f981692012-07-26 11:26:36 +0100494 memcpy(pos, din, cp_size);
495 din += sdp->sd_jbsize;
496 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000497
498 amount -= sdp->sd_jbsize;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000499 brelse(bh[x]);
500 }
501
Steven Whitehousea91ea692006-09-04 12:04:26 -0400502out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000503 kfree(bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000504 return error;
505}
506
Steven Whitehouse479c4272009-10-02 12:00:00 +0100507static int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
508 char *data, size_t size)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000509{
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100510 int ret;
511 size_t len = GFS2_EA_DATA_LEN(el->el_ea);
512 if (len > size)
513 return -ERANGE;
514
David Teiglandb3b94fa2006-01-16 16:50:04 +0000515 if (GFS2_EA_IS_STUFFED(el->el_ea)) {
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100516 memcpy(data, GFS2_EA2DATA(el->el_ea), len);
517 return len;
518 }
Steven Whitehouse1f981692012-07-26 11:26:36 +0100519 ret = gfs2_iter_unstuffed(ip, el->el_ea, NULL, data);
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100520 if (ret < 0)
521 return ret;
522 return len;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000523}
524
Steven Whitehouse479c4272009-10-02 12:00:00 +0100525int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **ppdata)
526{
527 struct gfs2_ea_location el;
528 int error;
529 int len;
530 char *data;
531
532 error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, &el);
533 if (error)
534 return error;
535 if (!el.el_ea)
536 goto out;
537 if (!GFS2_EA_DATA_LEN(el.el_ea))
538 goto out;
539
540 len = GFS2_EA_DATA_LEN(el.el_ea);
541 data = kmalloc(len, GFP_NOFS);
542 error = -ENOMEM;
543 if (data == NULL)
544 goto out;
545
546 error = gfs2_ea_get_copy(ip, &el, data, len);
Steven Whitehouse114b80c2011-11-09 12:54:43 +0000547 if (error < 0)
548 kfree(data);
549 else
550 *ppdata = data;
Steven Whitehouse479c4272009-10-02 12:00:00 +0100551out:
552 brelse(el.el_bh);
553 return error;
554}
555
David Teiglandb3b94fa2006-01-16 16:50:04 +0000556/**
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100557 * gfs2_xattr_get - Get a GFS2 extended attribute
558 * @inode: The inode
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100559 * @name: The name of the extended attribute
560 * @buffer: The buffer to write the result into
561 * @size: The size of the buffer
Christoph Hellwig431547b2009-11-13 09:52:56 +0000562 * @type: The type of extended attribute
David Teiglandb3b94fa2006-01-16 16:50:04 +0000563 *
564 * Returns: actual size of data on success, -errno on error
565 */
Al Viro1a39ba92016-05-13 03:59:17 +0200566static int __gfs2_xattr_get(struct inode *inode, const char *name,
567 void *buffer, size_t size, int type)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000568{
Al Virob2968212016-04-10 20:48:24 -0400569 struct gfs2_inode *ip = GFS2_I(inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000570 struct gfs2_ea_location el;
571 int error;
572
Steven Whitehouse3767ac22008-11-03 14:28:42 +0000573 if (!ip->i_eattr)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000574 return -ENODATA;
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100575 if (strlen(name) > GFS2_EA_MAX_NAME_LEN)
576 return -EINVAL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000577
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100578 error = gfs2_ea_find(ip, type, name, &el);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000579 if (error)
580 return error;
581 if (!el.el_ea)
582 return -ENODATA;
Steven Whitehouse86d00632009-09-14 09:50:57 +0100583 if (size)
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100584 error = gfs2_ea_get_copy(ip, &el, buffer, size);
585 else
David Teiglandb3b94fa2006-01-16 16:50:04 +0000586 error = GFS2_EA_DATA_LEN(el.el_ea);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000587 brelse(el.el_bh);
588
589 return error;
590}
591
Al Viro1a39ba92016-05-13 03:59:17 +0200592static int gfs2_xattr_get(const struct xattr_handler *handler,
593 struct dentry *unused, struct inode *inode,
594 const char *name, void *buffer, size_t size)
595{
596 struct gfs2_inode *ip = GFS2_I(inode);
597 struct gfs2_holder gh;
Al Viro1a39ba92016-05-13 03:59:17 +0200598 int ret;
599
600 /* During lookup, SELinux calls this function with the glock locked. */
601
602 if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
603 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
604 if (ret)
605 return ret;
Andreas Gruenbacherd0920a92017-10-13 00:39:38 +0200606 } else {
607 gfs2_holder_mark_uninitialized(&gh);
Al Viro1a39ba92016-05-13 03:59:17 +0200608 }
609 ret = __gfs2_xattr_get(inode, name, buffer, size, handler->flags);
Andreas Gruenbacherd0920a92017-10-13 00:39:38 +0200610 if (gfs2_holder_initialized(&gh))
Al Viro1a39ba92016-05-13 03:59:17 +0200611 gfs2_glock_dq_uninit(&gh);
612 return ret;
613}
614
David Teiglandb3b94fa2006-01-16 16:50:04 +0000615/**
David Teiglandb3b94fa2006-01-16 16:50:04 +0000616 * ea_alloc_blk - allocates a new block for extended attributes.
617 * @ip: A pointer to the inode that's getting extended attributes
Steven Whitehousecca195c2006-09-05 13:15:18 -0400618 * @bhp: Pointer to pointer to a struct buffer_head
David Teiglandb3b94fa2006-01-16 16:50:04 +0000619 *
620 * Returns: errno
621 */
622
623static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
624{
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400625 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000626 struct gfs2_ea_header *ea;
Steven Whitehouseb45e41d2008-02-06 10:11:15 +0000627 unsigned int n = 1;
Steven Whitehousecd915492006-09-04 12:49:07 -0400628 u64 block;
Steven Whitehouse09010972009-05-20 10:48:47 +0100629 int error;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000630
Bob Peterson6e87ed02011-11-18 10:58:32 -0500631 error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
Steven Whitehouse09010972009-05-20 10:48:47 +0100632 if (error)
633 return error;
Steven Whitehouse5731be52008-02-01 13:16:55 +0000634 gfs2_trans_add_unrevoke(sdp, block, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000635 *bhp = gfs2_meta_new(ip->i_gl, block);
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000636 gfs2_trans_add_meta(ip->i_gl, *bhp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000637 gfs2_metatype_set(*bhp, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
638 gfs2_buffer_clear_tail(*bhp, sizeof(struct gfs2_meta_header));
639
640 ea = GFS2_EA_BH2FIRST(*bhp);
641 ea->ea_rec_len = cpu_to_be32(sdp->sd_jbsize);
642 ea->ea_type = GFS2_EATYPE_UNUSED;
643 ea->ea_flags = GFS2_EAFLAG_LAST;
644 ea->ea_num_ptrs = 0;
645
Steven Whitehouse77658aa2008-02-12 14:17:27 +0000646 gfs2_add_inode_blocks(&ip->i_inode, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000647
648 return 0;
649}
650
651/**
652 * ea_write - writes the request info to an ea, creating new blocks if
653 * necessary
Steven Whitehousecca195c2006-09-05 13:15:18 -0400654 * @ip: inode that is being modified
655 * @ea: the location of the new ea in a block
David Teiglandb3b94fa2006-01-16 16:50:04 +0000656 * @er: the write request
657 *
658 * Note: does not update ea_rec_len or the GFS2_EAFLAG_LAST bin of ea_flags
659 *
660 * returns : errno
661 */
662
663static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
664 struct gfs2_ea_request *er)
665{
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400666 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
Steven Whitehouse09010972009-05-20 10:48:47 +0100667 int error;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000668
669 ea->ea_data_len = cpu_to_be32(er->er_data_len);
670 ea->ea_name_len = er->er_name_len;
671 ea->ea_type = er->er_type;
672 ea->__pad = 0;
673
674 memcpy(GFS2_EA2NAME(ea), er->er_name, er->er_name_len);
675
676 if (GFS2_EAREQ_SIZE_STUFFED(er) <= sdp->sd_jbsize) {
677 ea->ea_num_ptrs = 0;
678 memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len);
679 } else {
Al Virob44b84d2006-10-14 10:46:30 -0400680 __be64 *dataptr = GFS2_EA2DATAPTRS(ea);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000681 const char *data = er->er_data;
682 unsigned int data_len = er->er_data_len;
683 unsigned int copy;
684 unsigned int x;
685
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500686 ea->ea_num_ptrs = DIV_ROUND_UP(er->er_data_len, sdp->sd_jbsize);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000687 for (x = 0; x < ea->ea_num_ptrs; x++) {
688 struct buffer_head *bh;
Steven Whitehousecd915492006-09-04 12:49:07 -0400689 u64 block;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000690 int mh_size = sizeof(struct gfs2_meta_header);
Steven Whitehouseb45e41d2008-02-06 10:11:15 +0000691 unsigned int n = 1;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000692
Bob Peterson6e87ed02011-11-18 10:58:32 -0500693 error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
Steven Whitehouse09010972009-05-20 10:48:47 +0100694 if (error)
695 return error;
Steven Whitehouse5731be52008-02-01 13:16:55 +0000696 gfs2_trans_add_unrevoke(sdp, block, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000697 bh = gfs2_meta_new(ip->i_gl, block);
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000698 gfs2_trans_add_meta(ip->i_gl, bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000699 gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);
700
Steven Whitehouse77658aa2008-02-12 14:17:27 +0000701 gfs2_add_inode_blocks(&ip->i_inode, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000702
Steven Whitehousecca195c2006-09-05 13:15:18 -0400703 copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
704 data_len;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000705 memcpy(bh->b_data + mh_size, data, copy);
706 if (copy < sdp->sd_jbsize)
707 memset(bh->b_data + mh_size + copy, 0,
708 sdp->sd_jbsize - copy);
709
Steven Whitehousecca195c2006-09-05 13:15:18 -0400710 *dataptr++ = cpu_to_be64(bh->b_blocknr);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000711 data += copy;
712 data_len -= copy;
713
714 brelse(bh);
715 }
716
717 gfs2_assert_withdraw(sdp, !data_len);
718 }
719
720 return 0;
721}
722
723typedef int (*ea_skeleton_call_t) (struct gfs2_inode *ip,
Steven Whitehousecca195c2006-09-05 13:15:18 -0400724 struct gfs2_ea_request *er, void *private);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000725
726static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
727 unsigned int blks,
Steven Whitehousecca195c2006-09-05 13:15:18 -0400728 ea_skeleton_call_t skeleton_call, void *private)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000729{
Steven Whitehouse7b9cff42013-10-02 11:13:25 +0100730 struct gfs2_alloc_parms ap = { .target = blks };
David Teiglandb3b94fa2006-01-16 16:50:04 +0000731 int error;
732
Bob Peterson8e2e0042012-07-19 08:12:40 -0400733 error = gfs2_rindex_update(GFS2_SB(&ip->i_inode));
734 if (error)
735 return error;
736
Abhi Dasb8fbf472015-03-18 12:03:41 -0500737 error = gfs2_quota_lock_check(ip, &ap);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000738 if (error)
Bob Peterson5407e242012-05-18 09:28:23 -0400739 return error;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000740
Steven Whitehouse7b9cff42013-10-02 11:13:25 +0100741 error = gfs2_inplace_reserve(ip, &ap);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000742 if (error)
743 goto out_gunlock_q;
744
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400745 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
Steven Whitehouse71f890f2012-07-30 14:53:19 +0100746 blks + gfs2_rg_blocks(ip, blks) +
David Teiglandb3b94fa2006-01-16 16:50:04 +0000747 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
748 if (error)
749 goto out_ipres;
750
751 error = skeleton_call(ip, er, private);
752 if (error)
753 goto out_end_trans;
754
Andreas Gruenbacher6862c442017-10-04 16:21:19 +0200755 ip->i_inode.i_ctime = current_time(&ip->i_inode);
Christoph Hellwig937d3302018-02-21 07:54:46 -0800756 __mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000757
Steven Whitehousea91ea692006-09-04 12:04:26 -0400758out_end_trans:
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400759 gfs2_trans_end(GFS2_SB(&ip->i_inode));
Steven Whitehousea91ea692006-09-04 12:04:26 -0400760out_ipres:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000761 gfs2_inplace_release(ip);
Steven Whitehousea91ea692006-09-04 12:04:26 -0400762out_gunlock_q:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000763 gfs2_quota_unlock(ip);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000764 return error;
765}
766
767static int ea_init_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
768 void *private)
769{
770 struct buffer_head *bh;
771 int error;
772
773 error = ea_alloc_blk(ip, &bh);
774 if (error)
775 return error;
776
Steven Whitehouse3767ac22008-11-03 14:28:42 +0000777 ip->i_eattr = bh->b_blocknr;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000778 error = ea_write(ip, GFS2_EA_BH2FIRST(bh), er);
779
780 brelse(bh);
781
782 return error;
783}
784
785/**
786 * ea_init - initializes a new eattr block
787 * @ip:
788 * @er:
789 *
790 * Returns: errno
791 */
792
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100793static int ea_init(struct gfs2_inode *ip, int type, const char *name,
794 const void *data, size_t size)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000795{
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100796 struct gfs2_ea_request er;
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400797 unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000798 unsigned int blks = 1;
799
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100800 er.er_type = type;
801 er.er_name = name;
802 er.er_name_len = strlen(name);
803 er.er_data = (void *)data;
804 er.er_data_len = size;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000805
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100806 if (GFS2_EAREQ_SIZE_STUFFED(&er) > jbsize)
807 blks += DIV_ROUND_UP(er.er_data_len, jbsize);
808
809 return ea_alloc_skeleton(ip, &er, blks, ea_init_i, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000810}
811
812static struct gfs2_ea_header *ea_split_ea(struct gfs2_ea_header *ea)
813{
Steven Whitehousecd915492006-09-04 12:49:07 -0400814 u32 ea_size = GFS2_EA_SIZE(ea);
Steven Whitehouse568f4c92006-02-27 12:00:42 -0500815 struct gfs2_ea_header *new = (struct gfs2_ea_header *)((char *)ea +
816 ea_size);
Steven Whitehousecd915492006-09-04 12:49:07 -0400817 u32 new_size = GFS2_EA_REC_LEN(ea) - ea_size;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000818 int last = ea->ea_flags & GFS2_EAFLAG_LAST;
819
820 ea->ea_rec_len = cpu_to_be32(ea_size);
821 ea->ea_flags ^= last;
822
823 new->ea_rec_len = cpu_to_be32(new_size);
824 new->ea_flags = last;
825
826 return new;
827}
828
829static void ea_set_remove_stuffed(struct gfs2_inode *ip,
830 struct gfs2_ea_location *el)
831{
832 struct gfs2_ea_header *ea = el->el_ea;
833 struct gfs2_ea_header *prev = el->el_prev;
Steven Whitehousecd915492006-09-04 12:49:07 -0400834 u32 len;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000835
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000836 gfs2_trans_add_meta(ip->i_gl, el->el_bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000837
838 if (!prev || !GFS2_EA_IS_STUFFED(ea)) {
839 ea->ea_type = GFS2_EATYPE_UNUSED;
840 return;
841 } else if (GFS2_EA2NEXT(prev) != ea) {
842 prev = GFS2_EA2NEXT(prev);
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400843 gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), GFS2_EA2NEXT(prev) == ea);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000844 }
845
846 len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
847 prev->ea_rec_len = cpu_to_be32(len);
848
849 if (GFS2_EA_IS_LAST(ea))
850 prev->ea_flags |= GFS2_EAFLAG_LAST;
851}
852
853struct ea_set {
854 int ea_split;
855
856 struct gfs2_ea_request *es_er;
857 struct gfs2_ea_location *es_el;
858
859 struct buffer_head *es_bh;
860 struct gfs2_ea_header *es_ea;
861};
862
863static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
864 struct gfs2_ea_header *ea, struct ea_set *es)
865{
866 struct gfs2_ea_request *er = es->es_er;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000867 int error;
868
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400869 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000870 if (error)
871 return error;
872
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000873 gfs2_trans_add_meta(ip->i_gl, bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000874
875 if (es->ea_split)
876 ea = ea_split_ea(ea);
877
878 ea_write(ip, ea, er);
879
880 if (es->es_el)
881 ea_set_remove_stuffed(ip, es->es_el);
882
Deepa Dinamani078cd822016-09-14 07:48:04 -0700883 ip->i_inode.i_ctime = current_time(&ip->i_inode);
Christoph Hellwig937d3302018-02-21 07:54:46 -0800884 __mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
Andreas Gruenbacher6862c442017-10-04 16:21:19 +0200885
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400886 gfs2_trans_end(GFS2_SB(&ip->i_inode));
David Teiglandb3b94fa2006-01-16 16:50:04 +0000887 return error;
888}
889
890static int ea_set_simple_alloc(struct gfs2_inode *ip,
891 struct gfs2_ea_request *er, void *private)
892{
893 struct ea_set *es = private;
894 struct gfs2_ea_header *ea = es->es_ea;
895 int error;
896
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000897 gfs2_trans_add_meta(ip->i_gl, es->es_bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000898
899 if (es->ea_split)
900 ea = ea_split_ea(ea);
901
902 error = ea_write(ip, ea, er);
903 if (error)
904 return error;
905
906 if (es->es_el)
907 ea_set_remove_stuffed(ip, es->es_el);
908
909 return 0;
910}
911
912static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
913 struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
914 void *private)
915{
916 struct ea_set *es = private;
917 unsigned int size;
918 int stuffed;
919 int error;
920
Steven Whitehouse40b78a32009-08-26 18:41:32 +0100921 stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er->er_name_len,
922 es->es_er->er_data_len, &size);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000923
924 if (ea->ea_type == GFS2_EATYPE_UNUSED) {
925 if (GFS2_EA_REC_LEN(ea) < size)
926 return 0;
927 if (!GFS2_EA_IS_STUFFED(ea)) {
928 error = ea_remove_unstuffed(ip, bh, ea, prev, 1);
929 if (error)
930 return error;
931 }
932 es->ea_split = 0;
933 } else if (GFS2_EA_REC_LEN(ea) - GFS2_EA_SIZE(ea) >= size)
934 es->ea_split = 1;
935 else
936 return 0;
937
938 if (stuffed) {
939 error = ea_set_simple_noalloc(ip, bh, ea, es);
940 if (error)
941 return error;
942 } else {
943 unsigned int blks;
944
945 es->es_bh = bh;
946 es->es_ea = ea;
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500947 blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400948 GFS2_SB(&ip->i_inode)->sd_jbsize);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000949
950 error = ea_alloc_skeleton(ip, es->es_er, blks,
951 ea_set_simple_alloc, es);
952 if (error)
953 return error;
954 }
955
956 return 1;
957}
958
959static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
960 void *private)
961{
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400962 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000963 struct buffer_head *indbh, *newbh;
Al Virob44b84d2006-10-14 10:46:30 -0400964 __be64 *eablk;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000965 int error;
966 int mh_size = sizeof(struct gfs2_meta_header);
967
Steven Whitehouse383f01f2008-11-04 10:05:22 +0000968 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
Al Virob44b84d2006-10-14 10:46:30 -0400969 __be64 *end;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000970
Andreas Gruenbacherc8d57702015-11-11 15:00:35 -0600971 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0,
Steven Whitehouse7276b3b2006-09-21 17:05:23 -0400972 &indbh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000973 if (error)
974 return error;
975
976 if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
977 error = -EIO;
978 goto out;
979 }
980
Al Virob44b84d2006-10-14 10:46:30 -0400981 eablk = (__be64 *)(indbh->b_data + mh_size);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000982 end = eablk + sdp->sd_inptrs;
983
984 for (; eablk < end; eablk++)
985 if (!*eablk)
986 break;
987
988 if (eablk == end) {
989 error = -ENOSPC;
990 goto out;
991 }
992
Steven Whitehouse350a9b02012-12-14 12:36:02 +0000993 gfs2_trans_add_meta(ip->i_gl, indbh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000994 } else {
Steven Whitehousecd915492006-09-04 12:49:07 -0400995 u64 blk;
Steven Whitehouseb45e41d2008-02-06 10:11:15 +0000996 unsigned int n = 1;
Bob Peterson6e87ed02011-11-18 10:58:32 -0500997 error = gfs2_alloc_blocks(ip, &blk, &n, 0, NULL);
Steven Whitehouse09010972009-05-20 10:48:47 +0100998 if (error)
999 return error;
Steven Whitehouse5731be52008-02-01 13:16:55 +00001000 gfs2_trans_add_unrevoke(sdp, blk, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001001 indbh = gfs2_meta_new(ip->i_gl, blk);
Steven Whitehouse350a9b02012-12-14 12:36:02 +00001002 gfs2_trans_add_meta(ip->i_gl, indbh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001003 gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
1004 gfs2_buffer_clear_tail(indbh, mh_size);
1005
Al Virob44b84d2006-10-14 10:46:30 -04001006 eablk = (__be64 *)(indbh->b_data + mh_size);
Steven Whitehouse3767ac22008-11-03 14:28:42 +00001007 *eablk = cpu_to_be64(ip->i_eattr);
1008 ip->i_eattr = blk;
Steven Whitehouse383f01f2008-11-04 10:05:22 +00001009 ip->i_diskflags |= GFS2_DIF_EA_INDIRECT;
Steven Whitehouse77658aa2008-02-12 14:17:27 +00001010 gfs2_add_inode_blocks(&ip->i_inode, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001011
1012 eablk++;
1013 }
1014
1015 error = ea_alloc_blk(ip, &newbh);
1016 if (error)
1017 goto out;
1018
Steven Whitehousecd915492006-09-04 12:49:07 -04001019 *eablk = cpu_to_be64((u64)newbh->b_blocknr);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001020 error = ea_write(ip, GFS2_EA_BH2FIRST(newbh), er);
1021 brelse(newbh);
1022 if (error)
1023 goto out;
1024
1025 if (private)
Steven Whitehousecca195c2006-09-05 13:15:18 -04001026 ea_set_remove_stuffed(ip, private);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001027
Steven Whitehousea91ea692006-09-04 12:04:26 -04001028out:
David Teiglandb3b94fa2006-01-16 16:50:04 +00001029 brelse(indbh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001030 return error;
1031}
1032
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001033static int ea_set_i(struct gfs2_inode *ip, int type, const char *name,
1034 const void *value, size_t size, struct gfs2_ea_location *el)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001035{
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001036 struct gfs2_ea_request er;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001037 struct ea_set es;
1038 unsigned int blks = 2;
1039 int error;
1040
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001041 er.er_type = type;
1042 er.er_name = name;
1043 er.er_data = (void *)value;
1044 er.er_name_len = strlen(name);
1045 er.er_data_len = size;
1046
David Teiglandb3b94fa2006-01-16 16:50:04 +00001047 memset(&es, 0, sizeof(struct ea_set));
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001048 es.es_er = &er;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001049 es.es_el = el;
1050
1051 error = ea_foreach(ip, ea_set_simple, &es);
1052 if (error > 0)
1053 return 0;
1054 if (error)
1055 return error;
1056
Steven Whitehouse383f01f2008-11-04 10:05:22 +00001057 if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT))
David Teiglandb3b94fa2006-01-16 16:50:04 +00001058 blks++;
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001059 if (GFS2_EAREQ_SIZE_STUFFED(&er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
1060 blks += DIV_ROUND_UP(er.er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001061
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001062 return ea_alloc_skeleton(ip, &er, blks, ea_set_block, el);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001063}
1064
1065static int ea_set_remove_unstuffed(struct gfs2_inode *ip,
1066 struct gfs2_ea_location *el)
1067{
1068 if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
1069 el->el_prev = GFS2_EA2NEXT(el->el_prev);
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -04001070 gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
David Teiglandb3b94fa2006-01-16 16:50:04 +00001071 GFS2_EA2NEXT(el->el_prev) == el->el_ea);
1072 }
1073
Steven Whitehouse86d00632009-09-14 09:50:57 +01001074 return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001075}
1076
David Teiglandb3b94fa2006-01-16 16:50:04 +00001077static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
1078{
1079 struct gfs2_ea_header *ea = el->el_ea;
1080 struct gfs2_ea_header *prev = el->el_prev;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001081 int error;
1082
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -04001083 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001084 if (error)
1085 return error;
1086
Steven Whitehouse350a9b02012-12-14 12:36:02 +00001087 gfs2_trans_add_meta(ip->i_gl, el->el_bh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001088
1089 if (prev) {
Steven Whitehousecd915492006-09-04 12:49:07 -04001090 u32 len;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001091
1092 len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
1093 prev->ea_rec_len = cpu_to_be32(len);
1094
1095 if (GFS2_EA_IS_LAST(ea))
1096 prev->ea_flags |= GFS2_EAFLAG_LAST;
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001097 } else {
David Teiglandb3b94fa2006-01-16 16:50:04 +00001098 ea->ea_type = GFS2_EATYPE_UNUSED;
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001099 }
David Teiglandb3b94fa2006-01-16 16:50:04 +00001100
Andreas Gruenbacher6862c442017-10-04 16:21:19 +02001101 ip->i_inode.i_ctime = current_time(&ip->i_inode);
Christoph Hellwig937d3302018-02-21 07:54:46 -08001102 __mark_inode_dirty(&ip->i_inode, I_DIRTY_DATASYNC);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001103
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -04001104 gfs2_trans_end(GFS2_SB(&ip->i_inode));
David Teiglandb3b94fa2006-01-16 16:50:04 +00001105
1106 return error;
1107}
1108
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001109/**
1110 * gfs2_xattr_remove - Remove a GFS2 extended attribute
Christoph Hellwig431547b2009-11-13 09:52:56 +00001111 * @ip: The inode
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001112 * @type: The type of the extended attribute
1113 * @name: The name of the extended attribute
1114 *
1115 * This is not called directly by the VFS since we use the (common)
1116 * scheme of making a "set with NULL data" mean a remove request. Note
1117 * that this is different from a set with zero length data.
1118 *
1119 * Returns: 0, or errno on failure
1120 */
1121
Christoph Hellwig431547b2009-11-13 09:52:56 +00001122static int gfs2_xattr_remove(struct gfs2_inode *ip, int type, const char *name)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001123{
1124 struct gfs2_ea_location el;
1125 int error;
1126
Steven Whitehouse3767ac22008-11-03 14:28:42 +00001127 if (!ip->i_eattr)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001128 return -ENODATA;
1129
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001130 error = gfs2_ea_find(ip, type, name, &el);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001131 if (error)
1132 return error;
1133 if (!el.el_ea)
1134 return -ENODATA;
1135
1136 if (GFS2_EA_IS_STUFFED(el.el_ea))
1137 error = ea_remove_stuffed(ip, &el);
1138 else
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001139 error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001140
1141 brelse(el.el_bh);
1142
1143 return error;
1144}
1145
1146/**
Christoph Hellwig431547b2009-11-13 09:52:56 +00001147 * __gfs2_xattr_set - Set (or remove) a GFS2 extended attribute
1148 * @ip: The inode
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001149 * @name: The name of the extended attribute
1150 * @value: The value of the extended attribute (NULL for remove)
1151 * @size: The size of the @value argument
1152 * @flags: Create or Replace
Christoph Hellwig431547b2009-11-13 09:52:56 +00001153 * @type: The type of the extended attribute
David Teiglandb3b94fa2006-01-16 16:50:04 +00001154 *
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001155 * See gfs2_xattr_remove() for details of the removal of xattrs.
1156 *
1157 * Returns: 0 or errno on failure
David Teiglandb3b94fa2006-01-16 16:50:04 +00001158 */
1159
Christoph Hellwig431547b2009-11-13 09:52:56 +00001160int __gfs2_xattr_set(struct inode *inode, const char *name,
1161 const void *value, size_t size, int flags, int type)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001162{
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001163 struct gfs2_inode *ip = GFS2_I(inode);
Christoph Hellwig431547b2009-11-13 09:52:56 +00001164 struct gfs2_sbd *sdp = GFS2_SB(inode);
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001165 struct gfs2_ea_location el;
1166 unsigned int namel = strlen(name);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001167 int error;
1168
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001169 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1170 return -EPERM;
1171 if (namel > GFS2_EA_MAX_NAME_LEN)
1172 return -ERANGE;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001173
Ernesto A. Fernández54aae142017-08-30 07:26:30 -05001174 if (value == NULL) {
1175 error = gfs2_xattr_remove(ip, type, name);
1176 if (error == -ENODATA && !(flags & XATTR_REPLACE))
1177 error = 0;
1178 return error;
1179 }
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001180
1181 if (ea_check_size(sdp, namel, size))
1182 return -ERANGE;
1183
1184 if (!ip->i_eattr) {
1185 if (flags & XATTR_REPLACE)
1186 return -ENODATA;
1187 return ea_init(ip, type, name, value, size);
1188 }
1189
1190 error = gfs2_ea_find(ip, type, name, &el);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001191 if (error)
1192 return error;
1193
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001194 if (el.el_ea) {
1195 if (ip->i_diskflags & GFS2_DIF_APPENDONLY) {
1196 brelse(el.el_bh);
1197 return -EPERM;
1198 }
David Teiglandb3b94fa2006-01-16 16:50:04 +00001199
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001200 error = -EEXIST;
1201 if (!(flags & XATTR_CREATE)) {
1202 int unstuffed = !GFS2_EA_IS_STUFFED(el.el_ea);
1203 error = ea_set_i(ip, type, name, value, size, &el);
1204 if (!error && unstuffed)
1205 ea_set_remove_unstuffed(ip, &el);
1206 }
1207
1208 brelse(el.el_bh);
1209 return error;
1210 }
1211
1212 error = -ENODATA;
1213 if (!(flags & XATTR_REPLACE))
1214 error = ea_set_i(ip, type, name, value, size, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001215
1216 return error;
1217}
1218
Andreas Gruenbacherd9a82a02015-10-04 19:18:51 +02001219static int gfs2_xattr_set(const struct xattr_handler *handler,
Al Viro59301222016-05-27 10:19:30 -04001220 struct dentry *unused, struct inode *inode,
1221 const char *name, const void *value,
1222 size_t size, int flags)
Christoph Hellwig431547b2009-11-13 09:52:56 +00001223{
Al Viro1a39ba92016-05-13 03:59:17 +02001224 struct gfs2_inode *ip = GFS2_I(inode);
1225 struct gfs2_holder gh;
1226 int ret;
1227
1228 ret = gfs2_rsqa_alloc(ip);
1229 if (ret)
1230 return ret;
1231
Andreas Gruenbacherd0920a92017-10-13 00:39:38 +02001232 /* May be called from gfs_setattr with the glock locked. */
1233
1234 if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
1235 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
1236 if (ret)
1237 return ret;
1238 } else {
1239 if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE))
1240 return -EIO;
1241 gfs2_holder_mark_uninitialized(&gh);
1242 }
Al Viro1a39ba92016-05-13 03:59:17 +02001243 ret = __gfs2_xattr_set(inode, name, value, size, flags, handler->flags);
Andreas Gruenbacherd0920a92017-10-13 00:39:38 +02001244 if (gfs2_holder_initialized(&gh))
1245 gfs2_glock_dq_uninit(&gh);
Al Viro1a39ba92016-05-13 03:59:17 +02001246 return ret;
Christoph Hellwig431547b2009-11-13 09:52:56 +00001247}
1248
David Teiglandb3b94fa2006-01-16 16:50:04 +00001249static int ea_dealloc_indirect(struct gfs2_inode *ip)
1250{
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -04001251 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001252 struct gfs2_rgrp_list rlist;
1253 struct buffer_head *indbh, *dibh;
Al Virob44b84d2006-10-14 10:46:30 -04001254 __be64 *eablk, *end;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001255 unsigned int rg_blocks = 0;
Steven Whitehousecd915492006-09-04 12:49:07 -04001256 u64 bstart = 0;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001257 unsigned int blen = 0;
1258 unsigned int blks = 0;
1259 unsigned int x;
1260 int error;
1261
Bob Peterson5e2f7d62012-04-04 22:11:16 -04001262 error = gfs2_rindex_update(sdp);
1263 if (error)
1264 return error;
1265
David Teiglandb3b94fa2006-01-16 16:50:04 +00001266 memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
1267
Andreas Gruenbacherc8d57702015-11-11 15:00:35 -06001268 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &indbh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001269 if (error)
1270 return error;
1271
1272 if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
1273 error = -EIO;
1274 goto out;
1275 }
1276
Al Virob44b84d2006-10-14 10:46:30 -04001277 eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
David Teiglandb3b94fa2006-01-16 16:50:04 +00001278 end = eablk + sdp->sd_inptrs;
1279
1280 for (; eablk < end; eablk++) {
Steven Whitehousecd915492006-09-04 12:49:07 -04001281 u64 bn;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001282
1283 if (!*eablk)
1284 break;
1285 bn = be64_to_cpu(*eablk);
1286
1287 if (bstart + blen == bn)
1288 blen++;
1289 else {
1290 if (bstart)
Steven Whitehouse70b0c362011-09-02 16:08:09 +01001291 gfs2_rlist_add(ip, &rlist, bstart);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001292 bstart = bn;
1293 blen = 1;
1294 }
1295 blks++;
1296 }
1297 if (bstart)
Steven Whitehouse70b0c362011-09-02 16:08:09 +01001298 gfs2_rlist_add(ip, &rlist, bstart);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001299 else
1300 goto out;
1301
Bob Petersonc3abc292018-10-04 00:06:23 +01001302 gfs2_rlist_alloc(&rlist);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001303
1304 for (x = 0; x < rlist.rl_rgrps; x++) {
Andreas Gruenbacher6f6597ba2017-06-30 07:55:08 -05001305 struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(rlist.rl_ghs[x].gh_gl);
1306
Steven Whitehousebb8d8a62007-06-01 14:11:58 +01001307 rg_blocks += rgd->rd_length;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001308 }
1309
1310 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
1311 if (error)
1312 goto out_rlist_free;
1313
Steven Whitehousecca195c2006-09-05 13:15:18 -04001314 error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + RES_INDIRECT +
1315 RES_STATFS + RES_QUOTA, blks);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001316 if (error)
1317 goto out_gunlock;
1318
Steven Whitehouse350a9b02012-12-14 12:36:02 +00001319 gfs2_trans_add_meta(ip->i_gl, indbh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001320
Al Virob44b84d2006-10-14 10:46:30 -04001321 eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
David Teiglandb3b94fa2006-01-16 16:50:04 +00001322 bstart = 0;
1323 blen = 0;
1324
1325 for (; eablk < end; eablk++) {
Steven Whitehousecd915492006-09-04 12:49:07 -04001326 u64 bn;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001327
1328 if (!*eablk)
1329 break;
1330 bn = be64_to_cpu(*eablk);
1331
1332 if (bstart + blen == bn)
1333 blen++;
1334 else {
1335 if (bstart)
1336 gfs2_free_meta(ip, bstart, blen);
1337 bstart = bn;
1338 blen = 1;
1339 }
1340
1341 *eablk = 0;
Steven Whitehouse77658aa2008-02-12 14:17:27 +00001342 gfs2_add_inode_blocks(&ip->i_inode, -1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001343 }
1344 if (bstart)
1345 gfs2_free_meta(ip, bstart, blen);
1346
Steven Whitehouse383f01f2008-11-04 10:05:22 +00001347 ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001348
1349 error = gfs2_meta_inode_buffer(ip, &dibh);
1350 if (!error) {
Steven Whitehouse350a9b02012-12-14 12:36:02 +00001351 gfs2_trans_add_meta(ip->i_gl, dibh);
Steven Whitehouse539e5d62006-10-31 15:07:05 -05001352 gfs2_dinode_out(ip, dibh->b_data);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001353 brelse(dibh);
1354 }
1355
1356 gfs2_trans_end(sdp);
1357
Steven Whitehousea91ea692006-09-04 12:04:26 -04001358out_gunlock:
David Teiglandb3b94fa2006-01-16 16:50:04 +00001359 gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
Steven Whitehousea91ea692006-09-04 12:04:26 -04001360out_rlist_free:
David Teiglandb3b94fa2006-01-16 16:50:04 +00001361 gfs2_rlist_free(&rlist);
Steven Whitehousea91ea692006-09-04 12:04:26 -04001362out:
David Teiglandb3b94fa2006-01-16 16:50:04 +00001363 brelse(indbh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001364 return error;
1365}
1366
1367static int ea_dealloc_block(struct gfs2_inode *ip)
1368{
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -04001369 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001370 struct gfs2_rgrpd *rgd;
1371 struct buffer_head *dibh;
Bob Peterson564e12b2011-11-21 13:36:17 -05001372 struct gfs2_holder gh;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001373 int error;
1374
Bob Peterson5e2f7d62012-04-04 22:11:16 -04001375 error = gfs2_rindex_update(sdp);
1376 if (error)
1377 return error;
1378
Steven Whitehouse66fc0612012-02-08 12:58:32 +00001379 rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001380 if (!rgd) {
1381 gfs2_consist_inode(ip);
1382 return -EIO;
1383 }
1384
Bob Peterson564e12b2011-11-21 13:36:17 -05001385 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001386 if (error)
1387 return error;
1388
Steven Whitehousecca195c2006-09-05 13:15:18 -04001389 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_DINODE + RES_STATFS +
1390 RES_QUOTA, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001391 if (error)
1392 goto out_gunlock;
1393
Steven Whitehouse3767ac22008-11-03 14:28:42 +00001394 gfs2_free_meta(ip, ip->i_eattr, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001395
Steven Whitehouse3767ac22008-11-03 14:28:42 +00001396 ip->i_eattr = 0;
Steven Whitehouse77658aa2008-02-12 14:17:27 +00001397 gfs2_add_inode_blocks(&ip->i_inode, -1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001398
1399 error = gfs2_meta_inode_buffer(ip, &dibh);
1400 if (!error) {
Steven Whitehouse350a9b02012-12-14 12:36:02 +00001401 gfs2_trans_add_meta(ip->i_gl, dibh);
Steven Whitehouse539e5d62006-10-31 15:07:05 -05001402 gfs2_dinode_out(ip, dibh->b_data);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001403 brelse(dibh);
1404 }
1405
1406 gfs2_trans_end(sdp);
1407
Steven Whitehousea91ea692006-09-04 12:04:26 -04001408out_gunlock:
Bob Peterson564e12b2011-11-21 13:36:17 -05001409 gfs2_glock_dq_uninit(&gh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001410 return error;
1411}
1412
1413/**
1414 * gfs2_ea_dealloc - deallocate the extended attribute fork
1415 * @ip: the inode
1416 *
1417 * Returns: errno
1418 */
1419
1420int gfs2_ea_dealloc(struct gfs2_inode *ip)
1421{
David Teiglandb3b94fa2006-01-16 16:50:04 +00001422 int error;
1423
Bob Peterson8e2e0042012-07-19 08:12:40 -04001424 error = gfs2_rindex_update(GFS2_SB(&ip->i_inode));
1425 if (error)
1426 return error;
1427
Eric W. Biedermanf4108a62013-01-31 17:49:26 -08001428 error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001429 if (error)
Bob Peterson5407e242012-05-18 09:28:23 -04001430 return error;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001431
David Teiglandb3b94fa2006-01-16 16:50:04 +00001432 error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
1433 if (error)
Steven Whitehouse8339ee52011-08-31 16:38:29 +01001434 goto out_quota;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001435
Steven Whitehouse383f01f2008-11-04 10:05:22 +00001436 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
David Teiglandb3b94fa2006-01-16 16:50:04 +00001437 error = ea_dealloc_indirect(ip);
1438 if (error)
Steven Whitehouse8339ee52011-08-31 16:38:29 +01001439 goto out_quota;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001440 }
1441
1442 error = ea_dealloc_block(ip);
1443
Steven Whitehousea91ea692006-09-04 12:04:26 -04001444out_quota:
David Teiglandb3b94fa2006-01-16 16:50:04 +00001445 gfs2_quota_unhold(ip);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001446 return error;
1447}
1448
Stephen Hemmingerb7bb0a12010-05-13 17:53:23 -07001449static const struct xattr_handler gfs2_xattr_user_handler = {
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001450 .prefix = XATTR_USER_PREFIX,
Christoph Hellwig431547b2009-11-13 09:52:56 +00001451 .flags = GFS2_EATYPE_USR,
1452 .get = gfs2_xattr_get,
1453 .set = gfs2_xattr_set,
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001454};
1455
Stephen Hemmingerb7bb0a12010-05-13 17:53:23 -07001456static const struct xattr_handler gfs2_xattr_security_handler = {
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001457 .prefix = XATTR_SECURITY_PREFIX,
Christoph Hellwig431547b2009-11-13 09:52:56 +00001458 .flags = GFS2_EATYPE_SECURITY,
1459 .get = gfs2_xattr_get,
1460 .set = gfs2_xattr_set,
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001461};
1462
Stephen Hemmingerb7bb0a12010-05-13 17:53:23 -07001463const struct xattr_handler *gfs2_xattr_handlers[] = {
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001464 &gfs2_xattr_user_handler,
1465 &gfs2_xattr_security_handler,
Christoph Hellwige01580b2013-12-20 05:16:52 -08001466 &posix_acl_access_xattr_handler,
1467 &posix_acl_default_xattr_handler,
Steven Whitehouse40b78a32009-08-26 18:41:32 +01001468 NULL,
1469};
1470