AFS fixes
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEqG5UsNXhtOCrfGQP+7dXa6fLC2sFAl3xW+cACgkQ+7dXa6fL C2t+UQ/9ETwAYJ2XgfwatNhAHX0+Tf4XMlgEDybf5a+ERRLbkSQEqRjTImopk5m4 T7yKea0ctsVb1avdUVdayh2KuJhjmO627u3w48kd/uf2ut4IyOyaraatYKYOJ+XL upr8WxAMXUHgnwsb38avjH0dwq7+eDyX8FNLHiDY4Sk3mTAVHbafL6V0ujp0ms2o VmHLX6ihwECehUqrNEyy1pLX2nuFmd+MeLnoi/EWLa47/X0te21G8u8UdPWHGgHn cZp8kqWSEoaeChO7x6XOoJZCY6N/7o+hogsrU/N5YrB6FXPpFWGdwFpej3YcyFso QqffyXX5jVAyUg9I/v3WCrtDmTQ9xVG4kxhmBMVId6bBk3ZVpGaHuLE3ENLbr1w/ Z1k26BI41nJwrqV0C2bPoMalpDprP2WIuWsBIpYTqaICpc53KJ72c6mLhcDEt+oc YCSd9X0Bv5O7tZS9rLI8mt0JtCr9Uw+VfnK+uOuUTPv2YcqQwK1/xZ0/9hd2P8XS L5GKcEeuk3indgmefjwsz5YJcmzeCttaOQTlmaN/Hz3MbkK2CC+spMG4OZWzUXL4 axZmCIo/kKrv64bLyVZul6BjkhawyvfWzCs2NM6Ni63akW3Yb0S2WRdgJhvGILml 48YgqcG7R1y8LRPYiJzcuAPnbumuu6ZSxVuyZN0FU0qc4lt5mPM= =ldOp -----END PGP SIGNATURE----- Merge tag 'afs-fixes-20191211' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs Pull AFS fixes from David Howells: "Fixes for AFS plus one patch to make debugging easier: - Fix how addresses are matched to server records. This is currently incorrect which means cache invalidation callbacks from the server don't necessarily get delivered correctly. This causes stale data and metadata to be seen under some circumstances. - Make the dynamic root superblock R/W so that rpm/dnf can reapply the SELinux label to it when upgrading the Fedora filesystem-afs package. If the filesystem is R/O, this fails and the upgrade fails. It might be better in future to allow setxattr from an LSM to bypass the R/O protections, if only for pseudo-filesystems. - Fix the parsing of mountpoint strings. The mountpoint object has to have a terminal dot, whereas the source/device string passed to mount should not. This confuses type-forcing suffix detection leading to the wrong volume variant being mounted. - Make lookups in the dynamic root superblock for creation events (such as mkdir) fail with EOPNOTSUPP rather than something like EEXIST. The dynamic root only allows implicit creation by the ->lookup() method - and only if the target cell exists. - Fix the looking up of an AFS superblock to include the cell in the matching key - otherwise all volumes with the same ID number are treated as the same thing, irrespective of which cell they're in. - Show the volume name of each volume in the volume records displayed in /proc/net/afs/<cell>/volumes. This proved useful in debugging as it provides a way to map the volume IDs to names, where the names are what appear in /proc/mounts" * tag 'afs-fixes-20191211' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: afs: Show volume name in /proc/net/afs/<cell>/volumes afs: Fix missing cell comparison in afs_test_super() afs: Fix creation calls in the dynamic root to fail with EOPNOTSUPP afs: Fix mountpoint parsing afs: Fix SELinux setting security label on /afs afs: Fix afs_find_server lookups for ipv4 peers
This commit is contained in:
commit
ae4b064e2a
|
@ -136,6 +136,9 @@ static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentr
|
|||
|
||||
ASSERTCMP(d_inode(dentry), ==, NULL);
|
||||
|
||||
if (flags & LOOKUP_CREATE)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (dentry->d_name.len >= AFSNAMEMAX) {
|
||||
_leave(" = -ENAMETOOLONG");
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
|
|
@ -126,7 +126,7 @@ static int afs_mntpt_set_params(struct fs_context *fc, struct dentry *mntpt)
|
|||
if (src_as->cell)
|
||||
ctx->cell = afs_get_cell(src_as->cell);
|
||||
|
||||
if (size > PAGE_SIZE - 1)
|
||||
if (size < 2 || size > PAGE_SIZE - 1)
|
||||
return -EINVAL;
|
||||
|
||||
page = read_mapping_page(d_inode(mntpt)->i_mapping, 0, NULL);
|
||||
|
@ -140,7 +140,9 @@ static int afs_mntpt_set_params(struct fs_context *fc, struct dentry *mntpt)
|
|||
}
|
||||
|
||||
buf = kmap(page);
|
||||
ret = vfs_parse_fs_string(fc, "source", buf, size);
|
||||
ret = -EINVAL;
|
||||
if (buf[size - 1] == '.')
|
||||
ret = vfs_parse_fs_string(fc, "source", buf, size - 1);
|
||||
kunmap(page);
|
||||
put_page(page);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -213,13 +213,14 @@ static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)
|
|||
|
||||
/* Display header on line 1 */
|
||||
if (v == &cell->proc_volumes) {
|
||||
seq_puts(m, "USE VID TY\n");
|
||||
seq_puts(m, "USE VID TY NAME\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seq_printf(m, "%3d %08llx %s\n",
|
||||
seq_printf(m, "%3d %08llx %s %s\n",
|
||||
atomic_read(&vol->usage), vol->vid,
|
||||
afs_vol_types[vol->type]);
|
||||
afs_vol_types[vol->type],
|
||||
vol->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -32,18 +32,11 @@ static void afs_dec_servers_outstanding(struct afs_net *net)
|
|||
struct afs_server *afs_find_server(struct afs_net *net,
|
||||
const struct sockaddr_rxrpc *srx)
|
||||
{
|
||||
const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
|
||||
const struct afs_addr_list *alist;
|
||||
struct afs_server *server = NULL;
|
||||
unsigned int i;
|
||||
bool ipv6 = true;
|
||||
int seq = 0, diff;
|
||||
|
||||
if (srx->transport.sin6.sin6_addr.s6_addr32[0] == 0 ||
|
||||
srx->transport.sin6.sin6_addr.s6_addr32[1] == 0 ||
|
||||
srx->transport.sin6.sin6_addr.s6_addr32[2] == htonl(0xffff))
|
||||
ipv6 = false;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
do {
|
||||
|
@ -52,7 +45,8 @@ struct afs_server *afs_find_server(struct afs_net *net,
|
|||
server = NULL;
|
||||
read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
|
||||
|
||||
if (ipv6) {
|
||||
if (srx->transport.family == AF_INET6) {
|
||||
const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
|
||||
hlist_for_each_entry_rcu(server, &net->fs_addresses6, addr6_link) {
|
||||
alist = rcu_dereference(server->addresses);
|
||||
for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
|
||||
|
@ -68,15 +62,16 @@ struct afs_server *afs_find_server(struct afs_net *net,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
const struct sockaddr_in *a = &srx->transport.sin, *b;
|
||||
hlist_for_each_entry_rcu(server, &net->fs_addresses4, addr4_link) {
|
||||
alist = rcu_dereference(server->addresses);
|
||||
for (i = 0; i < alist->nr_ipv4; i++) {
|
||||
b = &alist->addrs[i].transport.sin6;
|
||||
diff = ((u16 __force)a->sin6_port -
|
||||
(u16 __force)b->sin6_port);
|
||||
b = &alist->addrs[i].transport.sin;
|
||||
diff = ((u16 __force)a->sin_port -
|
||||
(u16 __force)b->sin_port);
|
||||
if (diff == 0)
|
||||
diff = ((u32 __force)a->sin6_addr.s6_addr32[3] -
|
||||
(u32 __force)b->sin6_addr.s6_addr32[3]);
|
||||
diff = ((u32 __force)a->sin_addr.s_addr -
|
||||
(u32 __force)b->sin_addr.s_addr);
|
||||
if (diff == 0)
|
||||
goto found;
|
||||
}
|
||||
|
|
|
@ -404,6 +404,7 @@ static int afs_test_super(struct super_block *sb, struct fs_context *fc)
|
|||
return (as->net_ns == fc->net_ns &&
|
||||
as->volume &&
|
||||
as->volume->vid == ctx->volume->vid &&
|
||||
as->cell == ctx->cell &&
|
||||
!as->dyn_root);
|
||||
}
|
||||
|
||||
|
@ -448,7 +449,6 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)
|
|||
/* allocate the root inode and dentry */
|
||||
if (as->dyn_root) {
|
||||
inode = afs_iget_pseudo_dir(sb, true);
|
||||
sb->s_flags |= SB_RDONLY;
|
||||
} else {
|
||||
sprintf(sb->s_id, "%llu", as->volume->vid);
|
||||
afs_activate_volume(as->volume);
|
||||
|
|
Loading…
Reference in New Issue