Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't remove SA xattr when xattr=on #3472

Closed
nedbass opened this issue Jun 4, 2015 · 9 comments
Closed

Can't remove SA xattr when xattr=on #3472

nedbass opened this issue Jun 4, 2015 · 9 comments

Comments

@nedbass
Copy link
Contributor

nedbass commented Jun 4, 2015

If a file has an SA-based xattr but the dataset has xattr=on set, the SA-based xattr cannot be removed.

$ zfs get xattr rpool/satest
NAME          PROPERTY  VALUE  SOURCE
rpool/satest  xattr     sa     local
$ touch /rpool/satest/ZZZ
$ setfattr -n user.foo -v ZZZ /rpool/satest/ZZZ
$ getfattr -n user.foo  /rpool/satest/ZZZ
getfattr: Removing leading '/' from absolute path names
# file: rpool/satest/ZZZ
user.foo="ZZZ"

$ zfs set xattr=on rpool/satest
$ setfattr -x user.foo /rpool/satest/ZZZ
setfattr: /rpool/satest/ZZZ: No such attribute           <--------- this should succeed
$ getfattr -n user.foo  /rpool/satest/ZZZ
getfattr: Removing leading '/' from absolute path names
# file: rpool/satest/ZZZ
user.foo="ZZZ"

$ zfs set xattr=sa rpool/satest
$ setfattr -x user.foo /rpool/satest/ZZZ
$ getfattr -n user.foo  /rpool/satest/ZZZ
/rpool/satest/ZZZ: user.foo: No such attribute
@lundman
Copy link
Contributor

lundman commented Jun 5, 2015

I noticed this when we added xattr=sa to OSX. It has some other situations as well (if I remember correctly, having the same xattr in both SA and "on" could lead to doubles when listing).

It felt like xattr=sa should be a creation-time setting, and going from xattr=sa to xattr=on is not supported. But since you bring it up here, perhaps that wasn't intentional.. ?

@nedbass
Copy link
Contributor Author

nedbass commented Jun 5, 2015

I believe the intention is/was to support switching back and forth. There are situations where it will fall back to a directory-based xattr anyways. If the total size for all xattrs on a file gets too big (I think more than half the maximum block size?).

@dweeezil
Copy link
Contributor

dweeezil commented Jun 5, 2015

I've got a patch in one of my branches that starts trying to make it work more sensibly. I'll try to dig it up.

EDIT: Removed email quoting.

@dweeezil
Copy link
Contributor

dweeezil commented Jun 5, 2015

The patch I was working on is at https://github.com/dweeezil/zfs/tree/xattr-sa. One of the first issues I was trying to address is the apparent duplicates seen when iterating the xattrs and when the same xattr exists as an SA xattr and a dir-style xattr.

@mmehnert
Copy link
Contributor

mmehnert commented Dec 9, 2015

@dweeezil Have you tried that patch in production?
I'm having troubles with a samba server with very intensive xattr-usage for the Windows-ACLs (I can no longer set permissions on directories with very high numbers of files since the icacls command fails with an "unexpected network error" after some hours.)
I've used xattr=sa some versions back but ran into problems (duplicate xattrs ...).
If I read your patch correctly, it will replace xattrs according to the current xattr setting whenever they are changed / when zpl_xattr_set is called. That still does not seem to be the case in the current official code base...
So should I risk it? ;-)

@mmehnert
Copy link
Contributor

0e08566 looked straight forward enough to me so I just went with it. So far it works as advertised. Is there something missing that prevents it from inclusion?

@mmehnert
Copy link
Contributor

@dweeezil I just saw that in #2686 you said "IIRC, the main issue I've got with this patch is that it doesn't clean up the xattr directory when transitioning from directory-style to SA-style."
Is that something serious? ;-D Should I revert to a backup?

@dweeezil
Copy link
Contributor

@mmehnert I've not exercised the patch very thoroughly and, quite honestly, it's been quite awhile since I wrote it. AFAIK, it ought to be safe and leaving the empty xattr directory laying around should not cause any problems. I think the main reason I didn't post a pull request as-is is because I wanted to make this patch part of a larger rationalization of sa-versus-dir xattrs, possibly including additional values of the xattr property to provide for more fine-grained control over the manner in which transitions between xattr=on and xattr=sa are handled. At this point, I suspect you've given it more of a workout than I ever did :)

@mmehnert
Copy link
Contributor

@dweeezil
Ok. Then I'll continue using it. A windows client is currently constantly changing ACLs for about 12 hours now without problems and manually checking the xattrs yields the expected result (no duplicates).
Thanks!

goulvenriou pushed a commit to Alyseo/zfs that referenced this issue Jan 17, 2016
When replacing an xattr would cause overflowing in SA, we would fallback
to xattr dir. However, current implementation don't clear the one in SA,
so we would end up with duplicated SA.

For example, running the following script on an xattr=sa filesystem
would cause duplicated "user.1".

-- dup_xattr.sh begin --
randbase64()
{
        dd if=/dev/urandom bs=1 count=$1 2>/dev/null | openssl enc -a -A
}

file=$1
touch $file
setfattr -h -n user.1 -v `randbase64 5000` $file
setfattr -h -n user.2 -v `randbase64 20000` $file
setfattr -h -n user.3 -v `randbase64 20000` $file
setfattr -h -n user.1 -v `randbase64 20000` $file
getfattr -m. -d $file
-- dup_xattr.sh end --

Also, when a filesystem is switch from xattr=sa to xattr=on, it will
never modify those in SA. This would cause strange behavior like, you
cannot delete an xattr, or setxattr would cause duplicate and the result
would not match when you getxattr.

For example, the following shell sequence.

-- shell begin --
$ sudo zfs set xattr=sa pp/fs0
$ touch zzz
$ setfattr -n user.test -v asdf zzz
$ sudo zfs set xattr=on pp/fs0
$ setfattr -x user.test zzz
setfattr: zzz: No such attribute
$ getfattr -d zzz
user.test="asdf"
$ setfattr -n user.test -v zxcv zzz
$ getfattr -d zzz
user.test="asdf"
user.test="asdf"
-- shell end --

We fix this behavior, by first finding where the xattr resides before
setxattr. Then, after we successfully updated the xattr in one location,
we will clear the other location. Note that, because update and clear
are not in single tx, we could still end up with duplicated xattr. But
by doing setxattr again, it can be fixed.

Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Closes openzfs#3472
Closes openzfs#4153
behlendorf pushed a commit that referenced this issue Jan 29, 2016
When replacing an xattr would cause overflowing in SA, we would fallback
to xattr dir. However, current implementation don't clear the one in SA,
so we would end up with duplicated SA.

For example, running the following script on an xattr=sa filesystem
would cause duplicated "user.1".

-- dup_xattr.sh begin --
randbase64()
{
        dd if=/dev/urandom bs=1 count=$1 2>/dev/null | openssl enc -a -A
}

file=$1
touch $file
setfattr -h -n user.1 -v `randbase64 5000` $file
setfattr -h -n user.2 -v `randbase64 20000` $file
setfattr -h -n user.3 -v `randbase64 20000` $file
setfattr -h -n user.1 -v `randbase64 20000` $file
getfattr -m. -d $file
-- dup_xattr.sh end --

Also, when a filesystem is switch from xattr=sa to xattr=on, it will
never modify those in SA. This would cause strange behavior like, you
cannot delete an xattr, or setxattr would cause duplicate and the result
would not match when you getxattr.

For example, the following shell sequence.

-- shell begin --
$ sudo zfs set xattr=sa pp/fs0
$ touch zzz
$ setfattr -n user.test -v asdf zzz
$ sudo zfs set xattr=on pp/fs0
$ setfattr -x user.test zzz
setfattr: zzz: No such attribute
$ getfattr -d zzz
user.test="asdf"
$ setfattr -n user.test -v zxcv zzz
$ getfattr -d zzz
user.test="asdf"
user.test="asdf"
-- shell end --

We fix this behavior, by first finding where the xattr resides before
setxattr. Then, after we successfully updated the xattr in one location,
we will clear the other location. Note that, because update and clear
are not in single tx, we could still end up with duplicated xattr. But
by doing setxattr again, it can be fixed.

Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Closes #3472
Closes #4153
goulvenriou pushed a commit to Alyseo/zfs that referenced this issue Feb 4, 2016
When replacing an xattr would cause overflowing in SA, we would fallback
to xattr dir. However, current implementation don't clear the one in SA,
so we would end up with duplicated SA.

For example, running the following script on an xattr=sa filesystem
would cause duplicated "user.1".

-- dup_xattr.sh begin --
randbase64()
{
        dd if=/dev/urandom bs=1 count=$1 2>/dev/null | openssl enc -a -A
}

file=$1
touch $file
setfattr -h -n user.1 -v `randbase64 5000` $file
setfattr -h -n user.2 -v `randbase64 20000` $file
setfattr -h -n user.3 -v `randbase64 20000` $file
setfattr -h -n user.1 -v `randbase64 20000` $file
getfattr -m. -d $file
-- dup_xattr.sh end --

Also, when a filesystem is switch from xattr=sa to xattr=on, it will
never modify those in SA. This would cause strange behavior like, you
cannot delete an xattr, or setxattr would cause duplicate and the result
would not match when you getxattr.

For example, the following shell sequence.

-- shell begin --
$ sudo zfs set xattr=sa pp/fs0
$ touch zzz
$ setfattr -n user.test -v asdf zzz
$ sudo zfs set xattr=on pp/fs0
$ setfattr -x user.test zzz
setfattr: zzz: No such attribute
$ getfattr -d zzz
user.test="asdf"
$ setfattr -n user.test -v zxcv zzz
$ getfattr -d zzz
user.test="asdf"
user.test="asdf"
-- shell end --

We fix this behavior, by first finding where the xattr resides before
setxattr. Then, after we successfully updated the xattr in one location,
we will clear the other location. Note that, because update and clear
are not in single tx, we could still end up with duplicated xattr. But
by doing setxattr again, it can be fixed.

Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Closes openzfs#3472
Closes openzfs#4153
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants