Skip to content

Commit 35773c9

Browse files
committed
Merge branch 'afs-proc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
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
2 parents 29d6849 + 47ea0f2 commit 35773c9

22 files changed

+892
-645
lines changed

fs/afs/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

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

8-
kafs-objs := \
8+
kafs-y := \
99
$(afs-cache-y) \
1010
addr_list.o \
1111
callback.o \
@@ -21,7 +21,6 @@ kafs-objs := \
2121
main.o \
2222
misc.o \
2323
mntpt.o \
24-
proc.o \
2524
rotate.o \
2625
rxrpc.o \
2726
security.o \
@@ -34,4 +33,5 @@ kafs-objs := \
3433
write.o \
3534
xattr.o
3635

36+
kafs-$(CONFIG_PROC_FS) += proc.o
3737
obj-$(CONFIG_AFS_FS) := kafs.o

fs/afs/addr_list.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ struct afs_addr_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry)
215215
_enter("%s", cell->name);
216216

217217
ret = dns_query("afsdb", cell->name, cell->name_len,
218-
"ipv4", &vllist, _expiry);
218+
"", &vllist, _expiry);
219219
if (ret < 0)
220220
return ERR_PTR(ret);
221221

fs/afs/callback.c

Lines changed: 93 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,66 @@
2020
#include <linux/sched.h>
2121
#include "internal.h"
2222

23+
/*
24+
* Create volume and callback interests on a server.
25+
*/
26+
static struct afs_cb_interest *afs_create_interest(struct afs_server *server,
27+
struct afs_vnode *vnode)
28+
{
29+
struct afs_vol_interest *new_vi, *vi;
30+
struct afs_cb_interest *new;
31+
struct hlist_node **pp;
32+
33+
new_vi = kzalloc(sizeof(struct afs_vol_interest), GFP_KERNEL);
34+
if (!new_vi)
35+
return NULL;
36+
37+
new = kzalloc(sizeof(struct afs_cb_interest), GFP_KERNEL);
38+
if (!new) {
39+
kfree(new_vi);
40+
return NULL;
41+
}
42+
43+
new_vi->usage = 1;
44+
new_vi->vid = vnode->volume->vid;
45+
INIT_HLIST_NODE(&new_vi->srv_link);
46+
INIT_HLIST_HEAD(&new_vi->cb_interests);
47+
48+
refcount_set(&new->usage, 1);
49+
new->sb = vnode->vfs_inode.i_sb;
50+
new->vid = vnode->volume->vid;
51+
new->server = afs_get_server(server);
52+
INIT_HLIST_NODE(&new->cb_vlink);
53+
54+
write_lock(&server->cb_break_lock);
55+
56+
for (pp = &server->cb_volumes.first; *pp; pp = &(*pp)->next) {
57+
vi = hlist_entry(*pp, struct afs_vol_interest, srv_link);
58+
if (vi->vid < new_vi->vid)
59+
continue;
60+
if (vi->vid > new_vi->vid)
61+
break;
62+
vi->usage++;
63+
goto found_vi;
64+
}
65+
66+
new_vi->srv_link.pprev = pp;
67+
new_vi->srv_link.next = *pp;
68+
if (*pp)
69+
(*pp)->pprev = &new_vi->srv_link.next;
70+
*pp = &new_vi->srv_link;
71+
vi = new_vi;
72+
new_vi = NULL;
73+
found_vi:
74+
75+
new->vol_interest = vi;
76+
hlist_add_head(&new->cb_vlink, &vi->cb_interests);
77+
78+
write_unlock(&server->cb_break_lock);
79+
kfree(new_vi);
80+
return new;
81+
}
82+
2383
/*
2484
* Set up an interest-in-callbacks record for a volume on a server and
2585
* register it with the server.
@@ -77,20 +137,10 @@ int afs_register_server_cb_interest(struct afs_vnode *vnode,
77137
}
78138

79139
if (!cbi) {
80-
new = kzalloc(sizeof(struct afs_cb_interest), GFP_KERNEL);
140+
new = afs_create_interest(server, vnode);
81141
if (!new)
82142
return -ENOMEM;
83143

84-
refcount_set(&new->usage, 1);
85-
new->sb = vnode->vfs_inode.i_sb;
86-
new->vid = vnode->volume->vid;
87-
new->server = afs_get_server(server);
88-
INIT_LIST_HEAD(&new->cb_link);
89-
90-
write_lock(&server->cb_break_lock);
91-
list_add_tail(&new->cb_link, &server->cb_interests);
92-
write_unlock(&server->cb_break_lock);
93-
94144
write_lock(&slist->lock);
95145
if (!entry->cb_interest) {
96146
entry->cb_interest = afs_get_cb_interest(new);
@@ -126,11 +176,22 @@ int afs_register_server_cb_interest(struct afs_vnode *vnode,
126176
*/
127177
void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi)
128178
{
179+
struct afs_vol_interest *vi;
180+
129181
if (cbi && refcount_dec_and_test(&cbi->usage)) {
130-
if (!list_empty(&cbi->cb_link)) {
182+
if (!hlist_unhashed(&cbi->cb_vlink)) {
131183
write_lock(&cbi->server->cb_break_lock);
132-
list_del_init(&cbi->cb_link);
184+
185+
hlist_del_init(&cbi->cb_vlink);
186+
vi = cbi->vol_interest;
187+
cbi->vol_interest = NULL;
188+
if (--vi->usage == 0)
189+
hlist_del(&vi->srv_link);
190+
else
191+
vi = NULL;
192+
133193
write_unlock(&cbi->server->cb_break_lock);
194+
kfree(vi);
134195
afs_put_server(net, cbi->server);
135196
}
136197
kfree(cbi);
@@ -182,20 +243,34 @@ void afs_break_callback(struct afs_vnode *vnode)
182243
static void afs_break_one_callback(struct afs_server *server,
183244
struct afs_fid *fid)
184245
{
246+
struct afs_vol_interest *vi;
185247
struct afs_cb_interest *cbi;
186248
struct afs_iget_data data;
187249
struct afs_vnode *vnode;
188250
struct inode *inode;
189251

190252
read_lock(&server->cb_break_lock);
253+
hlist_for_each_entry(vi, &server->cb_volumes, srv_link) {
254+
if (vi->vid < fid->vid)
255+
continue;
256+
if (vi->vid > fid->vid) {
257+
vi = NULL;
258+
break;
259+
}
260+
//atomic_inc(&vi->usage);
261+
break;
262+
}
263+
264+
/* TODO: Find all matching volumes if we couldn't match the server and
265+
* break them anyway.
266+
*/
267+
if (!vi)
268+
goto out;
191269

192270
/* Step through all interested superblocks. There may be more than one
193271
* because of cell aliasing.
194272
*/
195-
list_for_each_entry(cbi, &server->cb_interests, cb_link) {
196-
if (cbi->vid != fid->vid)
197-
continue;
198-
273+
hlist_for_each_entry(cbi, &vi->cb_interests, cb_vlink) {
199274
if (fid->vnode == 0 && fid->unique == 0) {
200275
/* The callback break applies to an entire volume. */
201276
struct afs_super_info *as = AFS_FS_S(cbi->sb);
@@ -217,6 +292,7 @@ static void afs_break_one_callback(struct afs_server *server,
217292
}
218293
}
219294

295+
out:
220296
read_unlock(&server->cb_break_lock);
221297
}
222298

fs/afs/cell.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/dns_resolver.h>
1616
#include <linux/sched.h>
1717
#include <linux/inet.h>
18+
#include <linux/namei.h>
1819
#include <keys/rxrpc-type.h>
1920
#include "internal.h"
2021

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

342343
/* install the new cell */
343344
write_seqlock(&net->cells_lock);
344-
old_root = net->ws_cell;
345-
net->ws_cell = new_root;
345+
old_root = rcu_access_pointer(net->ws_cell);
346+
rcu_assign_pointer(net->ws_cell, new_root);
346347
write_sequnlock(&net->cells_lock);
347348

348349
afs_put_cell(net, old_root);
@@ -528,12 +529,14 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
528529
NULL, 0,
529530
cell, 0, true);
530531
#endif
531-
ret = afs_proc_cell_setup(net, cell);
532+
ret = afs_proc_cell_setup(cell);
532533
if (ret < 0)
533534
return ret;
534-
spin_lock(&net->proc_cells_lock);
535+
536+
mutex_lock(&net->proc_cells_lock);
535537
list_add_tail(&cell->proc_link, &net->proc_cells);
536-
spin_unlock(&net->proc_cells_lock);
538+
afs_dynroot_mkdir(net, cell);
539+
mutex_unlock(&net->proc_cells_lock);
537540
return 0;
538541
}
539542

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

547-
afs_proc_cell_remove(net, cell);
550+
afs_proc_cell_remove(cell);
548551

549-
spin_lock(&net->proc_cells_lock);
552+
mutex_lock(&net->proc_cells_lock);
550553
list_del_init(&cell->proc_link);
551-
spin_unlock(&net->proc_cells_lock);
554+
afs_dynroot_rmdir(net, cell);
555+
mutex_unlock(&net->proc_cells_lock);
552556

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

757761
write_seqlock(&net->cells_lock);
758-
ws = net->ws_cell;
759-
net->ws_cell = NULL;
762+
ws = rcu_access_pointer(net->ws_cell);
763+
RCU_INIT_POINTER(net->ws_cell, NULL);
760764
write_sequnlock(&net->cells_lock);
761765
afs_put_cell(net, ws);
762766

fs/afs/cmservice.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
526526
nifs = 0;
527527
ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
528528
if (ifs) {
529-
nifs = afs_get_ipv4_interfaces(ifs, 32, false);
529+
nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false);
530530
if (nifs < 0) {
531531
kfree(ifs);
532532
ifs = NULL;

0 commit comments

Comments
 (0)