xattr.c 33.3 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>
D
David Teigland 已提交
16 17 18
#include <asm/uaccess.h>

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

/**
 * 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
 */

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

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

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

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

	return 0;
}

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

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

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

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

	return 0;
}

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

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;

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

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

110
fail:
D
David Teigland 已提交
111 112 113 114 115 116 117
	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 已提交
118
	__be64 *eablk, *end;
D
David Teigland 已提交
119 120
	int error;

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

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

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

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

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

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

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

struct ea_find {
159 160 161
	int type;
	const char *name;
	size_t namel;
D
David Teigland 已提交
162 163 164 165 166 167 168 169 170 171 172 173
	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;

174 175 176
	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 已提交
177 178 179 180 181 182 183 184 185 186 187 188
			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 已提交
189 190
static int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
			struct gfs2_ea_location *el)
D
David Teigland 已提交
191 192 193 194
{
	struct ea_find ef;
	int error;

195 196 197
	ef.type = type;
	ef.name = name;
	ef.namel = strlen(name);
D
David Teigland 已提交
198 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
	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;
229
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
230 231 232
	struct gfs2_rgrpd *rgd;
	struct gfs2_holder rg_gh;
	struct buffer_head *dibh;
A
Al Viro 已提交
233 234
	__be64 *dataptrs;
	u64 bn = 0;
235
	u64 bstart = 0;
D
David Teigland 已提交
236 237 238 239 240 241 242 243 244
	unsigned int blen = 0;
	unsigned int blks = 0;
	unsigned int x;
	int error;

	if (GFS2_EA_IS_STUFFED(ea))
		return 0;

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

	rgd = gfs2_blk2rgrpd(sdp, bn);
	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;

264
	error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE +
265
				 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
D
David Teigland 已提交
266 267 268
	if (error)
		goto out_gunlock;

269
	gfs2_trans_add_bh(ip->i_gl, bh, 1);
D
David Teigland 已提交
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286

	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;
287
		gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
288 289 290 291 292
	}
	if (bstart)
		gfs2_free_meta(ip, bstart, blen);

	if (prev && !leave) {
293
		u32 len;
D
David Teigland 已提交
294 295 296 297 298 299 300 301 302 303 304 305 306

		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) {
307
		ip->i_inode.i_ctime = CURRENT_TIME;
308
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
309
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
310 311 312 313 314
		brelse(dibh);
	}

	gfs2_trans_end(sdp);

315
out_gunlock:
D
David Teigland 已提交
316 317 318 319 320 321 322 323 324 325 326 327
	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)
{
	struct gfs2_alloc *al;
	int error;

	al = gfs2_alloc_get(ip);
328 329
	if (!al)
		return -ENOMEM;
D
David Teigland 已提交
330 331 332 333 334

	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
	if (error)
		goto out_alloc;

335
	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
D
David Teigland 已提交
336 337 338
	if (error)
		goto out_quota;

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

	gfs2_glock_dq_uninit(&al->al_ri_gh);

343
out_quota:
D
David Teigland 已提交
344
	gfs2_quota_unhold(ip);
345
out_alloc:
D
David Teigland 已提交
346 347 348 349 350 351 352 353 354
	gfs2_alloc_put(ip);
	return error;
}

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

355 356 357 358 359 360 361 362 363 364 365 366 367 368
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 已提交
369 370 371 372 373 374
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 已提交
375
	unsigned int ea_size = gfs2_ea_strlen(ea);
D
David Teigland 已提交
376 377 378 379 380

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

	if (er->er_data_len) {
381 382
		char *prefix = NULL;
		unsigned int l = 0;
D
David Teigland 已提交
383 384 385 386 387
		char c = 0;

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

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

403 404
		BUG_ON(l == 0);

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

	ei->ei_size += ea_size;

	return 0;
}

/**
417 418 419 420
 * 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 已提交
421 422 423 424
 *
 * Returns: actual size of data on success, -errno on error
 */

425
ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
D
David Teigland 已提交
426
{
427 428
	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
	struct gfs2_ea_request er;
D
David Teigland 已提交
429 430 431
	struct gfs2_holder i_gh;
	int error;

432 433 434 435
	memset(&er, 0, sizeof(struct gfs2_ea_request));
	if (size) {
		er.er_data = buffer;
		er.er_data_len = size;
D
David Teigland 已提交
436 437
	}

438
	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
D
David Teigland 已提交
439 440 441
	if (error)
		return error;

442
	if (ip->i_eattr) {
443
		struct ea_list ei = { .ei_er = &er, .ei_size = 0 };
D
David Teigland 已提交
444 445 446 447 448 449 450 451 452 453 454 455 456 457

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

	gfs2_glock_dq_uninit(&i_gh);

	return error;
}

/**
 * ea_get_unstuffed - actually copies the unstuffed data into the
 *                    request buffer
458 459 460
 * @ip: The GFS2 inode
 * @ea: The extended attribute header structure
 * @data: The data to be copied
D
David Teigland 已提交
461 462 463 464 465 466 467
 *
 * Returns: errno
 */

static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
			    char *data)
{
468
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
469 470
	struct buffer_head **bh;
	unsigned int amount = GFS2_EA_DATA_LEN(ea);
471
	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
A
Al Viro 已提交
472
	__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
D
David Teigland 已提交
473 474 475
	unsigned int x;
	int error = 0;

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

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

	for (x = 0; x < nptrs; x++) {
S
Steven Whitehouse 已提交
492
		error = gfs2_meta_wait(sdp, bh[x]);
D
David Teigland 已提交
493 494 495 496 497 498 499 500 501 502 503 504
		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;
		}

505
		memcpy(data, bh[x]->b_data + sizeof(struct gfs2_meta_header),
D
David Teigland 已提交
506 507 508 509 510 511 512 513
		       (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);

		amount -= sdp->sd_jbsize;
		data += sdp->sd_jbsize;

		brelse(bh[x]);
	}

514
out:
D
David Teigland 已提交
515 516 517 518
	kfree(bh);
	return error;
}

S
Steven Whitehouse 已提交
519 520
static int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
			    char *data, size_t size)
D
David Teigland 已提交
521
{
522 523 524 525 526
	int ret;
	size_t len = GFS2_EA_DATA_LEN(el->el_ea);
	if (len > size)
		return -ERANGE;

D
David Teigland 已提交
527
	if (GFS2_EA_IS_STUFFED(el->el_ea)) {
528 529 530 531 532 533 534
		memcpy(data, GFS2_EA2DATA(el->el_ea), len);
		return len;
	}
	ret = ea_get_unstuffed(ip, el->el_ea, data);
	if (ret < 0)
		return ret;
	return len;
D
David Teigland 已提交
535 536
}

S
Steven Whitehouse 已提交
537 538 539 540 541 542 543 544 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);
	if (error == 0)
		error = len;
	*ppdata = data;
out:
	brelse(el.el_bh);
	return error;
}

D
David Teigland 已提交
567
/**
568 569 570 571 572
 * 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
573
 * @type: The type of extended attribute
D
David Teigland 已提交
574 575 576
 *
 * Returns: actual size of data on success, -errno on error
 */
577 578
static int gfs2_xattr_get(struct dentry *dentry, const char *name,
		void *buffer, size_t size, int type)
D
David Teigland 已提交
579
{
580
	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
D
David Teigland 已提交
581 582 583
	struct gfs2_ea_location el;
	int error;

584
	if (!ip->i_eattr)
D
David Teigland 已提交
585
		return -ENODATA;
586 587
	if (strlen(name) > GFS2_EA_MAX_NAME_LEN)
		return -EINVAL;
D
David Teigland 已提交
588

589
	error = gfs2_ea_find(ip, type, name, &el);
D
David Teigland 已提交
590 591 592 593
	if (error)
		return error;
	if (!el.el_ea)
		return -ENODATA;
S
Steven Whitehouse 已提交
594
	if (size)
595 596
		error = gfs2_ea_get_copy(ip, &el, buffer, size);
	else
D
David Teigland 已提交
597 598 599 600 601 602 603 604 605
		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
606
 * @bhp: Pointer to pointer to a struct buffer_head
D
David Teigland 已提交
607 608 609 610 611 612
 *
 * Returns: errno
 */

static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
{
613
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
614
	struct gfs2_ea_header *ea;
615
	unsigned int n = 1;
616
	u64 block;
617
	int error;
D
David Teigland 已提交
618

619 620 621
	error = gfs2_alloc_block(ip, &block, &n);
	if (error)
		return error;
622
	gfs2_trans_add_unrevoke(sdp, block, 1);
D
David Teigland 已提交
623
	*bhp = gfs2_meta_new(ip->i_gl, block);
624
	gfs2_trans_add_bh(ip->i_gl, *bhp, 1);
D
David Teigland 已提交
625 626 627 628 629 630 631 632 633
	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;

634
	gfs2_add_inode_blocks(&ip->i_inode, 1);
D
David Teigland 已提交
635 636 637 638 639 640 641

	return 0;
}

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

	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 已提交
668
		__be64 *dataptr = GFS2_EA2DATAPTRS(ea);
D
David Teigland 已提交
669 670 671 672 673
		const char *data = er->er_data;
		unsigned int data_len = er->er_data_len;
		unsigned int copy;
		unsigned int x;

674
		ea->ea_num_ptrs = DIV_ROUND_UP(er->er_data_len, sdp->sd_jbsize);
D
David Teigland 已提交
675 676
		for (x = 0; x < ea->ea_num_ptrs; x++) {
			struct buffer_head *bh;
677
			u64 block;
D
David Teigland 已提交
678
			int mh_size = sizeof(struct gfs2_meta_header);
679
			unsigned int n = 1;
D
David Teigland 已提交
680

681 682 683
			error = gfs2_alloc_block(ip, &block, &n);
			if (error)
				return error;
684
			gfs2_trans_add_unrevoke(sdp, block, 1);
D
David Teigland 已提交
685
			bh = gfs2_meta_new(ip->i_gl, block);
686
			gfs2_trans_add_bh(ip->i_gl, bh, 1);
D
David Teigland 已提交
687 688
			gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);

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

691 692
			copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
							   data_len;
D
David Teigland 已提交
693 694 695 696 697
			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);

698
			*dataptr++ = cpu_to_be64(bh->b_blocknr);
D
David Teigland 已提交
699 700 701 702 703 704 705 706 707 708 709 710 711
			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,
712
				   struct gfs2_ea_request *er, void *private);
D
David Teigland 已提交
713 714 715

static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
			     unsigned int blks,
716
			     ea_skeleton_call_t skeleton_call, void *private)
D
David Teigland 已提交
717 718 719 720 721 722
{
	struct gfs2_alloc *al;
	struct buffer_head *dibh;
	int error;

	al = gfs2_alloc_get(ip);
723 724
	if (!al)
		return -ENOMEM;
D
David Teigland 已提交
725

726
	error = gfs2_quota_lock_check(ip);
D
David Teigland 已提交
727 728 729 730 731 732 733 734 735
	if (error)
		goto out;

	al->al_requested = blks;

	error = gfs2_inplace_reserve(ip);
	if (error)
		goto out_gunlock_q;

736
	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
737
				 blks + al->al_rgd->rd_length +
D
David Teigland 已提交
738 739 740 741 742 743 744 745 746 747
				 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) {
748
		ip->i_inode.i_ctime = CURRENT_TIME;
749
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
750
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
751 752 753
		brelse(dibh);
	}

754
out_end_trans:
755
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
756
out_ipres:
D
David Teigland 已提交
757
	gfs2_inplace_release(ip);
758
out_gunlock_q:
D
David Teigland 已提交
759
	gfs2_quota_unlock(ip);
760
out:
D
David Teigland 已提交
761 762 763 764 765 766 767 768 769 770 771 772 773 774
	gfs2_alloc_put(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;

775
	ip->i_eattr = bh->b_blocknr;
D
David Teigland 已提交
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
	error = ea_write(ip, GFS2_EA_BH2FIRST(bh), er);

	brelse(bh);

	return error;
}

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

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

798 799 800 801 802 803 804 805
	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 已提交
806

807
	return ea_alloc_skeleton(ip, &er, blks, ea_init_i, NULL);
D
David Teigland 已提交
808 809 810 811
}

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

834
	gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
D
David Teigland 已提交
835 836 837 838 839 840

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

	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;

868
	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
D
David Teigland 已提交
869 870 871
	if (error)
		return error;

872
	gfs2_trans_add_bh(ip->i_gl, bh, 1);
D
David Teigland 已提交
873 874 875 876 877 878 879 880 881 882 883 884

	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;
885
	ip->i_inode.i_ctime = CURRENT_TIME;
886
	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
887
	gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
888
	brelse(dibh);
889
out:
890
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
D
David Teigland 已提交
891 892 893 894 895 896 897 898 899 900
	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;

901
	gfs2_trans_add_bh(ip->i_gl, es->es_bh, 1);
D
David Teigland 已提交
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924

	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;

925 926
	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 已提交
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950

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

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

972
	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
A
Al Viro 已提交
973
		__be64 *end;
D
David Teigland 已提交
974

975
		error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT,
S
Steven Whitehouse 已提交
976
				       &indbh);
D
David Teigland 已提交
977 978 979 980 981 982 983 984
		if (error)
			return error;

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

A
Al Viro 已提交
985
		eablk = (__be64 *)(indbh->b_data + mh_size);
D
David Teigland 已提交
986 987 988 989 990 991 992 993 994 995 996
		end = eablk + sdp->sd_inptrs;

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

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

997
		gfs2_trans_add_bh(ip->i_gl, indbh, 1);
D
David Teigland 已提交
998
	} else {
999
		u64 blk;
1000
		unsigned int n = 1;
1001 1002 1003
		error = gfs2_alloc_block(ip, &blk, &n);
		if (error)
			return error;
1004
		gfs2_trans_add_unrevoke(sdp, blk, 1);
D
David Teigland 已提交
1005
		indbh = gfs2_meta_new(ip->i_gl, blk);
1006
		gfs2_trans_add_bh(ip->i_gl, indbh, 1);
D
David Teigland 已提交
1007 1008 1009
		gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
		gfs2_buffer_clear_tail(indbh, mh_size);

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

		eablk++;
	}

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

1023
	*eablk = cpu_to_be64((u64)newbh->b_blocknr);
D
David Teigland 已提交
1024 1025 1026 1027 1028 1029
	error = ea_write(ip, GFS2_EA_BH2FIRST(newbh), er);
	brelse(newbh);
	if (error)
		goto out;

	if (private)
1030
		ea_set_remove_stuffed(ip, private);
D
David Teigland 已提交
1031

1032
out:
D
David Teigland 已提交
1033 1034 1035 1036
	brelse(indbh);
	return error;
}

1037 1038
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 已提交
1039
{
1040
	struct gfs2_ea_request er;
D
David Teigland 已提交
1041 1042 1043 1044
	struct ea_set es;
	unsigned int blks = 2;
	int error;

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

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

1061
	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT))
D
David Teigland 已提交
1062
		blks++;
1063 1064
	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 已提交
1065

1066
	return ea_alloc_skeleton(ip, &er, blks, ea_set_block, el);
D
David Teigland 已提交
1067 1068 1069 1070 1071 1072 1073
}

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);
1074
		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
D
David Teigland 已提交
1075 1076 1077
				     GFS2_EA2NEXT(el->el_prev) == el->el_ea);
	}

S
Steven Whitehouse 已提交
1078
	return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev, 0);
D
David Teigland 已提交
1079 1080 1081 1082 1083 1084 1085 1086 1087
}

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;

1088
	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
D
David Teigland 已提交
1089 1090 1091
	if (error)
		return error;

1092
	gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
D
David Teigland 已提交
1093 1094

	if (prev) {
1095
		u32 len;
D
David Teigland 已提交
1096 1097 1098 1099 1100 1101

		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;
1102
	} else {
D
David Teigland 已提交
1103
		ea->ea_type = GFS2_EATYPE_UNUSED;
1104
	}
D
David Teigland 已提交
1105 1106 1107

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
1108
		ip->i_inode.i_ctime = CURRENT_TIME;
1109
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1110
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
1111
		brelse(dibh);
1112
	}
D
David Teigland 已提交
1113

1114
	gfs2_trans_end(GFS2_SB(&ip->i_inode));
D
David Teigland 已提交
1115 1116 1117 1118

	return error;
}

1119 1120
/**
 * gfs2_xattr_remove - Remove a GFS2 extended attribute
1121
 * @ip: The inode
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
 * @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
 */

1132
static int gfs2_xattr_remove(struct gfs2_inode *ip, int type, const char *name)
D
David Teigland 已提交
1133 1134 1135 1136
{
	struct gfs2_ea_location el;
	int error;

1137
	if (!ip->i_eattr)
D
David Teigland 已提交
1138 1139
		return -ENODATA;

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

	brelse(el.el_bh);

	return error;
}

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

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

1179 1180 1181 1182
	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
		return -EPERM;
	if (namel > GFS2_EA_MAX_NAME_LEN)
		return -ERANGE;
D
David Teigland 已提交
1183

1184
	if (value == NULL)
1185
		return gfs2_xattr_remove(ip, type, name);
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196

	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 已提交
1197 1198 1199
	if (error)
		return error;

1200 1201 1202 1203 1204
	if (el.el_ea) {
		if (ip->i_diskflags & GFS2_DIF_APPENDONLY) {
			brelse(el.el_bh);
			return -EPERM;
		}
D
David Teigland 已提交
1205

1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220
		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 已提交
1221 1222 1223 1224

	return error;
}

1225 1226 1227 1228 1229 1230 1231
static int gfs2_xattr_set(struct dentry *dentry, const char *name,
		const void *value, size_t size, int flags, int type)
{
	return __gfs2_xattr_set(dentry->d_inode, name, value,
				size, flags, type);
}

D
David Teigland 已提交
1232 1233 1234
static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
				  struct gfs2_ea_header *ea, char *data)
{
1235
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
1236 1237
	struct buffer_head **bh;
	unsigned int amount = GFS2_EA_DATA_LEN(ea);
1238
	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
A
Al Viro 已提交
1239
	__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
D
David Teigland 已提交
1240 1241 1242
	unsigned int x;
	int error;

J
Josef Bacik 已提交
1243
	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
D
David Teigland 已提交
1244 1245 1246 1247 1248 1249 1250 1251
	if (!bh)
		return -ENOMEM;

	error = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
	if (error)
		goto out;

	for (x = 0; x < nptrs; x++) {
S
Steven Whitehouse 已提交
1252 1253
		error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
				       bh + x);
D
David Teigland 已提交
1254 1255 1256 1257 1258 1259 1260 1261 1262
		if (error) {
			while (x--)
				brelse(bh[x]);
			goto fail;
		}
		dataptrs++;
	}

	for (x = 0; x < nptrs; x++) {
S
Steven Whitehouse 已提交
1263
		error = gfs2_meta_wait(sdp, bh[x]);
D
David Teigland 已提交
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
		if (error) {
			for (; x < nptrs; x++)
				brelse(bh[x]);
			goto fail;
		}
		if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
			for (; x < nptrs; x++)
				brelse(bh[x]);
			error = -EIO;
			goto fail;
		}

1276
		gfs2_trans_add_bh(ip->i_gl, bh[x], 1);
D
David Teigland 已提交
1277

1278
		memcpy(bh[x]->b_data + sizeof(struct gfs2_meta_header), data,
D
David Teigland 已提交
1279 1280 1281 1282 1283 1284 1285 1286
		       (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);

		amount -= sdp->sd_jbsize;
		data += sdp->sd_jbsize;

		brelse(bh[x]);
	}

1287
out:
D
David Teigland 已提交
1288 1289 1290
	kfree(bh);
	return error;

1291
fail:
D
David Teigland 已提交
1292 1293 1294 1295 1296
	gfs2_trans_end(sdp);
	kfree(bh);
	return error;
}

S
Steven Whitehouse 已提交
1297
int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
D
David Teigland 已提交
1298
{
1299
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
S
Steven Whitehouse 已提交
1300
	struct gfs2_ea_location el;
D
David Teigland 已提交
1301 1302 1303
	struct buffer_head *dibh;
	int error;

S
Steven Whitehouse 已提交
1304 1305 1306 1307 1308
	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)) {
1309 1310 1311 1312 1313 1314 1315
		error = gfs2_trans_begin(sdp, RES_DINODE + RES_EATTR, 0);
		if (error == 0) {
			gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1);
			memcpy(GFS2_EA2DATA(el.el_ea), data,
			       GFS2_EA_DATA_LEN(el.el_ea));
		}
	} else {
S
Steven Whitehouse 已提交
1316
		error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
1317
	}
D
David Teigland 已提交
1318

1319
	brelse(el.el_bh);
D
David Teigland 已提交
1320 1321 1322 1323 1324
	if (error)
		return error;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
1325 1326
		error = inode_setattr(&ip->i_inode, attr);
		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
1327
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1328
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
1329 1330 1331
		brelse(dibh);
	}

1332
	gfs2_trans_end(sdp);
D
David Teigland 已提交
1333 1334 1335 1336 1337
	return error;
}

static int ea_dealloc_indirect(struct gfs2_inode *ip)
{
1338
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
D
David Teigland 已提交
1339 1340
	struct gfs2_rgrp_list rlist;
	struct buffer_head *indbh, *dibh;
A
Al Viro 已提交
1341
	__be64 *eablk, *end;
D
David Teigland 已提交
1342
	unsigned int rg_blocks = 0;
1343
	u64 bstart = 0;
D
David Teigland 已提交
1344 1345 1346 1347 1348 1349 1350
	unsigned int blen = 0;
	unsigned int blks = 0;
	unsigned int x;
	int error;

	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));

1351
	error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh);
D
David Teigland 已提交
1352 1353 1354 1355 1356 1357 1358 1359
	if (error)
		return error;

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

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

	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 1380 1381 1382 1383 1384

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

		if (bstart + blen == bn)
			blen++;
		else {
			if (bstart)
				gfs2_rlist_add(sdp, &rlist, bstart);
			bstart = bn;
			blen = 1;
		}
		blks++;
	}
	if (bstart)
		gfs2_rlist_add(sdp, &rlist, bstart);
	else
		goto out;

1385
	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
D
David Teigland 已提交
1386 1387 1388

	for (x = 0; x < rlist.rl_rgrps; x++) {
		struct gfs2_rgrpd *rgd;
1389
		rgd = rlist.rl_ghs[x].gh_gl->gl_object;
1390
		rg_blocks += rgd->rd_length;
D
David Teigland 已提交
1391 1392 1393 1394 1395 1396
	}

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

1397 1398
	error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + RES_INDIRECT +
				 RES_STATFS + RES_QUOTA, blks);
D
David Teigland 已提交
1399 1400 1401
	if (error)
		goto out_gunlock;

1402
	gfs2_trans_add_bh(ip->i_gl, indbh, 1);
D
David Teigland 已提交
1403

A
Al Viro 已提交
1404
	eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
D
David Teigland 已提交
1405 1406 1407 1408
	bstart = 0;
	blen = 0;

	for (; eablk < end; eablk++) {
1409
		u64 bn;
D
David Teigland 已提交
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424

		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;
1425
		gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
1426 1427 1428 1429
	}
	if (bstart)
		gfs2_free_meta(ip, bstart, blen);

1430
	ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT;
D
David Teigland 已提交
1431 1432 1433

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
1434
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1435
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
1436 1437 1438 1439 1440
		brelse(dibh);
	}

	gfs2_trans_end(sdp);

1441
out_gunlock:
D
David Teigland 已提交
1442
	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
1443
out_rlist_free:
D
David Teigland 已提交
1444
	gfs2_rlist_free(&rlist);
1445
out:
D
David Teigland 已提交
1446 1447 1448 1449 1450 1451
	brelse(indbh);
	return error;
}

static int ea_dealloc_block(struct gfs2_inode *ip)
{
1452
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1453
	struct gfs2_alloc *al = ip->i_alloc;
D
David Teigland 已提交
1454 1455 1456 1457
	struct gfs2_rgrpd *rgd;
	struct buffer_head *dibh;
	int error;

1458
	rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr);
D
David Teigland 已提交
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468
	if (!rgd) {
		gfs2_consist_inode(ip);
		return -EIO;
	}

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

1469 1470
	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_DINODE + RES_STATFS +
				 RES_QUOTA, 1);
D
David Teigland 已提交
1471 1472 1473
	if (error)
		goto out_gunlock;

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

1476
	ip->i_eattr = 0;
1477
	gfs2_add_inode_blocks(&ip->i_inode, -1);
D
David Teigland 已提交
1478 1479 1480

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
1481
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1482
		gfs2_dinode_out(ip, dibh->b_data);
D
David Teigland 已提交
1483 1484 1485 1486 1487
		brelse(dibh);
	}

	gfs2_trans_end(sdp);

1488
out_gunlock:
D
David Teigland 已提交
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
	gfs2_glock_dq_uninit(&al->al_rgd_gh);
	return error;
}

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

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

	al = gfs2_alloc_get(ip);
1506 1507
	if (!al)
		return -ENOMEM;
D
David Teigland 已提交
1508 1509 1510 1511 1512

	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
	if (error)
		goto out_alloc;

1513
	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
D
David Teigland 已提交
1514 1515 1516 1517 1518 1519 1520
	if (error)
		goto out_quota;

	error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
	if (error)
		goto out_rindex;

1521
	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
D
David Teigland 已提交
1522 1523 1524 1525 1526 1527 1528
		error = ea_dealloc_indirect(ip);
		if (error)
			goto out_rindex;
	}

	error = ea_dealloc_block(ip);

1529
out_rindex:
D
David Teigland 已提交
1530
	gfs2_glock_dq_uninit(&al->al_ri_gh);
1531
out_quota:
D
David Teigland 已提交
1532
	gfs2_quota_unhold(ip);
1533
out_alloc:
D
David Teigland 已提交
1534 1535 1536 1537
	gfs2_alloc_put(ip);
	return error;
}

1538 1539
static struct xattr_handler gfs2_xattr_user_handler = {
	.prefix = XATTR_USER_PREFIX,
1540 1541 1542
	.flags  = GFS2_EATYPE_USR,
	.get    = gfs2_xattr_get,
	.set    = gfs2_xattr_set,
1543 1544 1545 1546
};

static struct xattr_handler gfs2_xattr_security_handler = {
	.prefix = XATTR_SECURITY_PREFIX,
1547 1548 1549
	.flags  = GFS2_EATYPE_SECURITY,
	.get    = gfs2_xattr_get,
	.set    = gfs2_xattr_set,
1550 1551 1552 1553 1554 1555 1556 1557 1558
};

struct xattr_handler *gfs2_xattr_handlers[] = {
	&gfs2_xattr_user_handler,
	&gfs2_xattr_security_handler,
	&gfs2_xattr_system_handler,
	NULL,
};