public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Brian Foster <bfoster@redhat.com>
To: Sage Weil <sage@inktank.com>
Cc: xfs@oss.sgi.com
Subject: Re: E2BIG from listxattr
Date: Wed, 26 Mar 2014 17:35:49 -0400	[thread overview]
Message-ID: <20140326213548.GB4128@laptop.bfoster> (raw)
In-Reply-To: <alpine.DEB.2.00.1403252242220.893@cobra.newdream.net>

On Tue, Mar 25, 2014 at 10:48:08PM -0700, Sage Weil wrote:
> Hi,
> 
> If you create a bunch of xattrs on an inode, you can get into a sitation 
> where you can no longer list them.  The reproducer below just does 
> setxattr until it gets an error or listxattr starts returning E2BIG.  Once 
> you're in this state you can getxattr attrs you know the name of, but you 
> can't list them, which is a bit inconvenient.
> 
> Presumably the fix is for setxattr to verify that the list of all xattr 
> names will fit into a 64K buffer or else return ENOSPC...
> 

Hi Sage,

I think doing something like this would be an artificial restriction on
XFS. The listxattr() function in the vfs actually caps the provided
buffer to 64k. This in turn causes an error in XFS, which is capable of
filling a larger buffer, and the VFS converts that error into E2BIG.

I ran a quick experiment to remove that bit of code from listxattr() and
modified your program to use a 128k buffer. Everything still seems to
work Ok until I exhaust that buffer. Given that and the fact that
listxattr() does an allocation of the user-provided size, I suspect the
64k restriction here is some kind of policy based on memory allocation,
but that's a guess. The right fix might be something more involved, such
as fixing the interface to handle larger sets of data (e.g., copy direct
to a user buffer, or introduce an iterative interface, etc.).

Brian

> sage
> 
> 
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/types.h>
> #include <sys/xattr.h>
> #include <string.h>
> #include <errno.h>
> 
> int main(int argc, char **argv)
> {
> 	char *fn = argv[1];
> 	char buf[655360];
> 	int buflen = sizeof(buf);
> 	int i;
> 
> 	for (i = 0; i < 10000; ++i) {
> 		int r = listxattr(fn, buf, buflen);
> 		if (r < 0) {
> 			perror("listxattr");
> 			return 1;
> 		}
> 		char n[100];
> 		sprintf(n, "user.foooooooooooooooooooooooooooooooooooooo%d", i);
> 		r = setxattr(fn, n, "", 0, 0);
> 		if (r < 0) {
> 			perror("setxattr");
> 			return 1;
> 		}
> 		printf("set %d\n", i);
> 	}
> 	return 0;
> }
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  reply	other threads:[~2014-03-26 21:35 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-26  5:48 E2BIG from listxattr Sage Weil
2014-03-26 21:35 ` Brian Foster [this message]
2014-03-27 16:07   ` Sage Weil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140326213548.GB4128@laptop.bfoster \
    --to=bfoster@redhat.com \
    --cc=sage@inktank.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox