Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35773c93 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull AFS updates from Al Viro:
 "Assorted AFS stuff - ended up in vfs.git since most of that consists
  of David's AFS-related followups to Christoph's procfs series"

* 'afs-proc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  afs: Optimise callback breaking by not repeating volume lookup
  afs: Display manually added cells in dynamic root mount
  afs: Enable IPv6 DNS lookups
  afs: Show all of a server's addresses in /proc/fs/afs/servers
  afs: Handle CONFIG_PROC_FS=n
  proc: Make inline name size calculation automatic
  afs: Implement network namespacing
  afs: Mark afs_net::ws_cell as __rcu and set using rcu functions
  afs: Fix a Sparse warning in xdr_decode_AFSFetchStatus()
  proc: Add a way to make network proc files writable
  afs: Rearrange fs/afs/proc.c to remove remaining predeclarations.
  afs: Rearrange fs/afs/proc.c to move the show routines up
  afs: Rearrange fs/afs/proc.c by moving fops and open functions down
  afs: Move /proc management functions to the end of the file
parents 29d6849d 47ea0f2e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@

afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o

kafs-objs := \
kafs-y := \
	$(afs-cache-y) \
	addr_list.o \
	callback.o \
@@ -21,7 +21,6 @@ kafs-objs := \
	main.o \
	misc.o \
	mntpt.o \
	proc.o \
	rotate.o \
	rxrpc.o \
	security.o \
@@ -34,4 +33,5 @@ kafs-objs := \
	write.o \
	xattr.o

kafs-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_AFS_FS)  := kafs.o
+1 −1
Original line number Diff line number Diff line
@@ -215,7 +215,7 @@ struct afs_addr_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry)
	_enter("%s", cell->name);

	ret = dns_query("afsdb", cell->name, cell->name_len,
			"ipv4", &vllist, _expiry);
			"", &vllist, _expiry);
	if (ret < 0)
		return ERR_PTR(ret);

+93 −17
Original line number Diff line number Diff line
@@ -20,6 +20,66 @@
#include <linux/sched.h>
#include "internal.h"

/*
 * Create volume and callback interests on a server.
 */
static struct afs_cb_interest *afs_create_interest(struct afs_server *server,
						   struct afs_vnode *vnode)
{
	struct afs_vol_interest *new_vi, *vi;
	struct afs_cb_interest *new;
	struct hlist_node **pp;

	new_vi = kzalloc(sizeof(struct afs_vol_interest), GFP_KERNEL);
	if (!new_vi)
		return NULL;

	new = kzalloc(sizeof(struct afs_cb_interest), GFP_KERNEL);
	if (!new) {
		kfree(new_vi);
		return NULL;
	}

	new_vi->usage = 1;
	new_vi->vid = vnode->volume->vid;
	INIT_HLIST_NODE(&new_vi->srv_link);
	INIT_HLIST_HEAD(&new_vi->cb_interests);

	refcount_set(&new->usage, 1);
	new->sb = vnode->vfs_inode.i_sb;
	new->vid = vnode->volume->vid;
	new->server = afs_get_server(server);
	INIT_HLIST_NODE(&new->cb_vlink);

	write_lock(&server->cb_break_lock);

	for (pp = &server->cb_volumes.first; *pp; pp = &(*pp)->next) {
		vi = hlist_entry(*pp, struct afs_vol_interest, srv_link);
		if (vi->vid < new_vi->vid)
			continue;
		if (vi->vid > new_vi->vid)
			break;
		vi->usage++;
		goto found_vi;
	}

	new_vi->srv_link.pprev = pp;
	new_vi->srv_link.next = *pp;
	if (*pp)
		(*pp)->pprev = &new_vi->srv_link.next;
	*pp = &new_vi->srv_link;
	vi = new_vi;
	new_vi = NULL;
found_vi:

	new->vol_interest = vi;
	hlist_add_head(&new->cb_vlink, &vi->cb_interests);

	write_unlock(&server->cb_break_lock);
	kfree(new_vi);
	return new;
}

/*
 * Set up an interest-in-callbacks record for a volume on a server and
 * register it with the server.
@@ -77,20 +137,10 @@ int afs_register_server_cb_interest(struct afs_vnode *vnode,
	}

	if (!cbi) {
		new = kzalloc(sizeof(struct afs_cb_interest), GFP_KERNEL);
		new = afs_create_interest(server, vnode);
		if (!new)
			return -ENOMEM;

		refcount_set(&new->usage, 1);
		new->sb = vnode->vfs_inode.i_sb;
		new->vid = vnode->volume->vid;
		new->server = afs_get_server(server);
		INIT_LIST_HEAD(&new->cb_link);

		write_lock(&server->cb_break_lock);
		list_add_tail(&new->cb_link, &server->cb_interests);
		write_unlock(&server->cb_break_lock);

		write_lock(&slist->lock);
		if (!entry->cb_interest) {
			entry->cb_interest = afs_get_cb_interest(new);
@@ -126,11 +176,22 @@ int afs_register_server_cb_interest(struct afs_vnode *vnode,
 */
void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi)
{
	struct afs_vol_interest *vi;

	if (cbi && refcount_dec_and_test(&cbi->usage)) {
		if (!list_empty(&cbi->cb_link)) {
		if (!hlist_unhashed(&cbi->cb_vlink)) {
			write_lock(&cbi->server->cb_break_lock);
			list_del_init(&cbi->cb_link);

			hlist_del_init(&cbi->cb_vlink);
			vi = cbi->vol_interest;
			cbi->vol_interest = NULL;
			if (--vi->usage == 0)
				hlist_del(&vi->srv_link);
			else
				vi = NULL;

			write_unlock(&cbi->server->cb_break_lock);
			kfree(vi);
			afs_put_server(net, cbi->server);
		}
		kfree(cbi);
@@ -182,20 +243,34 @@ void afs_break_callback(struct afs_vnode *vnode)
static void afs_break_one_callback(struct afs_server *server,
				   struct afs_fid *fid)
{
	struct afs_vol_interest *vi;
	struct afs_cb_interest *cbi;
	struct afs_iget_data data;
	struct afs_vnode *vnode;
	struct inode *inode;

	read_lock(&server->cb_break_lock);
	hlist_for_each_entry(vi, &server->cb_volumes, srv_link) {
		if (vi->vid < fid->vid)
			continue;
		if (vi->vid > fid->vid) {
			vi = NULL;
			break;
		}
		//atomic_inc(&vi->usage);
		break;
	}

	/* TODO: Find all matching volumes if we couldn't match the server and
	 * break them anyway.
	 */
	if (!vi)
		goto out;

	/* Step through all interested superblocks.  There may be more than one
	 * because of cell aliasing.
	 */
	list_for_each_entry(cbi, &server->cb_interests, cb_link) {
		if (cbi->vid != fid->vid)
			continue;

	hlist_for_each_entry(cbi, &vi->cb_interests, cb_vlink) {
		if (fid->vnode == 0 && fid->unique == 0) {
			/* The callback break applies to an entire volume. */
			struct afs_super_info *as = AFS_FS_S(cbi->sb);
@@ -217,6 +292,7 @@ static void afs_break_one_callback(struct afs_server *server,
		}
	}

out:
	read_unlock(&server->cb_break_lock);
}

+14 −10
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/dns_resolver.h>
#include <linux/sched.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <keys/rxrpc-type.h>
#include "internal.h"

@@ -341,8 +342,8 @@ int afs_cell_init(struct afs_net *net, const char *rootcell)

	/* install the new cell */
	write_seqlock(&net->cells_lock);
	old_root = net->ws_cell;
	net->ws_cell = new_root;
	old_root = rcu_access_pointer(net->ws_cell);
	rcu_assign_pointer(net->ws_cell, new_root);
	write_sequnlock(&net->cells_lock);

	afs_put_cell(net, old_root);
@@ -528,12 +529,14 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
					     NULL, 0,
					     cell, 0, true);
#endif
	ret = afs_proc_cell_setup(net, cell);
	ret = afs_proc_cell_setup(cell);
	if (ret < 0)
		return ret;
	spin_lock(&net->proc_cells_lock);

	mutex_lock(&net->proc_cells_lock);
	list_add_tail(&cell->proc_link, &net->proc_cells);
	spin_unlock(&net->proc_cells_lock);
	afs_dynroot_mkdir(net, cell);
	mutex_unlock(&net->proc_cells_lock);
	return 0;
}

@@ -544,11 +547,12 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
{
	_enter("%s", cell->name);

	afs_proc_cell_remove(net, cell);
	afs_proc_cell_remove(cell);

	spin_lock(&net->proc_cells_lock);
	mutex_lock(&net->proc_cells_lock);
	list_del_init(&cell->proc_link);
	spin_unlock(&net->proc_cells_lock);
	afs_dynroot_rmdir(net, cell);
	mutex_unlock(&net->proc_cells_lock);

#ifdef CONFIG_AFS_FSCACHE
	fscache_relinquish_cookie(cell->cache, NULL, false);
@@ -755,8 +759,8 @@ void afs_cell_purge(struct afs_net *net)
	_enter("");

	write_seqlock(&net->cells_lock);
	ws = net->ws_cell;
	net->ws_cell = NULL;
	ws = rcu_access_pointer(net->ws_cell);
	RCU_INIT_POINTER(net->ws_cell, NULL);
	write_sequnlock(&net->cells_lock);
	afs_put_cell(net, ws);

+1 −1
Original line number Diff line number Diff line
@@ -526,7 +526,7 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
	nifs = 0;
	ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
	if (ifs) {
		nifs = afs_get_ipv4_interfaces(ifs, 32, false);
		nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false);
		if (nifs < 0) {
			kfree(ifs);
			ifs = NULL;
Loading