View | Details | Raw Unified | Return to bug 65424
Collapse All | Expand All

(-)linux-2.4.21/fs/ext3/xattr.c (-14 / +14 lines)
Lines 43-54 Link Here
43
 *
43
 *
44
 * Locking strategy
44
 * Locking strategy
45
 * ----------------
45
 * ----------------
46
 * EXT3_I(inode)->i_file_acl is protected by EXT3_I(inode)->xattr_sem.
46
 * As a minimal fix of a race with the mbcache, we are using a global
47
 * EA blocks are only changed if they are exclusive to an inode, so
47
 * readers/writer semaphore (http://linux.bkbits.net:8080/linux-2.6/
48
 * holding xattr_sem also means that nothing but the EA block's reference
48
 * cset@41e9a8dde680BhQtidQ5PNNkGXHKMQ?nav=index.html|ChangeSet@-8w
49
 * count will change. Multiple writers to an EA block are synchronized
49
 * explains the problem).
50
 * by the bh lock. No more than a single bh lock is held at any time,
51
 * which avoids deadlocks.
52
 */
50
 */
53
51
54
#include <linux/fs.h>
52
#include <linux/fs.h>
Lines 84-89 Link Here
84
# define ea_bdebug(f...)
82
# define ea_bdebug(f...)
85
#endif
83
#endif
86
84
85
static DECLARE_RWSEM(ext3_xattr_sem);
86
87
static int ext3_xattr_set_handle2(handle_t *, struct inode *,
87
static int ext3_xattr_set_handle2(handle_t *, struct inode *,
88
				  struct buffer_head *,
88
				  struct buffer_head *,
89
				  struct ext3_xattr_header *);
89
				  struct ext3_xattr_header *);
Lines 280-286 ext3_xattr_get(struct inode *inode, int Link Here
280
280
281
	if (name == NULL)
281
	if (name == NULL)
282
		return -EINVAL;
282
		return -EINVAL;
283
	down_read(&EXT3_I(inode)->xattr_sem);
283
	down_read(&ext3_xattr_sem);
284
	error = -ENODATA;
284
	error = -ENODATA;
285
	if (!EXT3_I(inode)->i_file_acl)
285
	if (!EXT3_I(inode)->i_file_acl)
286
		goto cleanup;
286
		goto cleanup;
Lines 353-359 found: Link Here
353
353
354
cleanup:
354
cleanup:
355
	brelse(bh);
355
	brelse(bh);
356
	up_read(&EXT3_I(inode)->xattr_sem);
356
	up_read(&ext3_xattr_sem);
357
357
358
	return error;
358
	return error;
359
}
359
}
Lines 380-386 ext3_xattr_list(struct inode *inode, cha Link Here
380
	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
380
	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
381
		  buffer, (long)buffer_size);
381
		  buffer, (long)buffer_size);
382
382
383
	down_read(&EXT3_I(inode)->xattr_sem);
383
	down_read(&ext3_xattr_sem);
384
	error = 0;
384
	error = 0;
385
	if (!EXT3_I(inode)->i_file_acl)
385
	if (!EXT3_I(inode)->i_file_acl)
386
		goto cleanup;
386
		goto cleanup;
Lines 441-447 bad_block: ext3_error(inode->i_sb, "ext3 Link Here
441
441
442
cleanup:
442
cleanup:
443
	brelse(bh);
443
	brelse(bh);
444
	up_read(&EXT3_I(inode)->xattr_sem);
444
	up_read(&ext3_xattr_sem);
445
445
446
	return error;
446
	return error;
447
}
447
}
Lines 517-523 ext3_xattr_set_handle(handle_t *handle, Link Here
517
	name_len = strlen(name);
517
	name_len = strlen(name);
518
	if (name_len > 255 || value_len > sb->s_blocksize)
518
	if (name_len > 255 || value_len > sb->s_blocksize)
519
		return -ERANGE;
519
		return -ERANGE;
520
	down_write(&EXT3_I(inode)->xattr_sem);
520
	down_write(&ext3_xattr_sem);
521
	if (EXT3_I(inode)->i_file_acl) {
521
	if (EXT3_I(inode)->i_file_acl) {
522
		/* The inode already has an extended attribute block. */
522
		/* The inode already has an extended attribute block. */
523
		bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
523
		bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
Lines 740-746 cleanup: Link Here
740
	brelse(bh);
740
	brelse(bh);
741
	if (!(bh && header == HDR(bh)))
741
	if (!(bh && header == HDR(bh)))
742
		kfree(header);
742
		kfree(header);
743
	up_write(&EXT3_I(inode)->xattr_sem);
743
	up_write(&ext3_xattr_sem);
744
744
745
	return error;
745
	return error;
746
}
746
}
Lines 911-917 ext3_xattr_delete_inode(handle_t *handle Link Here
911
{
911
{
912
	struct buffer_head *bh = NULL;
912
	struct buffer_head *bh = NULL;
913
913
914
	down_write(&EXT3_I(inode)->xattr_sem);
914
	down_write(&ext3_xattr_sem);
915
	if (!EXT3_I(inode)->i_file_acl)
915
	if (!EXT3_I(inode)->i_file_acl)
916
		goto cleanup;
916
		goto cleanup;
917
	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
917
	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
Lines 954-960 ext3_xattr_delete_inode(handle_t *handle Link Here
954
954
955
cleanup:
955
cleanup:
956
	brelse(bh);
956
	brelse(bh);
957
	up_write(&EXT3_I(inode)->xattr_sem);
957
	up_write(&ext3_xattr_sem);
958
}
958
}
959
959
960
/*
960
/*
(-)linux-2.4.21/fs/ext2/xattr.c (-14 / +14 lines)
Lines 42-53 Link Here
42
 *
42
 *
43
 * Locking strategy
43
 * Locking strategy
44
 * ----------------
44
 * ----------------
45
 * EXT2_I(inode)->i_file_acl is protected by EXT2_I(inode)->xattr_sem.
45
 * As a minimal fix of a race with the mbcache, we are using a global
46
 * EA blocks are only changed if they are exclusive to an inode, so
46
 * readers/writer semaphore (http://linux.bkbits.net:8080/linux-2.6/
47
 * holding xattr_sem also means that nothing but the EA block's reference
47
 * cset@41e9a8dde680BhQtidQ5PNNkGXHKMQ?nav=index.html|ChangeSet@-8w
48
 * count will change. Multiple writers to an EA block are synchronized
48
 * explains the problem).
49
 * by the bh lock. No more than a single bh lock is held at any time,
50
 * which avoids deadlocks.
51
 */
49
 */
52
50
53
#include <linux/module.h>
51
#include <linux/module.h>
Lines 90-95 EXPORT_SYMBOL(ext2_xattr_set); Link Here
90
# define ea_bdebug(f...)
88
# define ea_bdebug(f...)
91
#endif
89
#endif
92
90
91
static DECLARE_RWSEM(ext2_xattr_sem);
92
93
static int ext2_xattr_set2(struct inode *, struct buffer_head *,
93
static int ext2_xattr_set2(struct inode *, struct buffer_head *,
94
			   struct ext2_xattr_header *);
94
			   struct ext2_xattr_header *);
95
95
Lines 285-291 ext2_xattr_get(struct inode *inode, int Link Here
285
285
286
	if (name == NULL)
286
	if (name == NULL)
287
		return -EINVAL;
287
		return -EINVAL;
288
	down_read(&EXT2_I(inode)->xattr_sem);
288
	down_read(&ext2_xattr_sem);
289
	error = -ENODATA;
289
	error = -ENODATA;
290
	if (!EXT2_I(inode)->i_file_acl)
290
	if (!EXT2_I(inode)->i_file_acl)
291
		goto cleanup;
291
		goto cleanup;
Lines 358-364 found: Link Here
358
358
359
cleanup:
359
cleanup:
360
	brelse(bh);
360
	brelse(bh);
361
	up_read(&EXT2_I(inode)->xattr_sem);
361
	up_read(&ext2_xattr_sem);
362
362
363
	return error;
363
	return error;
364
}
364
}
Lines 385-391 ext2_xattr_list(struct inode *inode, cha Link Here
385
	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
385
	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
386
		  buffer, (long)buffer_size);
386
		  buffer, (long)buffer_size);
387
387
388
	down_read(&EXT2_I(inode)->xattr_sem);
388
	down_read(&ext2_xattr_sem);
389
	error = 0;
389
	error = 0;
390
	if (!EXT2_I(inode)->i_file_acl)
390
	if (!EXT2_I(inode)->i_file_acl)
391
		goto cleanup;
391
		goto cleanup;
Lines 446-452 bad_block: ext2_error(inode->i_sb, "ext2 Link Here
446
446
447
cleanup:
447
cleanup:
448
	brelse(bh);
448
	brelse(bh);
449
	up_read(&EXT2_I(inode)->xattr_sem);
449
	up_read(&ext2_xattr_sem);
450
450
451
	return error;
451
	return error;
452
}
452
}
Lines 518-524 ext2_xattr_set(struct inode *inode, int Link Here
518
	name_len = strlen(name);
518
	name_len = strlen(name);
519
	if (name_len > 255 || value_len > sb->s_blocksize)
519
	if (name_len > 255 || value_len > sb->s_blocksize)
520
		return -ERANGE;
520
		return -ERANGE;
521
	down_write(&EXT2_I(inode)->xattr_sem);
521
	down_write(&ext2_xattr_sem);
522
	if (EXT2_I(inode)->i_file_acl) {
522
	if (EXT2_I(inode)->i_file_acl) {
523
		/* The inode already has an extended attribute block. */
523
		/* The inode already has an extended attribute block. */
524
524
Lines 733-739 cleanup: Link Here
733
	brelse(bh);
733
	brelse(bh);
734
	if (!(bh && header == HDR(bh)))
734
	if (!(bh && header == HDR(bh)))
735
		kfree(header);
735
		kfree(header);
736
	up_write(&EXT2_I(inode)->xattr_sem);
736
	up_write(&ext2_xattr_sem);
737
737
738
	return error;
738
	return error;
739
}
739
}
Lines 866-872 ext2_xattr_delete_inode(struct inode *in Link Here
866
{
866
{
867
	struct buffer_head *bh = NULL;
867
	struct buffer_head *bh = NULL;
868
868
869
	down_write(&EXT2_I(inode)->xattr_sem);
869
	down_write(&ext2_xattr_sem);
870
	if (!EXT2_I(inode)->i_file_acl)
870
	if (!EXT2_I(inode)->i_file_acl)
871
		goto cleanup;
871
		goto cleanup;
872
	bh = sb_bread(inode->i_sb, EXT2_I(inode)->i_file_acl);
872
	bh = sb_bread(inode->i_sb, EXT2_I(inode)->i_file_acl);
Lines 905-911 ext2_xattr_delete_inode(struct inode *in Link Here
905
905
906
cleanup:
906
cleanup:
907
	brelse(bh);
907
	brelse(bh);
908
	up_write(&EXT2_I(inode)->xattr_sem);
908
	up_write(&ext2_xattr_sem);
909
}
909
}
910
910
911
/*
911
/*

Return to bug 65424