xattr.c 32.6 KB
Newer Older
D
David Teigland 已提交
1 2
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
D
David Teigland 已提交
4 5 6
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
7
 * of the GNU General Public License version 2.
D
David Teigland 已提交
8 9 10 11 12 13 14
 */

#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/xattr.h>
15
#include <linux/gfs2_ondisk.h>
16
#include <linux/posix_acl_xattr.h>
D
David Teigland 已提交
17 18 19
#include <asm/uaccess.h>

#include "gfs2.h"
20
#include "incore.h"
D
David Teigland 已提交
21
#include "acl.h"
22
#include "xattr.h"
D
David Teigland 已提交
23 24 25 26 27 28
#include "glock.h"
#include "inode.h"
#include "meta_io.h"
#include "quota.h"
#include "rgrp.h"
#include "trans.h"
29
#include "util.h"
D
David Teigland 已提交
30 31 32 33 34 35 36 37 38 39 40

/**
 * ea_calc_size - returns the acutal number of bytes the request will take up
 *                (not counting any unstuffed data blocks)
 * @sdp:
 * @er:
 * @size:
 *
 * Returns: 1 if the EA should be stuffed
 */

41
static int ea_calc_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize,
D
David Teigland 已提交
42 43
			unsigned int *size)
{
44 45 46 47 48 49
	unsigned int jbsize = sdp->sd_jbsize;

	/* Stuffed */
	*size = ALIGN(sizeof(struct gfs2_ea_header) + nsize + dsize, 8);

	if (*size <= jbsize)
D
David Teigland 已提交
50 51
		return 1;

52 53 54
	/* Unstuffed */
	*size = ALIGN(sizeof(struct gfs2_ea_header) + nsize +
		      (sizeof(__be64) * DIV_ROUND_UP(dsize, jbsize)), 8);
D
David Teigland 已提交
55 56 57 58

	return 0;
}

59
static int ea_check_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize)
D
David Teigland 已提交
60 61 62
{
	unsigned int size;

63
	if (dsize > GFS2_EA_MAX_DATA_LEN)
D
David Teigland 已提交
64 65
		return -ERANGE;

66
	ea_calc_size(sdp, nsize, dsize, &size);
D
David Teigland 已提交
67 68 69 70 71 72 73 74

	/* This can only happen with 512 byte blocks */
	if (size > sdp->sd_jbsize)
		return -ERANGE;

	return 0;
}

75
typedef int (*ea_call_t) (struct gfs2_inode *ip, struct buffer_head *bh,
D
David Teigland 已提交
76
			  struct gfs2_ea_header *ea,
77
			  struct gfs2_ea_header *prev, void *private);
D
David Teigland 已提交
78 79 80 81 82 83 84

static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
			ea_call_t ea_call, void *data)
{
	struct gfs2_ea_header *ea, *prev = NULL;
	int error = 0;

85
	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_EA))
D
David Teigland 已提交
86 87 88 89 90
		return -EIO;

	for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
		if (!GFS2_EA_REC_LEN(ea))
			goto fail;
91 92
		if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
						  bh->b_data + bh->b_size))
D
David Teigland 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
			goto fail;
		if (!GFS2_EATYPE_VALID(ea->ea_type))
			goto fail;

		error = ea_call(ip, bh, ea, prev, data);
		if (error)
			return error;

		if (GFS2_EA_IS_LAST(ea)) {
			if ((char *)GFS2_EA2NEXT(ea) !=
			    bh->b_data + bh->b_size)
				goto fail;
			break;
		}
	}

	return error;

111
fail:
D
David Teigland 已提交
112 113 114 115 116 117 118
	gfs2_consist_inode(ip);
	return -EIO;
}

static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
{
	struct buffer_head *bh, *eabh;
A
Al Viro 已提交
119
	__be64 *eablk, *end;
D
David Teigland 已提交
120 121
	int error;

122
	error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &bh);
D
David Teigland 已提交
123 124 125
	if (error)
		return error;

126
	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT)) {
D
David Teigland 已提交
127 128 129 130
		error = ea_foreach_i(ip, bh, ea_call, data);
		goto out;
	}

131
	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_IN)) {
D
David Teigland 已提交
132 133 134 135
		error = -EIO;
		goto out;
	}

A
Al Viro 已提交
136
	eablk = (__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header));
137
	end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs;
D
David Teigland 已提交
138 139

	for (; eablk < end; eablk++) {
140
		u64 bn;
D
David Teigland 已提交
141 142 143 144 145

		if (!*eablk)
			break;
		bn = be64_to_cpu(*eablk);

S
Steven Whitehouse 已提交
146
		error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, &eabh);
D
David Teigland 已提交
147 148 149 150 151 152 153
		if (error)
			break;
		error = ea_foreach_i(ip, eabh, ea_call, data);
		brelse(eabh);
		if (error)
			break;
	}
154
out:
D
David Teigland 已提交
155 156 157 158 159
	brelse(bh);
	return error;
}

struct ea_find {
160 161 162
	int type;
	const char *name;
	size_t namel;
D
David Teigland 已提交
163 164 165 166 167 168 169 170 171 172 173 174
	struct gfs2_ea_location *ef_el;
};

static int ea_find_i(struct gfs2_inode *ip, struct buffer_head *bh,
		     struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
		     void *private)
{
	struct ea_find *ef = private;

	if (ea->ea_type == GFS2_EATYPE_UNUSED)
		return 0;

175 176 177
	if (ea->ea_type == ef->type) {
		if (ea->ea_name_len == ef->namel &&
		    !memcmp(GFS2_EA2NAME(ea), ef->name, ea->ea_name_len)) {
D
David Teigland 已提交
178 179 180 181 182 183 184 185 186 187 188 189
			struct gfs2_ea_location *el = ef->ef_el;
			get_bh(bh);
			el->el_bh = bh;
			el->el_ea = ea;
			el->el_prev = prev;
			return 1;
		}
	}

	return 0;
}

S
Steven Whitehouse 已提交
190 191
static int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
			struct gfs2_ea_location *el)
D
David Teigland 已提交
192 193 194 195
{
	struct ea_find ef;
	int error;

196 197 198
	ef.type = type;
	ef.name = name;
	ef.namel = strlen(name);
D
David Teigland 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
	ef.ef_el = el;

	memset(el, 0, sizeof(struct gfs2_ea_location));

	error = ea_foreach(ip, ea_find_i, &ef);
	if (error > 0)
		return 0;

	return error;
}

/**
 * ea_dealloc_unstuffed -
 * @ip:
 * @bh:
 * @ea:
 * @prev:
 * @private:
 *
 * Take advantage of the fact that all unstuffed blocks are
 * allocated from the same RG.  But watch, this may not always
 * be true.
 *
 * Returns: errno
 */

static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
				struct gfs2_ea_header *ea,
				struct gfs2_ea_header *prev, void *private)
{
	int *leave = private;
230
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
231 232 233
	struct gfs2_rgrpd *rgd;
	struct gfs2_holder rg_gh;
	struct buffer_head *dibh;
A
Al Viro 已提交
234 235
	__be64 *dataptrs;
	u64 bn = 0;
236
	u64 bstart = 0;
D
David Teigland 已提交
237 238 239 240 241
	unsigned int blen = 0;
	unsigned int blks = 0;
	unsigned int x;
	int error;

242 243 244 245
	error = gfs2_rindex_update(sdp);
	if (error)
		return error;

D
David Teigland 已提交
246 247 248 249
	if (GFS2_EA_IS_STUFFED(ea))
		return 0;

	dataptrs = GFS2_EA2DATAPTRS(ea);
250
	for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
D
David Teigland 已提交
251 252 253 254
		if (*dataptrs) {
			blks++;
			bn = be64_to_cpu(*dataptrs);
		}
255
	}
D
David Teigland 已提交
256 257 258
	if (!blks)
		return 0;

S
Steven Whitehouse 已提交
259
	rgd = gfs2_blk2rgrpd(sdp, bn, 1);
D
David Teigland 已提交
260 261 262 263 264 265 266 267 268
	if (!rgd) {
		gfs2_consist_inode(ip);
		return -EIO;
	}

	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
	if (error)
		return error;

269
	error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE +
270
				 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
D
David Teigland 已提交
271 272 273
	if (error)
		goto out_gunlock;

274
	gfs2_trans_add_meta(ip->i_gl, bh);
D
David Teigland 已提交
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291

	dataptrs = GFS2_EA2DATAPTRS(ea);
	for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
		if (!*dataptrs)
			break;
		bn = be64_to_cpu(*dataptrs);

		if (bstart + blen == bn)
			blen++;
		else {
			if (bstart)
				gfs2_free_meta(ip, bstart, blen);
			bstart = bn;
			blen = 1;
		}

		*dataptrs = 0;
292
		gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
293 294 295 296 297
	}
	if (bstart)
		gfs2_free_meta(ip, bstart, blen);

	if (prev && !leave) {
298
		u32 len;
D
David Teigland 已提交
299 300 301 302 303 304 305 306 307 308 309 310 311

		len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
		prev->ea_rec_len = cpu_to_be32(len);

		if (GFS2_EA_IS_LAST(ea))
			prev->ea_flags |= GFS2_EAFLAG_LAST;
	} else {
		ea->ea_type = GFS2_EATYPE_UNUSED;
		ea->ea_num_ptrs = 0;
	}

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
312
		ip->i_inode.i_ctime = CURRENT_TIME;
313
		gfs2_trans_add_meta(ip->i_gl, dibh);
314
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
315 316 317 318 319
		brelse(dibh);
	}

	gfs2_trans_end(sdp);

320
out_gunlock:
D
David Teigland 已提交
321 322 323 324 325 326 327 328 329 330
	gfs2_glock_dq_uninit(&rg_gh);
	return error;
}

static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
			       struct gfs2_ea_header *ea,
			       struct gfs2_ea_header *prev, int leave)
{
	int error;

B
Bob Peterson 已提交
331 332 333 334
	error = gfs2_rindex_update(GFS2_SB(&ip->i_inode));
	if (error)
		return error;

335
	error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
D
David Teigland 已提交
336 337 338
	if (error)
		goto out_alloc;

339
	error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL);
D
David Teigland 已提交
340 341

	gfs2_quota_unhold(ip);
342
out_alloc:
D
David Teigland 已提交
343 344 345 346 347 348 349 350
	return error;
}

struct ea_list {
	struct gfs2_ea_request *ei_er;
	unsigned int ei_size;
};

351 352 353 354 355 356 357 358 359 360 361 362 363 364
static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea)
{
	switch (ea->ea_type) {
	case GFS2_EATYPE_USR:
		return 5 + ea->ea_name_len + 1;
	case GFS2_EATYPE_SYS:
		return 7 + ea->ea_name_len + 1;
	case GFS2_EATYPE_SECURITY:
		return 9 + ea->ea_name_len + 1;
	default:
		return 0;
	}
}

D
David Teigland 已提交
365 366 367 368 369 370
static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
		     struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
		     void *private)
{
	struct ea_list *ei = private;
	struct gfs2_ea_request *er = ei->ei_er;
R
Ryan O'Hara 已提交
371
	unsigned int ea_size = gfs2_ea_strlen(ea);
D
David Teigland 已提交
372 373 374 375 376

	if (ea->ea_type == GFS2_EATYPE_UNUSED)
		return 0;

	if (er->er_data_len) {
377 378
		char *prefix = NULL;
		unsigned int l = 0;
D
David Teigland 已提交
379 380 381 382 383
		char c = 0;

		if (ei->ei_size + ea_size > er->er_data_len)
			return -ERANGE;

R
Ryan O'Hara 已提交
384 385
		switch (ea->ea_type) {
		case GFS2_EATYPE_USR:
D
David Teigland 已提交
386 387
			prefix = "user.";
			l = 5;
R
Ryan O'Hara 已提交
388 389
			break;
		case GFS2_EATYPE_SYS:
D
David Teigland 已提交
390 391
			prefix = "system.";
			l = 7;
R
Ryan O'Hara 已提交
392 393 394 395 396
			break;
		case GFS2_EATYPE_SECURITY:
			prefix = "security.";
			l = 9;
			break;
D
David Teigland 已提交
397 398
		}

399 400
		BUG_ON(l == 0);

401 402
		memcpy(er->er_data + ei->ei_size, prefix, l);
		memcpy(er->er_data + ei->ei_size + l, GFS2_EA2NAME(ea),
D
David Teigland 已提交
403
		       ea->ea_name_len);
404
		memcpy(er->er_data + ei->ei_size + ea_size - 1, &c, 1);
D
David Teigland 已提交
405 406 407 408 409 410 411 412
	}

	ei->ei_size += ea_size;

	return 0;
}

/**
413 414 415 416
 * gfs2_listxattr - List gfs2 extended attributes
 * @dentry: The dentry whose inode we are interested in
 * @buffer: The buffer to write the results
 * @size: The size of the buffer
D
David Teigland 已提交
417 418 419 420
 *
 * Returns: actual size of data on success, -errno on error
 */

421
ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
D
David Teigland 已提交
422
{
423
	struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
424
	struct gfs2_ea_request er;
D
David Teigland 已提交
425 426 427
	struct gfs2_holder i_gh;
	int error;

428 429 430 431
	memset(&er, 0, sizeof(struct gfs2_ea_request));
	if (size) {
		er.er_data = buffer;
		er.er_data_len = size;
D
David Teigland 已提交
432 433
	}

434
	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
D
David Teigland 已提交
435 436 437
	if (error)
		return error;

438
	if (ip->i_eattr) {
439
		struct ea_list ei = { .ei_er = &er, .ei_size = 0 };
D
David Teigland 已提交
440 441 442 443 444 445 446 447 448 449 450 451

		error = ea_foreach(ip, ea_list_i, &ei);
		if (!error)
			error = ei.ei_size;
	}

	gfs2_glock_dq_uninit(&i_gh);

	return error;
}

/**
452 453
 * ea_iter_unstuffed - copies the unstuffed xattr data to/from the
 *                     request buffer
454 455
 * @ip: The GFS2 inode
 * @ea: The extended attribute header structure
456 457
 * @din: The data to be copied in
 * @dout: The data to be copied out (one of din,dout will be NULL)
D
David Teigland 已提交
458 459 460 461
 *
 * Returns: errno
 */

462 463
static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
			       const char *din, char *dout)
D
David Teigland 已提交
464
{
465
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
466 467
	struct buffer_head **bh;
	unsigned int amount = GFS2_EA_DATA_LEN(ea);
468
	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
A
Al Viro 已提交
469
	__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
D
David Teigland 已提交
470 471
	unsigned int x;
	int error = 0;
472 473
	unsigned char *pos;
	unsigned cp_size;
D
David Teigland 已提交
474

J
Josef Bacik 已提交
475
	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
D
David Teigland 已提交
476 477 478 479
	if (!bh)
		return -ENOMEM;

	for (x = 0; x < nptrs; x++) {
S
Steven Whitehouse 已提交
480 481
		error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
				       bh + x);
D
David Teigland 已提交
482 483 484 485 486 487 488 489 490
		if (error) {
			while (x--)
				brelse(bh[x]);
			goto out;
		}
		dataptrs++;
	}

	for (x = 0; x < nptrs; x++) {
S
Steven Whitehouse 已提交
491
		error = gfs2_meta_wait(sdp, bh[x]);
D
David Teigland 已提交
492 493 494 495 496 497 498 499 500 501 502 503
		if (error) {
			for (; x < nptrs; x++)
				brelse(bh[x]);
			goto out;
		}
		if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
			for (; x < nptrs; x++)
				brelse(bh[x]);
			error = -EIO;
			goto out;
		}

504 505
		pos = bh[x]->b_data + sizeof(struct gfs2_meta_header);
		cp_size = (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize;
D
David Teigland 已提交
506

507 508 509 510 511 512
		if (dout) {
			memcpy(dout, pos, cp_size);
			dout += sdp->sd_jbsize;
		}

		if (din) {
513
			gfs2_trans_add_meta(ip->i_gl, bh[x]);
514 515 516
			memcpy(pos, din, cp_size);
			din += sdp->sd_jbsize;
		}
D
David Teigland 已提交
517

518
		amount -= sdp->sd_jbsize;
D
David Teigland 已提交
519 520 521
		brelse(bh[x]);
	}

522
out:
D
David Teigland 已提交
523 524 525 526
	kfree(bh);
	return error;
}

S
Steven Whitehouse 已提交
527 528
static int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
			    char *data, size_t size)
D
David Teigland 已提交
529
{
530 531 532 533 534
	int ret;
	size_t len = GFS2_EA_DATA_LEN(el->el_ea);
	if (len > size)
		return -ERANGE;

D
David Teigland 已提交
535
	if (GFS2_EA_IS_STUFFED(el->el_ea)) {
536 537 538
		memcpy(data, GFS2_EA2DATA(el->el_ea), len);
		return len;
	}
539
	ret = gfs2_iter_unstuffed(ip, el->el_ea, NULL, data);
540 541 542
	if (ret < 0)
		return ret;
	return len;
D
David Teigland 已提交
543 544
}

S
Steven Whitehouse 已提交
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **ppdata)
{
	struct gfs2_ea_location el;
	int error;
	int len;
	char *data;

	error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, &el);
	if (error)
		return error;
	if (!el.el_ea)
		goto out;
	if (!GFS2_EA_DATA_LEN(el.el_ea))
		goto out;

	len = GFS2_EA_DATA_LEN(el.el_ea);
	data = kmalloc(len, GFP_NOFS);
	error = -ENOMEM;
	if (data == NULL)
		goto out;

	error = gfs2_ea_get_copy(ip, &el, data, len);
567 568 569 570
	if (error < 0)
		kfree(data);
	else
		*ppdata = data;
S
Steven Whitehouse 已提交
571 572 573 574 575
out:
	brelse(el.el_bh);
	return error;
}

D
David Teigland 已提交
576
/**
577 578 579 580 581
 * gfs2_xattr_get - Get a GFS2 extended attribute
 * @inode: The inode
 * @name: The name of the extended attribute
 * @buffer: The buffer to write the result into
 * @size: The size of the buffer
582
 * @type: The type of extended attribute
D
David Teigland 已提交
583 584 585
 *
 * Returns: actual size of data on success, -errno on error
 */
586 587 588
static int gfs2_xattr_get(const struct xattr_handler *handler,
			  struct dentry *dentry, const char *name,
			  void *buffer, size_t size)
D
David Teigland 已提交
589
{
590
	struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
D
David Teigland 已提交
591
	struct gfs2_ea_location el;
592
	int type = handler->flags;
D
David Teigland 已提交
593 594
	int error;

595
	if (!ip->i_eattr)
D
David Teigland 已提交
596
		return -ENODATA;
597 598
	if (strlen(name) > GFS2_EA_MAX_NAME_LEN)
		return -EINVAL;
D
David Teigland 已提交
599

600
	error = gfs2_ea_find(ip, type, name, &el);
D
David Teigland 已提交
601 602 603 604
	if (error)
		return error;
	if (!el.el_ea)
		return -ENODATA;
S
Steven Whitehouse 已提交
605
	if (size)
606 607
		error = gfs2_ea_get_copy(ip, &el, buffer, size);
	else
D
David Teigland 已提交
608 609 610 611 612 613 614 615 616
		error = GFS2_EA_DATA_LEN(el.el_ea);
	brelse(el.el_bh);

	return error;
}

/**
 * ea_alloc_blk - allocates a new block for extended attributes.
 * @ip: A pointer to the inode that's getting extended attributes
617
 * @bhp: Pointer to pointer to a struct buffer_head
D
David Teigland 已提交
618 619 620 621 622 623
 *
 * Returns: errno
 */

static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
{
624
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
625
	struct gfs2_ea_header *ea;
626
	unsigned int n = 1;
627
	u64 block;
628
	int error;
D
David Teigland 已提交
629

630
	error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
631 632
	if (error)
		return error;
633
	gfs2_trans_add_unrevoke(sdp, block, 1);
D
David Teigland 已提交
634
	*bhp = gfs2_meta_new(ip->i_gl, block);
635
	gfs2_trans_add_meta(ip->i_gl, *bhp);
D
David Teigland 已提交
636 637 638 639 640 641 642 643 644
	gfs2_metatype_set(*bhp, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
	gfs2_buffer_clear_tail(*bhp, sizeof(struct gfs2_meta_header));

	ea = GFS2_EA_BH2FIRST(*bhp);
	ea->ea_rec_len = cpu_to_be32(sdp->sd_jbsize);
	ea->ea_type = GFS2_EATYPE_UNUSED;
	ea->ea_flags = GFS2_EAFLAG_LAST;
	ea->ea_num_ptrs = 0;

645
	gfs2_add_inode_blocks(&ip->i_inode, 1);
D
David Teigland 已提交
646 647 648 649 650 651 652

	return 0;
}

/**
 * ea_write - writes the request info to an ea, creating new blocks if
 *            necessary
653 654
 * @ip: inode that is being modified
 * @ea: the location of the new ea in a block
D
David Teigland 已提交
655 656 657 658 659 660 661 662 663 664
 * @er: the write request
 *
 * Note: does not update ea_rec_len or the GFS2_EAFLAG_LAST bin of ea_flags
 *
 * returns : errno
 */

static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
		    struct gfs2_ea_request *er)
{
665
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
666
	int error;
D
David Teigland 已提交
667 668 669 670 671 672 673 674 675 676 677 678

	ea->ea_data_len = cpu_to_be32(er->er_data_len);
	ea->ea_name_len = er->er_name_len;
	ea->ea_type = er->er_type;
	ea->__pad = 0;

	memcpy(GFS2_EA2NAME(ea), er->er_name, er->er_name_len);

	if (GFS2_EAREQ_SIZE_STUFFED(er) <= sdp->sd_jbsize) {
		ea->ea_num_ptrs = 0;
		memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len);
	} else {
A
Al Viro 已提交
679
		__be64 *dataptr = GFS2_EA2DATAPTRS(ea);
D
David Teigland 已提交
680 681 682 683 684
		const char *data = er->er_data;
		unsigned int data_len = er->er_data_len;
		unsigned int copy;
		unsigned int x;

685
		ea->ea_num_ptrs = DIV_ROUND_UP(er->er_data_len, sdp->sd_jbsize);
D
David Teigland 已提交
686 687
		for (x = 0; x < ea->ea_num_ptrs; x++) {
			struct buffer_head *bh;
688
			u64 block;
D
David Teigland 已提交
689
			int mh_size = sizeof(struct gfs2_meta_header);
690
			unsigned int n = 1;
D
David Teigland 已提交
691

692
			error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
693 694
			if (error)
				return error;
695
			gfs2_trans_add_unrevoke(sdp, block, 1);
D
David Teigland 已提交
696
			bh = gfs2_meta_new(ip->i_gl, block);
697
			gfs2_trans_add_meta(ip->i_gl, bh);
D
David Teigland 已提交
698 699
			gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);

700
			gfs2_add_inode_blocks(&ip->i_inode, 1);
D
David Teigland 已提交
701

702 703
			copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
							   data_len;
D
David Teigland 已提交
704 705 706 707 708
			memcpy(bh->b_data + mh_size, data, copy);
			if (copy < sdp->sd_jbsize)
				memset(bh->b_data + mh_size + copy, 0,
				       sdp->sd_jbsize - copy);

709
			*dataptr++ = cpu_to_be64(bh->b_blocknr);
D
David Teigland 已提交
710 711 712 713 714 715 716 717 718 719 720 721 722
			data += copy;
			data_len -= copy;

			brelse(bh);
		}

		gfs2_assert_withdraw(sdp, !data_len);
	}

	return 0;
}

typedef int (*ea_skeleton_call_t) (struct gfs2_inode *ip,
723
				   struct gfs2_ea_request *er, void *private);
D
David Teigland 已提交
724 725 726

static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
			     unsigned int blks,
727
			     ea_skeleton_call_t skeleton_call, void *private)
D
David Teigland 已提交
728
{
729
	struct gfs2_alloc_parms ap = { .target = blks };
D
David Teigland 已提交
730 731 732
	struct buffer_head *dibh;
	int error;

B
Bob Peterson 已提交
733 734 735 736
	error = gfs2_rindex_update(GFS2_SB(&ip->i_inode));
	if (error)
		return error;

737
	error = gfs2_quota_lock_check(ip, &ap);
D
David Teigland 已提交
738
	if (error)
739
		return error;
D
David Teigland 已提交
740

741
	error = gfs2_inplace_reserve(ip, &ap);
D
David Teigland 已提交
742 743 744
	if (error)
		goto out_gunlock_q;

745
	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
746
				 blks + gfs2_rg_blocks(ip, blks) +
D
David Teigland 已提交
747 748 749 750 751 752 753 754 755 756
				 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
	if (error)
		goto out_ipres;

	error = skeleton_call(ip, er, private);
	if (error)
		goto out_end_trans;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
757
		ip->i_inode.i_ctime = CURRENT_TIME;
758
		gfs2_trans_add_meta(ip->i_gl, dibh);
759
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
760 761 762
		brelse(dibh);
	}

763
out_end_trans:
764
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
765
out_ipres:
D
David Teigland 已提交
766
	gfs2_inplace_release(ip);
767
out_gunlock_q:
D
David Teigland 已提交
768 769 770 771 772 773 774 775 776 777 778 779 780 781
	gfs2_quota_unlock(ip);
	return error;
}

static int ea_init_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
		     void *private)
{
	struct buffer_head *bh;
	int error;

	error = ea_alloc_blk(ip, &bh);
	if (error)
		return error;

782
	ip->i_eattr = bh->b_blocknr;
D
David Teigland 已提交
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
	error = ea_write(ip, GFS2_EA_BH2FIRST(bh), er);

	brelse(bh);

	return error;
}

/**
 * ea_init - initializes a new eattr block
 * @ip:
 * @er:
 *
 * Returns: errno
 */

798 799
static int ea_init(struct gfs2_inode *ip, int type, const char *name,
		   const void *data, size_t size)
D
David Teigland 已提交
800
{
801
	struct gfs2_ea_request er;
802
	unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
D
David Teigland 已提交
803 804
	unsigned int blks = 1;

805 806 807 808 809 810 811 812
	er.er_type = type;
	er.er_name = name;
	er.er_name_len = strlen(name);
	er.er_data = (void *)data;
	er.er_data_len = size;

	if (GFS2_EAREQ_SIZE_STUFFED(&er) > jbsize)
		blks += DIV_ROUND_UP(er.er_data_len, jbsize);
D
David Teigland 已提交
813

814
	return ea_alloc_skeleton(ip, &er, blks, ea_init_i, NULL);
D
David Teigland 已提交
815 816 817 818
}

static struct gfs2_ea_header *ea_split_ea(struct gfs2_ea_header *ea)
{
819
	u32 ea_size = GFS2_EA_SIZE(ea);
820 821
	struct gfs2_ea_header *new = (struct gfs2_ea_header *)((char *)ea +
				     ea_size);
822
	u32 new_size = GFS2_EA_REC_LEN(ea) - ea_size;
D
David Teigland 已提交
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
	int last = ea->ea_flags & GFS2_EAFLAG_LAST;

	ea->ea_rec_len = cpu_to_be32(ea_size);
	ea->ea_flags ^= last;

	new->ea_rec_len = cpu_to_be32(new_size);
	new->ea_flags = last;

	return new;
}

static void ea_set_remove_stuffed(struct gfs2_inode *ip,
				  struct gfs2_ea_location *el)
{
	struct gfs2_ea_header *ea = el->el_ea;
	struct gfs2_ea_header *prev = el->el_prev;
839
	u32 len;
D
David Teigland 已提交
840

841
	gfs2_trans_add_meta(ip->i_gl, el->el_bh);
D
David Teigland 已提交
842 843 844 845 846 847

	if (!prev || !GFS2_EA_IS_STUFFED(ea)) {
		ea->ea_type = GFS2_EATYPE_UNUSED;
		return;
	} else if (GFS2_EA2NEXT(prev) != ea) {
		prev = GFS2_EA2NEXT(prev);
848
		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), GFS2_EA2NEXT(prev) == ea);
D
David Teigland 已提交
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
	}

	len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
	prev->ea_rec_len = cpu_to_be32(len);

	if (GFS2_EA_IS_LAST(ea))
		prev->ea_flags |= GFS2_EAFLAG_LAST;
}

struct ea_set {
	int ea_split;

	struct gfs2_ea_request *es_er;
	struct gfs2_ea_location *es_el;

	struct buffer_head *es_bh;
	struct gfs2_ea_header *es_ea;
};

static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
				 struct gfs2_ea_header *ea, struct ea_set *es)
{
	struct gfs2_ea_request *er = es->es_er;
	struct buffer_head *dibh;
	int error;

875
	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
D
David Teigland 已提交
876 877 878
	if (error)
		return error;

879
	gfs2_trans_add_meta(ip->i_gl, bh);
D
David Teigland 已提交
880 881 882 883 884 885 886 887 888 889 890 891

	if (es->ea_split)
		ea = ea_split_ea(ea);

	ea_write(ip, ea, er);

	if (es->es_el)
		ea_set_remove_stuffed(ip, es->es_el);

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto out;
892
	ip->i_inode.i_ctime = CURRENT_TIME;
893
	gfs2_trans_add_meta(ip->i_gl, dibh);
894
	gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
895
	brelse(dibh);
896
out:
897
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
D
David Teigland 已提交
898 899 900 901 902 903 904 905 906 907
	return error;
}

static int ea_set_simple_alloc(struct gfs2_inode *ip,
			       struct gfs2_ea_request *er, void *private)
{
	struct ea_set *es = private;
	struct gfs2_ea_header *ea = es->es_ea;
	int error;

908
	gfs2_trans_add_meta(ip->i_gl, es->es_bh);
D
David Teigland 已提交
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931

	if (es->ea_split)
		ea = ea_split_ea(ea);

	error = ea_write(ip, ea, er);
	if (error)
		return error;

	if (es->es_el)
		ea_set_remove_stuffed(ip, es->es_el);

	return 0;
}

static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
			 struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
			 void *private)
{
	struct ea_set *es = private;
	unsigned int size;
	int stuffed;
	int error;

932 933
	stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er->er_name_len,
			       es->es_er->er_data_len, &size);
D
David Teigland 已提交
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957

	if (ea->ea_type == GFS2_EATYPE_UNUSED) {
		if (GFS2_EA_REC_LEN(ea) < size)
			return 0;
		if (!GFS2_EA_IS_STUFFED(ea)) {
			error = ea_remove_unstuffed(ip, bh, ea, prev, 1);
			if (error)
				return error;
		}
		es->ea_split = 0;
	} else if (GFS2_EA_REC_LEN(ea) - GFS2_EA_SIZE(ea) >= size)
		es->ea_split = 1;
	else
		return 0;

	if (stuffed) {
		error = ea_set_simple_noalloc(ip, bh, ea, es);
		if (error)
			return error;
	} else {
		unsigned int blks;

		es->es_bh = bh;
		es->es_ea = ea;
958
		blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
959
					GFS2_SB(&ip->i_inode)->sd_jbsize);
D
David Teigland 已提交
960 961 962 963 964 965 966 967 968 969 970 971 972

		error = ea_alloc_skeleton(ip, es->es_er, blks,
					  ea_set_simple_alloc, es);
		if (error)
			return error;
	}

	return 1;
}

static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
			void *private)
{
973
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
974
	struct buffer_head *indbh, *newbh;
A
Al Viro 已提交
975
	__be64 *eablk;
D
David Teigland 已提交
976 977 978
	int error;
	int mh_size = sizeof(struct gfs2_meta_header);

979
	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
A
Al Viro 已提交
980
		__be64 *end;
D
David Teigland 已提交
981

982
		error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT,
S
Steven Whitehouse 已提交
983
				       &indbh);
D
David Teigland 已提交
984 985 986 987 988 989 990 991
		if (error)
			return error;

		if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
			error = -EIO;
			goto out;
		}

A
Al Viro 已提交
992
		eablk = (__be64 *)(indbh->b_data + mh_size);
D
David Teigland 已提交
993 994 995 996 997 998 999 1000 1001 1002 1003
		end = eablk + sdp->sd_inptrs;

		for (; eablk < end; eablk++)
			if (!*eablk)
				break;

		if (eablk == end) {
			error = -ENOSPC;
			goto out;
		}

1004
		gfs2_trans_add_meta(ip->i_gl, indbh);
D
David Teigland 已提交
1005
	} else {
1006
		u64 blk;
1007
		unsigned int n = 1;
1008
		error = gfs2_alloc_blocks(ip, &blk, &n, 0, NULL);
1009 1010
		if (error)
			return error;
1011
		gfs2_trans_add_unrevoke(sdp, blk, 1);
D
David Teigland 已提交
1012
		indbh = gfs2_meta_new(ip->i_gl, blk);
1013
		gfs2_trans_add_meta(ip->i_gl, indbh);
D
David Teigland 已提交
1014 1015 1016
		gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
		gfs2_buffer_clear_tail(indbh, mh_size);

A
Al Viro 已提交
1017
		eablk = (__be64 *)(indbh->b_data + mh_size);
1018 1019
		*eablk = cpu_to_be64(ip->i_eattr);
		ip->i_eattr = blk;
1020
		ip->i_diskflags |= GFS2_DIF_EA_INDIRECT;
1021
		gfs2_add_inode_blocks(&ip->i_inode, 1);
D
David Teigland 已提交
1022 1023 1024 1025 1026 1027 1028 1029

		eablk++;
	}

	error = ea_alloc_blk(ip, &newbh);
	if (error)
		goto out;

1030
	*eablk = cpu_to_be64((u64)newbh->b_blocknr);
D
David Teigland 已提交
1031 1032 1033 1034 1035 1036
	error = ea_write(ip, GFS2_EA_BH2FIRST(newbh), er);
	brelse(newbh);
	if (error)
		goto out;

	if (private)
1037
		ea_set_remove_stuffed(ip, private);
D
David Teigland 已提交
1038

1039
out:
D
David Teigland 已提交
1040 1041 1042 1043
	brelse(indbh);
	return error;
}

1044 1045
static int ea_set_i(struct gfs2_inode *ip, int type, const char *name,
		    const void *value, size_t size, struct gfs2_ea_location *el)
D
David Teigland 已提交
1046
{
1047
	struct gfs2_ea_request er;
D
David Teigland 已提交
1048 1049 1050 1051
	struct ea_set es;
	unsigned int blks = 2;
	int error;

1052 1053 1054 1055 1056 1057
	er.er_type = type;
	er.er_name = name;
	er.er_data = (void *)value;
	er.er_name_len = strlen(name);
	er.er_data_len = size;

D
David Teigland 已提交
1058
	memset(&es, 0, sizeof(struct ea_set));
1059
	es.es_er = &er;
D
David Teigland 已提交
1060 1061 1062 1063 1064 1065 1066 1067
	es.es_el = el;

	error = ea_foreach(ip, ea_set_simple, &es);
	if (error > 0)
		return 0;
	if (error)
		return error;

1068
	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT))
D
David Teigland 已提交
1069
		blks++;
1070 1071
	if (GFS2_EAREQ_SIZE_STUFFED(&er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
		blks += DIV_ROUND_UP(er.er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
D
David Teigland 已提交
1072

1073
	return ea_alloc_skeleton(ip, &er, blks, ea_set_block, el);
D
David Teigland 已提交
1074 1075 1076 1077 1078 1079 1080
}

static int ea_set_remove_unstuffed(struct gfs2_inode *ip,
				   struct gfs2_ea_location *el)
{
	if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
		el->el_prev = GFS2_EA2NEXT(el->el_prev);
1081
		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
D
David Teigland 已提交
1082 1083 1084
				     GFS2_EA2NEXT(el->el_prev) == el->el_ea);
	}

S
Steven Whitehouse 已提交
1085
	return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev, 0);
D
David Teigland 已提交
1086 1087 1088 1089 1090 1091 1092 1093 1094
}

static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
{
	struct gfs2_ea_header *ea = el->el_ea;
	struct gfs2_ea_header *prev = el->el_prev;
	struct buffer_head *dibh;
	int error;

1095
	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
D
David Teigland 已提交
1096 1097 1098
	if (error)
		return error;

1099
	gfs2_trans_add_meta(ip->i_gl, el->el_bh);
D
David Teigland 已提交
1100 1101

	if (prev) {
1102
		u32 len;
D
David Teigland 已提交
1103 1104 1105 1106 1107 1108

		len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
		prev->ea_rec_len = cpu_to_be32(len);

		if (GFS2_EA_IS_LAST(ea))
			prev->ea_flags |= GFS2_EAFLAG_LAST;
1109
	} else {
D
David Teigland 已提交
1110
		ea->ea_type = GFS2_EATYPE_UNUSED;
1111
	}
D
David Teigland 已提交
1112 1113 1114

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
1115
		ip->i_inode.i_ctime = CURRENT_TIME;
1116
		gfs2_trans_add_meta(ip->i_gl, dibh);
1117
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
1118
		brelse(dibh);
1119
	}
D
David Teigland 已提交
1120

1121
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
D
David Teigland 已提交
1122 1123 1124 1125

	return error;
}

1126 1127
/**
 * gfs2_xattr_remove - Remove a GFS2 extended attribute
1128
 * @ip: The inode
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
 * @type: The type of the extended attribute
 * @name: The name of the extended attribute
 *
 * This is not called directly by the VFS since we use the (common)
 * scheme of making a "set with NULL data" mean a remove request. Note
 * that this is different from a set with zero length data.
 *
 * Returns: 0, or errno on failure
 */

1139
static int gfs2_xattr_remove(struct gfs2_inode *ip, int type, const char *name)
D
David Teigland 已提交
1140 1141 1142 1143
{
	struct gfs2_ea_location el;
	int error;

1144
	if (!ip->i_eattr)
D
David Teigland 已提交
1145 1146
		return -ENODATA;

1147
	error = gfs2_ea_find(ip, type, name, &el);
D
David Teigland 已提交
1148 1149 1150 1151 1152 1153 1154 1155
	if (error)
		return error;
	if (!el.el_ea)
		return -ENODATA;

	if (GFS2_EA_IS_STUFFED(el.el_ea))
		error = ea_remove_stuffed(ip, &el);
	else
1156
		error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, 0);
D
David Teigland 已提交
1157 1158 1159 1160 1161 1162 1163

	brelse(el.el_bh);

	return error;
}

/**
1164 1165
 * __gfs2_xattr_set - Set (or remove) a GFS2 extended attribute
 * @ip: The inode
1166 1167 1168 1169
 * @name: The name of the extended attribute
 * @value: The value of the extended attribute (NULL for remove)
 * @size: The size of the @value argument
 * @flags: Create or Replace
1170
 * @type: The type of the extended attribute
D
David Teigland 已提交
1171
 *
1172 1173 1174
 * See gfs2_xattr_remove() for details of the removal of xattrs.
 *
 * Returns: 0 or errno on failure
D
David Teigland 已提交
1175 1176
 */

1177 1178
int __gfs2_xattr_set(struct inode *inode, const char *name,
		   const void *value, size_t size, int flags, int type)
D
David Teigland 已提交
1179
{
1180
	struct gfs2_inode *ip = GFS2_I(inode);
1181
	struct gfs2_sbd *sdp = GFS2_SB(inode);
1182 1183
	struct gfs2_ea_location el;
	unsigned int namel = strlen(name);
D
David Teigland 已提交
1184 1185
	int error;

1186 1187 1188 1189
	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
		return -EPERM;
	if (namel > GFS2_EA_MAX_NAME_LEN)
		return -ERANGE;
D
David Teigland 已提交
1190

1191
	if (value == NULL)
1192
		return gfs2_xattr_remove(ip, type, name);
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203

	if (ea_check_size(sdp, namel, size))
		return -ERANGE;

	if (!ip->i_eattr) {
		if (flags & XATTR_REPLACE)
			return -ENODATA;
		return ea_init(ip, type, name, value, size);
	}

	error = gfs2_ea_find(ip, type, name, &el);
D
David Teigland 已提交
1204 1205 1206
	if (error)
		return error;

1207 1208 1209 1210 1211
	if (el.el_ea) {
		if (ip->i_diskflags & GFS2_DIF_APPENDONLY) {
			brelse(el.el_bh);
			return -EPERM;
		}
D
David Teigland 已提交
1212

1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
		error = -EEXIST;
		if (!(flags & XATTR_CREATE)) {
			int unstuffed = !GFS2_EA_IS_STUFFED(el.el_ea);
			error = ea_set_i(ip, type, name, value, size, &el);
			if (!error && unstuffed)
				ea_set_remove_unstuffed(ip, &el);
		}

		brelse(el.el_bh);
		return error;
	}

	error = -ENODATA;
	if (!(flags & XATTR_REPLACE))
		error = ea_set_i(ip, type, name, value, size, NULL);
D
David Teigland 已提交
1228 1229 1230 1231

	return error;
}

1232 1233 1234
static int gfs2_xattr_set(const struct xattr_handler *handler,
			  struct dentry *dentry, const char *name,
			  const void *value, size_t size, int flags)
1235
{
1236
	return __gfs2_xattr_set(d_inode(dentry), name, value,
1237
				size, flags, handler->flags);
1238 1239
}

1240

D
David Teigland 已提交
1241 1242 1243
static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
				  struct gfs2_ea_header *ea, char *data)
{
1244
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
1245
	unsigned int amount = GFS2_EA_DATA_LEN(ea);
1246
	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
1247
	int ret;
D
David Teigland 已提交
1248

1249 1250 1251
	ret = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
	if (ret)
		return ret;
D
David Teigland 已提交
1252

1253
	ret = gfs2_iter_unstuffed(ip, ea, data, NULL);
D
David Teigland 已提交
1254
	gfs2_trans_end(sdp);
1255 1256

	return ret;
D
David Teigland 已提交
1257 1258
}

S
Steven Whitehouse 已提交
1259
int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
D
David Teigland 已提交
1260
{
S
Steven Whitehouse 已提交
1261 1262
	struct inode *inode = &ip->i_inode;
	struct gfs2_sbd *sdp = GFS2_SB(inode);
S
Steven Whitehouse 已提交
1263
	struct gfs2_ea_location el;
D
David Teigland 已提交
1264 1265
	int error;

S
Steven Whitehouse 已提交
1266 1267 1268 1269 1270
	error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, GFS2_POSIX_ACL_ACCESS, &el);
	if (error)
		return error;

	if (GFS2_EA_IS_STUFFED(el.el_ea)) {
1271 1272
		error = gfs2_trans_begin(sdp, RES_DINODE + RES_EATTR, 0);
		if (error == 0) {
1273
			gfs2_trans_add_meta(ip->i_gl, el.el_bh);
1274 1275 1276 1277
			memcpy(GFS2_EA2DATA(el.el_ea), data,
			       GFS2_EA_DATA_LEN(el.el_ea));
		}
	} else {
S
Steven Whitehouse 已提交
1278
		error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
1279
	}
D
David Teigland 已提交
1280

1281
	brelse(el.el_bh);
D
David Teigland 已提交
1282 1283 1284
	if (error)
		return error;

S
Steven Whitehouse 已提交
1285
	error = gfs2_setattr_simple(inode, attr);
1286
	gfs2_trans_end(sdp);
D
David Teigland 已提交
1287 1288 1289 1290 1291
	return error;
}

static int ea_dealloc_indirect(struct gfs2_inode *ip)
{
1292
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
1293 1294
	struct gfs2_rgrp_list rlist;
	struct buffer_head *indbh, *dibh;
A
Al Viro 已提交
1295
	__be64 *eablk, *end;
D
David Teigland 已提交
1296
	unsigned int rg_blocks = 0;
1297
	u64 bstart = 0;
D
David Teigland 已提交
1298 1299 1300 1301 1302
	unsigned int blen = 0;
	unsigned int blks = 0;
	unsigned int x;
	int error;

1303 1304 1305 1306
	error = gfs2_rindex_update(sdp);
	if (error)
		return error;

D
David Teigland 已提交
1307 1308
	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));

1309
	error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh);
D
David Teigland 已提交
1310 1311 1312 1313 1314 1315 1316 1317
	if (error)
		return error;

	if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
		error = -EIO;
		goto out;
	}

A
Al Viro 已提交
1318
	eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
D
David Teigland 已提交
1319 1320 1321
	end = eablk + sdp->sd_inptrs;

	for (; eablk < end; eablk++) {
1322
		u64 bn;
D
David Teigland 已提交
1323 1324 1325 1326 1327 1328 1329 1330 1331

		if (!*eablk)
			break;
		bn = be64_to_cpu(*eablk);

		if (bstart + blen == bn)
			blen++;
		else {
			if (bstart)
1332
				gfs2_rlist_add(ip, &rlist, bstart);
D
David Teigland 已提交
1333 1334 1335 1336 1337 1338
			bstart = bn;
			blen = 1;
		}
		blks++;
	}
	if (bstart)
1339
		gfs2_rlist_add(ip, &rlist, bstart);
D
David Teigland 已提交
1340 1341 1342
	else
		goto out;

1343
	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
D
David Teigland 已提交
1344 1345 1346

	for (x = 0; x < rlist.rl_rgrps; x++) {
		struct gfs2_rgrpd *rgd;
1347
		rgd = rlist.rl_ghs[x].gh_gl->gl_object;
1348
		rg_blocks += rgd->rd_length;
D
David Teigland 已提交
1349 1350 1351 1352 1353 1354
	}

	error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
	if (error)
		goto out_rlist_free;

1355 1356
	error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + RES_INDIRECT +
				 RES_STATFS + RES_QUOTA, blks);
D
David Teigland 已提交
1357 1358 1359
	if (error)
		goto out_gunlock;

1360
	gfs2_trans_add_meta(ip->i_gl, indbh);
D
David Teigland 已提交
1361

A
Al Viro 已提交
1362
	eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
D
David Teigland 已提交
1363 1364 1365 1366
	bstart = 0;
	blen = 0;

	for (; eablk < end; eablk++) {
1367
		u64 bn;
D
David Teigland 已提交
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382

		if (!*eablk)
			break;
		bn = be64_to_cpu(*eablk);

		if (bstart + blen == bn)
			blen++;
		else {
			if (bstart)
				gfs2_free_meta(ip, bstart, blen);
			bstart = bn;
			blen = 1;
		}

		*eablk = 0;
1383
		gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
1384 1385 1386 1387
	}
	if (bstart)
		gfs2_free_meta(ip, bstart, blen);

1388
	ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT;
D
David Teigland 已提交
1389 1390 1391

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
1392
		gfs2_trans_add_meta(ip->i_gl, dibh);
1393
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
1394 1395 1396 1397 1398
		brelse(dibh);
	}

	gfs2_trans_end(sdp);

1399
out_gunlock:
D
David Teigland 已提交
1400
	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
1401
out_rlist_free:
D
David Teigland 已提交
1402
	gfs2_rlist_free(&rlist);
1403
out:
D
David Teigland 已提交
1404 1405 1406 1407 1408 1409
	brelse(indbh);
	return error;
}

static int ea_dealloc_block(struct gfs2_inode *ip)
{
1410
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
1411 1412
	struct gfs2_rgrpd *rgd;
	struct buffer_head *dibh;
1413
	struct gfs2_holder gh;
D
David Teigland 已提交
1414 1415
	int error;

1416 1417 1418 1419
	error = gfs2_rindex_update(sdp);
	if (error)
		return error;

S
Steven Whitehouse 已提交
1420
	rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr, 1);
D
David Teigland 已提交
1421 1422 1423 1424 1425
	if (!rgd) {
		gfs2_consist_inode(ip);
		return -EIO;
	}

1426
	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh);
D
David Teigland 已提交
1427 1428 1429
	if (error)
		return error;

1430 1431
	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_DINODE + RES_STATFS +
				 RES_QUOTA, 1);
D
David Teigland 已提交
1432 1433 1434
	if (error)
		goto out_gunlock;

1435
	gfs2_free_meta(ip, ip->i_eattr, 1);
D
David Teigland 已提交
1436

1437
	ip->i_eattr = 0;
1438
	gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
1439 1440 1441

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
1442
		gfs2_trans_add_meta(ip->i_gl, dibh);
1443
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
1444 1445 1446 1447 1448
		brelse(dibh);
	}

	gfs2_trans_end(sdp);

1449
out_gunlock:
1450
	gfs2_glock_dq_uninit(&gh);
D
David Teigland 已提交
1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464
	return error;
}

/**
 * gfs2_ea_dealloc - deallocate the extended attribute fork
 * @ip: the inode
 *
 * Returns: errno
 */

int gfs2_ea_dealloc(struct gfs2_inode *ip)
{
	int error;

B
Bob Peterson 已提交
1465 1466 1467 1468
	error = gfs2_rindex_update(GFS2_SB(&ip->i_inode));
	if (error)
		return error;

1469
	error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
D
David Teigland 已提交
1470
	if (error)
1471
		return error;
D
David Teigland 已提交
1472 1473 1474

	error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
	if (error)
1475
		goto out_quota;
D
David Teigland 已提交
1476

1477
	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
D
David Teigland 已提交
1478 1479
		error = ea_dealloc_indirect(ip);
		if (error)
1480
			goto out_quota;
D
David Teigland 已提交
1481 1482 1483 1484
	}

	error = ea_dealloc_block(ip);

1485
out_quota:
D
David Teigland 已提交
1486 1487 1488 1489
	gfs2_quota_unhold(ip);
	return error;
}

S
Stephen Hemminger 已提交
1490
static const struct xattr_handler gfs2_xattr_user_handler = {
1491
	.prefix = XATTR_USER_PREFIX,
1492 1493 1494
	.flags  = GFS2_EATYPE_USR,
	.get    = gfs2_xattr_get,
	.set    = gfs2_xattr_set,
1495 1496
};

S
Stephen Hemminger 已提交
1497
static const struct xattr_handler gfs2_xattr_security_handler = {
1498
	.prefix = XATTR_SECURITY_PREFIX,
1499 1500 1501
	.flags  = GFS2_EATYPE_SECURITY,
	.get    = gfs2_xattr_get,
	.set    = gfs2_xattr_set,
1502 1503
};

S
Stephen Hemminger 已提交
1504
const struct xattr_handler *gfs2_xattr_handlers[] = {
1505 1506
	&gfs2_xattr_user_handler,
	&gfs2_xattr_security_handler,
1507 1508
	&posix_acl_access_xattr_handler,
	&posix_acl_default_xattr_handler,
1509 1510 1511
	NULL,
};