xattr.c 32.5 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
static int gfs2_xattr_get(struct dentry *dentry, const char *name,
		void *buffer, size_t size, int type)
D
David Teigland 已提交
588
{
589
	struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
D
David Teigland 已提交
590 591 592
	struct gfs2_ea_location el;
	int error;

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

598
	error = gfs2_ea_find(ip, type, name, &el);
D
David Teigland 已提交
599 600 601 602
	if (error)
		return error;
	if (!el.el_ea)
		return -ENODATA;
S
Steven Whitehouse 已提交
603
	if (size)
604 605
		error = gfs2_ea_get_copy(ip, &el, buffer, size);
	else
D
David Teigland 已提交
606 607 608 609 610 611 612 613 614
		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
615
 * @bhp: Pointer to pointer to a struct buffer_head
D
David Teigland 已提交
616 617 618 619 620 621
 *
 * Returns: errno
 */

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

628
	error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
629 630
	if (error)
		return error;
631
	gfs2_trans_add_unrevoke(sdp, block, 1);
D
David Teigland 已提交
632
	*bhp = gfs2_meta_new(ip->i_gl, block);
633
	gfs2_trans_add_meta(ip->i_gl, *bhp);
D
David Teigland 已提交
634 635 636 637 638 639 640 641 642
	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;

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

	return 0;
}

/**
 * ea_write - writes the request info to an ea, creating new blocks if
 *            necessary
651 652
 * @ip: inode that is being modified
 * @ea: the location of the new ea in a block
D
David Teigland 已提交
653 654 655 656 657 658 659 660 661 662
 * @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)
{
663
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
664
	int error;
D
David Teigland 已提交
665 666 667 668 669 670 671 672 673 674 675 676

	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 已提交
677
		__be64 *dataptr = GFS2_EA2DATAPTRS(ea);
D
David Teigland 已提交
678 679 680 681 682
		const char *data = er->er_data;
		unsigned int data_len = er->er_data_len;
		unsigned int copy;
		unsigned int x;

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

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

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

700 701
			copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
							   data_len;
D
David Teigland 已提交
702 703 704 705 706
			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);

707
			*dataptr++ = cpu_to_be64(bh->b_blocknr);
D
David Teigland 已提交
708 709 710 711 712 713 714 715 716 717 718 719 720
			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,
721
				   struct gfs2_ea_request *er, void *private);
D
David Teigland 已提交
722 723 724

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

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

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

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

743
	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
744
				 blks + gfs2_rg_blocks(ip, blks) +
D
David Teigland 已提交
745 746 747 748 749 750 751 752 753 754
				 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) {
755
		ip->i_inode.i_ctime = CURRENT_TIME;
756
		gfs2_trans_add_meta(ip->i_gl, dibh);
757
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
758 759 760
		brelse(dibh);
	}

761
out_end_trans:
762
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
763
out_ipres:
D
David Teigland 已提交
764
	gfs2_inplace_release(ip);
765
out_gunlock_q:
D
David Teigland 已提交
766 767 768 769 770 771 772 773 774 775 776 777 778 779
	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;

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

	brelse(bh);

	return error;
}

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

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

803 804 805 806 807 808 809 810
	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 已提交
811

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

static struct gfs2_ea_header *ea_split_ea(struct gfs2_ea_header *ea)
{
817
	u32 ea_size = GFS2_EA_SIZE(ea);
818 819
	struct gfs2_ea_header *new = (struct gfs2_ea_header *)((char *)ea +
				     ea_size);
820
	u32 new_size = GFS2_EA_REC_LEN(ea) - ea_size;
D
David Teigland 已提交
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
	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;
837
	u32 len;
D
David Teigland 已提交
838

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

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

	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;

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

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

	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;
890
	ip->i_inode.i_ctime = CURRENT_TIME;
891
	gfs2_trans_add_meta(ip->i_gl, dibh);
892
	gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
893
	brelse(dibh);
894
out:
895
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
D
David Teigland 已提交
896 897 898 899 900 901 902 903 904 905
	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;

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

	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;

930 931
	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 已提交
932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955

	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;
956
		blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
957
					GFS2_SB(&ip->i_inode)->sd_jbsize);
D
David Teigland 已提交
958 959 960 961 962 963 964 965 966 967 968 969 970

		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)
{
971
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
972
	struct buffer_head *indbh, *newbh;
A
Al Viro 已提交
973
	__be64 *eablk;
D
David Teigland 已提交
974 975 976
	int error;
	int mh_size = sizeof(struct gfs2_meta_header);

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

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

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

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

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

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

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

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

		eablk++;
	}

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

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

	if (private)
1035
		ea_set_remove_stuffed(ip, private);
D
David Teigland 已提交
1036

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

1042 1043
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 已提交
1044
{
1045
	struct gfs2_ea_request er;
D
David Teigland 已提交
1046 1047 1048 1049
	struct ea_set es;
	unsigned int blks = 2;
	int error;

1050 1051 1052 1053 1054 1055
	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 已提交
1056
	memset(&es, 0, sizeof(struct ea_set));
1057
	es.es_er = &er;
D
David Teigland 已提交
1058 1059 1060 1061 1062 1063 1064 1065
	es.es_el = el;

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

1066
	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT))
D
David Teigland 已提交
1067
		blks++;
1068 1069
	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 已提交
1070

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

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);
1079
		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
D
David Teigland 已提交
1080 1081 1082
				     GFS2_EA2NEXT(el->el_prev) == el->el_ea);
	}

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

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;

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

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

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

		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;
1107
	} else {
D
David Teigland 已提交
1108
		ea->ea_type = GFS2_EATYPE_UNUSED;
1109
	}
D
David Teigland 已提交
1110 1111 1112

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

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

	return error;
}

1124 1125
/**
 * gfs2_xattr_remove - Remove a GFS2 extended attribute
1126
 * @ip: The inode
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
 * @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
 */

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

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

1145
	error = gfs2_ea_find(ip, type, name, &el);
D
David Teigland 已提交
1146 1147 1148 1149 1150 1151 1152 1153
	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
1154
		error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, 0);
D
David Teigland 已提交
1155 1156 1157 1158 1159 1160 1161

	brelse(el.el_bh);

	return error;
}

/**
1162 1163
 * __gfs2_xattr_set - Set (or remove) a GFS2 extended attribute
 * @ip: The inode
1164 1165 1166 1167
 * @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
1168
 * @type: The type of the extended attribute
D
David Teigland 已提交
1169
 *
1170 1171 1172
 * See gfs2_xattr_remove() for details of the removal of xattrs.
 *
 * Returns: 0 or errno on failure
D
David Teigland 已提交
1173 1174
 */

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

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

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

	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 已提交
1202 1203 1204
	if (error)
		return error;

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

1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225
		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 已提交
1226 1227 1228 1229

	return error;
}

1230 1231 1232
static int gfs2_xattr_set(struct dentry *dentry, const char *name,
		const void *value, size_t size, int flags, int type)
{
1233
	return __gfs2_xattr_set(d_inode(dentry), name, value,
1234 1235 1236
				size, flags, type);
}

1237

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

1246 1247 1248
	ret = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
	if (ret)
		return ret;
D
David Teigland 已提交
1249

1250
	ret = gfs2_iter_unstuffed(ip, ea, data, NULL);
D
David Teigland 已提交
1251
	gfs2_trans_end(sdp);
1252 1253

	return ret;
D
David Teigland 已提交
1254 1255
}

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

S
Steven Whitehouse 已提交
1263 1264 1265 1266 1267
	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)) {
1268 1269
		error = gfs2_trans_begin(sdp, RES_DINODE + RES_EATTR, 0);
		if (error == 0) {
1270
			gfs2_trans_add_meta(ip->i_gl, el.el_bh);
1271 1272 1273 1274
			memcpy(GFS2_EA2DATA(el.el_ea), data,
			       GFS2_EA_DATA_LEN(el.el_ea));
		}
	} else {
S
Steven Whitehouse 已提交
1275
		error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
1276
	}
D
David Teigland 已提交
1277

1278
	brelse(el.el_bh);
D
David Teigland 已提交
1279 1280 1281
	if (error)
		return error;

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

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

1300 1301 1302 1303
	error = gfs2_rindex_update(sdp);
	if (error)
		return error;

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

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

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

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

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

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

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

1340
	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
D
David Teigland 已提交
1341 1342 1343

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

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

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

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

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

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

		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;
1380
		gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
1381 1382 1383 1384
	}
	if (bstart)
		gfs2_free_meta(ip, bstart, blen);

1385
	ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT;
D
David Teigland 已提交
1386 1387 1388

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

	gfs2_trans_end(sdp);

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

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

1413 1414 1415 1416
	error = gfs2_rindex_update(sdp);
	if (error)
		return error;

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

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

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

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

1434
	ip->i_eattr = 0;
1435
	gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
1436 1437 1438

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

	gfs2_trans_end(sdp);

1446
out_gunlock:
1447
	gfs2_glock_dq_uninit(&gh);
D
David Teigland 已提交
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461
	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 已提交
1462 1463 1464 1465
	error = gfs2_rindex_update(GFS2_SB(&ip->i_inode));
	if (error)
		return error;

1466
	error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
D
David Teigland 已提交
1467
	if (error)
1468
		return error;
D
David Teigland 已提交
1469 1470 1471

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

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

	error = ea_dealloc_block(ip);

1482
out_quota:
D
David Teigland 已提交
1483 1484 1485 1486
	gfs2_quota_unhold(ip);
	return error;
}

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

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

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