tools/testing/selftests/filesystems/xattr/xattr_sockfs_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/filesystems/xattr/xattr_sockfs_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/filesystems/xattr/xattr_sockfs_test.c
Extension
.c
Size
9130 bytes
Lines
364
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

ASSERT_EQ(ret, 0) {
			TH_LOG("fsetxattr %s failed at i=%d: %s",
			       name, i, strerror(errno));
		}
	}

	ret = fsetxattr(self->sockfd, "user.overflow", "v", 1, 0);
	ASSERT_EQ(ret, -1);
	ASSERT_EQ(errno, ENOSPC) {
		TH_LOG("Expected ENOSPC for xattr %d, got %s",
		       SIMPLE_XATTR_MAX_NR + 1, strerror(errno));
	}
}

/*
 * Test maximum total value size for user.* xattrs.
 * The kernel enforces SIMPLE_XATTR_MAX_SIZE (128KB). Individual xattr
 * values are limited to XATTR_SIZE_MAX (64KB) by the VFS, so we need
 * at least two xattrs to hit the total limit.
 */
TEST_F(xattr_sockfs, max_xattr_size)
{
	char *value;
	int ret;

	value = malloc(XATTR_SIZE_MAX);
	ASSERT_NE(value, NULL);
	memset(value, 'A', XATTR_SIZE_MAX);

	/* First 64KB xattr - total = 64KB */
	ret = fsetxattr(self->sockfd, "user.big1", value, XATTR_SIZE_MAX, 0);
	ASSERT_EQ(ret, 0) {
		TH_LOG("first large xattr failed: %s", strerror(errno));
	}

	/* Second 64KB xattr - total = 128KB (exactly at limit) */
	ret = fsetxattr(self->sockfd, "user.big2", value, XATTR_SIZE_MAX, 0);
	free(value);
	ASSERT_EQ(ret, 0) {
		TH_LOG("second large xattr failed: %s", strerror(errno));
	}

	/* Third xattr with 1 byte - total > 128KB, should fail */
	ret = fsetxattr(self->sockfd, "user.big3", "v", 1, 0);
	ASSERT_EQ(ret, -1);
	ASSERT_EQ(errno, ENOSPC) {
		TH_LOG("Expected ENOSPC when exceeding size limit, got %s",
		       strerror(errno));
	}
}

/*
 * Test that removing an xattr frees limit space, allowing re-addition.
 */
TEST_F(xattr_sockfs, limit_remove_readd)
{
	char name[32];
	int i, ret;

	/* Fill up to the maximum count */
	for (i = 0; i < SIMPLE_XATTR_MAX_NR; i++) {
		snprintf(name, sizeof(name), "user.test%03d", i);
		ret = fsetxattr(self->sockfd, name, "v", 1, 0);
		ASSERT_EQ(ret, 0);
	}

	/* Verify we're at the limit */
	ret = fsetxattr(self->sockfd, "user.overflow", "v", 1, 0);
	ASSERT_EQ(ret, -1);
	ASSERT_EQ(errno, ENOSPC);

	/* Remove one xattr */
	ret = fremovexattr(self->sockfd, "user.test000");
	ASSERT_EQ(ret, 0);

	/* Now we should be able to add one more */
	ret = fsetxattr(self->sockfd, "user.newattr", "v", 1, 0);
	ASSERT_EQ(ret, 0) {
		TH_LOG("re-add after remove failed: %s", strerror(errno));
	}
}

/*
 * Test that two different sockets have independent xattr limits.
 */
TEST_F(xattr_sockfs, limits_per_inode)
{
	char buf[256];
	int sock2;
	ssize_t ret;

Annotation

Implementation Notes