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 -2
fs/afs/Makefile
··· 5 5 6 6 afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o 7 7 8 - kafs-objs := \ 8 + kafs-y := \ 9 9 $(afs-cache-y) \ 10 10 addr_list.o \ 11 11 callback.o \ ··· 21 21 main.o \ 22 22 misc.o \ 23 23 mntpt.o \ 24 - proc.o \ 25 24 rotate.o \ 26 25 rxrpc.o \ 27 26 security.o \ ··· 33 34 write.o \ 34 35 xattr.o 35 36 37 + kafs-$(CONFIG_PROC_FS) += proc.o 36 38 obj-$(CONFIG_AFS_FS) := kafs.o
+1 -1
fs/afs/addr_list.c
··· 215 215 _enter("%s", cell->name); 216 216 217 217 ret = dns_query("afsdb", cell->name, cell->name_len, 218 - "ipv4", &vllist, _expiry); 218 + "", &vllist, _expiry); 219 219 if (ret < 0) 220 220 return ERR_PTR(ret); 221 221
+93 -17
fs/afs/callback.c
··· 21 21 #include "internal.h" 22 22 23 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 + 83 + /* 24 84 * Set up an interest-in-callbacks record for a volume on a server and 25 85 * register it with the server. 26 86 * - Called with vnode->io_lock held. ··· 137 77 } 138 78 139 79 if (!cbi) { 140 - new = kzalloc(sizeof(struct afs_cb_interest), GFP_KERNEL); 80 + new = afs_create_interest(server, vnode); 141 81 if (!new) 142 82 return -ENOMEM; 143 - 144 - refcount_set(&new->usage, 1); 145 - new->sb = vnode->vfs_inode.i_sb; 146 - new->vid = vnode->volume->vid; 147 - new->server = afs_get_server(server); 148 - INIT_LIST_HEAD(&new->cb_link); 149 - 150 - write_lock(&server->cb_break_lock); 151 - list_add_tail(&new->cb_link, &server->cb_interests); 152 - write_unlock(&server->cb_break_lock); 153 83 154 84 write_lock(&slist->lock); 155 85 if (!entry->cb_interest) { ··· 176 126 */ 177 127 void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi) 178 128 { 129 + struct afs_vol_interest *vi; 130 + 179 131 if (cbi && refcount_dec_and_test(&cbi->usage)) { 180 - if (!list_empty(&cbi->cb_link)) { 132 + if (!hlist_unhashed(&cbi->cb_vlink)) { 181 133 write_lock(&cbi->server->cb_break_lock); 182 - list_del_init(&cbi->cb_link); 134 + 135 + hlist_del_init(&cbi->cb_vlink); 136 + vi = cbi->vol_interest; 137 + cbi->vol_interest = NULL; 138 + if (--vi->usage == 0) 139 + hlist_del(&vi->srv_link); 140 + else 141 + vi = NULL; 142 + 183 143 write_unlock(&cbi->server->cb_break_lock); 144 + kfree(vi); 184 145 afs_put_server(net, cbi->server); 185 146 } 186 147 kfree(cbi); ··· 243 182 static void afs_break_one_callback(struct afs_server *server, 244 183 struct afs_fid *fid) 245 184 { 185 + struct afs_vol_interest *vi; 246 186 struct afs_cb_interest *cbi; 247 187 struct afs_iget_data data; 248 188 struct afs_vnode *vnode; 249 189 struct inode *inode; 250 190 251 191 read_lock(&server->cb_break_lock); 192 + hlist_for_each_entry(vi, &server->cb_volumes, srv_link) { 193 + if (vi->vid < fid->vid) 194 + continue; 195 + if (vi->vid > fid->vid) { 196 + vi = NULL; 197 + break; 198 + } 199 + //atomic_inc(&vi->usage); 200 + break; 201 + } 202 + 203 + /* TODO: Find all matching volumes if we couldn't match the server and 204 + * break them anyway. 205 + */ 206 + if (!vi) 207 + goto out; 252 208 253 209 /* Step through all interested superblocks. There may be more than one 254 210 * because of cell aliasing. 255 211 */ 256 - list_for_each_entry(cbi, &server->cb_interests, cb_link) { 257 - if (cbi->vid != fid->vid) 258 - continue; 259 - 212 + hlist_for_each_entry(cbi, &vi->cb_interests, cb_vlink) { 260 213 if (fid->vnode == 0 && fid->unique == 0) { 261 214 /* The callback break applies to an entire volume. */ 262 215 struct afs_super_info *as = AFS_FS_S(cbi->sb); ··· 292 217 } 293 218 } 294 219 220 + out: 295 221 read_unlock(&server->cb_break_lock); 296 222 } 297 223
+14 -10
fs/afs/cell.c
··· 15 15 #include <linux/dns_resolver.h> 16 16 #include <linux/sched.h> 17 17 #include <linux/inet.h> 18 + #include <linux/namei.h> 18 19 #include <keys/rxrpc-type.h> 19 20 #include "internal.h" 20 21 ··· 342 341 343 342 /* install the new cell */ 344 343 write_seqlock(&net->cells_lock); 345 - old_root = net->ws_cell; 346 - net->ws_cell = new_root; 344 + old_root = rcu_access_pointer(net->ws_cell); 345 + rcu_assign_pointer(net->ws_cell, new_root); 347 346 write_sequnlock(&net->cells_lock); 348 347 349 348 afs_put_cell(net, old_root); ··· 529 528 NULL, 0, 530 529 cell, 0, true); 531 530 #endif 532 - ret = afs_proc_cell_setup(net, cell); 531 + ret = afs_proc_cell_setup(cell); 533 532 if (ret < 0) 534 533 return ret; 535 - spin_lock(&net->proc_cells_lock); 534 + 535 + mutex_lock(&net->proc_cells_lock); 536 536 list_add_tail(&cell->proc_link, &net->proc_cells); 537 - spin_unlock(&net->proc_cells_lock); 537 + afs_dynroot_mkdir(net, cell); 538 + mutex_unlock(&net->proc_cells_lock); 538 539 return 0; 539 540 } 540 541 ··· 547 544 { 548 545 _enter("%s", cell->name); 549 546 550 - afs_proc_cell_remove(net, cell); 547 + afs_proc_cell_remove(cell); 551 548 552 - spin_lock(&net->proc_cells_lock); 549 + mutex_lock(&net->proc_cells_lock); 553 550 list_del_init(&cell->proc_link); 554 - spin_unlock(&net->proc_cells_lock); 551 + afs_dynroot_rmdir(net, cell); 552 + mutex_unlock(&net->proc_cells_lock); 555 553 556 554 #ifdef CONFIG_AFS_FSCACHE 557 555 fscache_relinquish_cookie(cell->cache, NULL, false); ··· 759 755 _enter(""); 760 756 761 757 write_seqlock(&net->cells_lock); 762 - ws = net->ws_cell; 763 - net->ws_cell = NULL; 758 + ws = rcu_access_pointer(net->ws_cell); 759 + RCU_INIT_POINTER(net->ws_cell, NULL); 764 760 write_sequnlock(&net->cells_lock); 765 761 afs_put_cell(net, ws); 766 762
+1 -1
fs/afs/cmservice.c
··· 526 526 nifs = 0; 527 527 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL); 528 528 if (ifs) { 529 - nifs = afs_get_ipv4_interfaces(ifs, 32, false); 529 + nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false); 530 530 if (nifs < 0) { 531 531 kfree(ifs); 532 532 ifs = NULL;
+124 -2
fs/afs/dynroot.c
··· 1 - /* dir.c: AFS dynamic root handling 1 + /* AFS dynamic root handling 2 2 * 3 3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 4 * Written by David Howells (dhowells@redhat.com) ··· 46 46 return 0; 47 47 } 48 48 49 - ret = dns_query("afsdb", name, len, "ipv4", NULL, NULL); 49 + ret = dns_query("afsdb", name, len, "", NULL, NULL); 50 50 if (ret == -ENODATA) 51 51 ret = -EDESTADDRREQ; 52 52 return ret; ··· 207 207 .d_release = afs_d_release, 208 208 .d_automount = afs_d_automount, 209 209 }; 210 + 211 + /* 212 + * Create a manually added cell mount directory. 213 + * - The caller must hold net->proc_cells_lock 214 + */ 215 + int afs_dynroot_mkdir(struct afs_net *net, struct afs_cell *cell) 216 + { 217 + struct super_block *sb = net->dynroot_sb; 218 + struct dentry *root, *subdir; 219 + int ret; 220 + 221 + if (!sb || atomic_read(&sb->s_active) == 0) 222 + return 0; 223 + 224 + /* Let the ->lookup op do the creation */ 225 + root = sb->s_root; 226 + inode_lock(root->d_inode); 227 + subdir = lookup_one_len(cell->name, root, cell->name_len); 228 + if (IS_ERR(subdir)) { 229 + ret = PTR_ERR(subdir); 230 + goto unlock; 231 + } 232 + 233 + /* Note that we're retaining an extra ref on the dentry */ 234 + subdir->d_fsdata = (void *)1UL; 235 + ret = 0; 236 + unlock: 237 + inode_unlock(root->d_inode); 238 + return ret; 239 + } 240 + 241 + /* 242 + * Remove a manually added cell mount directory. 243 + * - The caller must hold net->proc_cells_lock 244 + */ 245 + void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell) 246 + { 247 + struct super_block *sb = net->dynroot_sb; 248 + struct dentry *root, *subdir; 249 + 250 + if (!sb || atomic_read(&sb->s_active) == 0) 251 + return; 252 + 253 + root = sb->s_root; 254 + inode_lock(root->d_inode); 255 + 256 + /* Don't want to trigger a lookup call, which will re-add the cell */ 257 + subdir = try_lookup_one_len(cell->name, root, cell->name_len); 258 + if (IS_ERR_OR_NULL(subdir)) { 259 + _debug("lookup %ld", PTR_ERR(subdir)); 260 + goto no_dentry; 261 + } 262 + 263 + _debug("rmdir %pd %u", subdir, d_count(subdir)); 264 + 265 + if (subdir->d_fsdata) { 266 + _debug("unpin %u", d_count(subdir)); 267 + subdir->d_fsdata = NULL; 268 + dput(subdir); 269 + } 270 + dput(subdir); 271 + no_dentry: 272 + inode_unlock(root->d_inode); 273 + _leave(""); 274 + } 275 + 276 + /* 277 + * Populate a newly created dynamic root with cell names. 278 + */ 279 + int afs_dynroot_populate(struct super_block *sb) 280 + { 281 + struct afs_cell *cell; 282 + struct afs_net *net = afs_sb2net(sb); 283 + int ret; 284 + 285 + if (mutex_lock_interruptible(&net->proc_cells_lock) < 0) 286 + return -ERESTARTSYS; 287 + 288 + net->dynroot_sb = sb; 289 + list_for_each_entry(cell, &net->proc_cells, proc_link) { 290 + ret = afs_dynroot_mkdir(net, cell); 291 + if (ret < 0) 292 + goto error; 293 + } 294 + 295 + ret = 0; 296 + out: 297 + mutex_unlock(&net->proc_cells_lock); 298 + return ret; 299 + 300 + error: 301 + net->dynroot_sb = NULL; 302 + goto out; 303 + } 304 + 305 + /* 306 + * When a dynamic root that's in the process of being destroyed, depopulate it 307 + * of pinned directories. 308 + */ 309 + void afs_dynroot_depopulate(struct super_block *sb) 310 + { 311 + struct afs_net *net = afs_sb2net(sb); 312 + struct dentry *root = sb->s_root, *subdir, *tmp; 313 + 314 + /* Prevent more subdirs from being created */ 315 + mutex_lock(&net->proc_cells_lock); 316 + if (net->dynroot_sb == sb) 317 + net->dynroot_sb = NULL; 318 + mutex_unlock(&net->proc_cells_lock); 319 + 320 + inode_lock(root->d_inode); 321 + 322 + /* Remove all the pins for dirs created for manually added cells */ 323 + list_for_each_entry_safe(subdir, tmp, &root->d_subdirs, d_child) { 324 + if (subdir->d_fsdata) { 325 + subdir->d_fsdata = NULL; 326 + dput(subdir); 327 + } 328 + } 329 + 330 + inode_unlock(root->d_inode); 331 + }
+56 -44
fs/afs/fsclient.c
··· 138 138 u64 data_version, size; 139 139 u32 type, abort_code; 140 140 u8 flags = 0; 141 - int ret; 142 - 143 - if (vnode) 144 - write_seqlock(&vnode->cb_lock); 145 141 146 142 abort_code = ntohl(xdr->abort_code); 147 143 ··· 150 154 * case. 151 155 */ 152 156 status->abort_code = abort_code; 153 - ret = 0; 154 - goto out; 157 + return 0; 155 158 } 156 159 157 160 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); ··· 159 164 160 165 if (abort_code != 0 && inline_error) { 161 166 status->abort_code = abort_code; 162 - ret = 0; 163 - goto out; 167 + return 0; 164 168 } 165 169 166 170 type = ntohl(xdr->type); ··· 229 235 flags); 230 236 } 231 237 232 - ret = 0; 233 - 234 - out: 235 - if (vnode) 236 - write_sequnlock(&vnode->cb_lock); 237 - return ret; 238 + return 0; 238 239 239 240 bad: 240 241 xdr_dump_bad(*_bp); 241 - ret = afs_protocol_error(call, -EBADMSG); 242 - goto out; 242 + return afs_protocol_error(call, -EBADMSG); 243 + } 244 + 245 + /* 246 + * Decode the file status. We need to lock the target vnode if we're going to 247 + * update its status so that stat() sees the attributes update atomically. 248 + */ 249 + static int afs_decode_status(struct afs_call *call, 250 + const __be32 **_bp, 251 + struct afs_file_status *status, 252 + struct afs_vnode *vnode, 253 + const afs_dataversion_t *expected_version, 254 + struct afs_read *read_req) 255 + { 256 + int ret; 257 + 258 + if (!vnode) 259 + return xdr_decode_AFSFetchStatus(call, _bp, status, vnode, 260 + expected_version, read_req); 261 + 262 + write_seqlock(&vnode->cb_lock); 263 + ret = xdr_decode_AFSFetchStatus(call, _bp, status, vnode, 264 + expected_version, read_req); 265 + write_sequnlock(&vnode->cb_lock); 266 + return ret; 243 267 } 244 268 245 269 /* ··· 399 387 400 388 /* unmarshall the reply once we've received all of it */ 401 389 bp = call->buffer; 402 - if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 403 - &call->expected_version, NULL) < 0) 390 + if (afs_decode_status(call, &bp, &vnode->status, vnode, 391 + &call->expected_version, NULL) < 0) 404 392 return afs_protocol_error(call, -EBADMSG); 405 393 xdr_decode_AFSCallBack(call, vnode, &bp); 406 394 if (call->reply[1]) ··· 580 568 return ret; 581 569 582 570 bp = call->buffer; 583 - if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 584 - &vnode->status.data_version, req) < 0) 571 + if (afs_decode_status(call, &bp, &vnode->status, vnode, 572 + &vnode->status.data_version, req) < 0) 585 573 return afs_protocol_error(call, -EBADMSG); 586 574 xdr_decode_AFSCallBack(call, vnode, &bp); 587 575 if (call->reply[1]) ··· 733 721 /* unmarshall the reply once we've received all of it */ 734 722 bp = call->buffer; 735 723 xdr_decode_AFSFid(&bp, call->reply[1]); 736 - if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 || 737 - xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 738 - &call->expected_version, NULL) < 0) 724 + if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 || 725 + afs_decode_status(call, &bp, &vnode->status, vnode, 726 + &call->expected_version, NULL) < 0) 739 727 return afs_protocol_error(call, -EBADMSG); 740 728 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]); 741 729 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ ··· 839 827 840 828 /* unmarshall the reply once we've received all of it */ 841 829 bp = call->buffer; 842 - if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 843 - &call->expected_version, NULL) < 0) 830 + if (afs_decode_status(call, &bp, &vnode->status, vnode, 831 + &call->expected_version, NULL) < 0) 844 832 return afs_protocol_error(call, -EBADMSG); 845 833 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 846 834 ··· 929 917 930 918 /* unmarshall the reply once we've received all of it */ 931 919 bp = call->buffer; 932 - if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 || 933 - xdr_decode_AFSFetchStatus(call, &bp, &dvnode->status, dvnode, 934 - &call->expected_version, NULL) < 0) 920 + if (afs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 || 921 + afs_decode_status(call, &bp, &dvnode->status, dvnode, 922 + &call->expected_version, NULL) < 0) 935 923 return afs_protocol_error(call, -EBADMSG); 936 924 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 937 925 ··· 1016 1004 /* unmarshall the reply once we've received all of it */ 1017 1005 bp = call->buffer; 1018 1006 xdr_decode_AFSFid(&bp, call->reply[1]); 1019 - if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) || 1020 - xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1021 - &call->expected_version, NULL) < 0) 1007 + if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) || 1008 + afs_decode_status(call, &bp, &vnode->status, vnode, 1009 + &call->expected_version, NULL) < 0) 1022 1010 return afs_protocol_error(call, -EBADMSG); 1023 1011 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1024 1012 ··· 1122 1110 1123 1111 /* unmarshall the reply once we've received all of it */ 1124 1112 bp = call->buffer; 1125 - if (xdr_decode_AFSFetchStatus(call, &bp, &orig_dvnode->status, orig_dvnode, 1126 - &call->expected_version, NULL) < 0) 1113 + if (afs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode, 1114 + &call->expected_version, NULL) < 0) 1127 1115 return afs_protocol_error(call, -EBADMSG); 1128 1116 if (new_dvnode != orig_dvnode && 1129 - xdr_decode_AFSFetchStatus(call, &bp, &new_dvnode->status, new_dvnode, 1130 - &call->expected_version_2, NULL) < 0) 1117 + afs_decode_status(call, &bp, &new_dvnode->status, new_dvnode, 1118 + &call->expected_version_2, NULL) < 0) 1131 1119 return afs_protocol_error(call, -EBADMSG); 1132 1120 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1133 1121 ··· 1231 1219 1232 1220 /* unmarshall the reply once we've received all of it */ 1233 1221 bp = call->buffer; 1234 - if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1235 - &call->expected_version, NULL) < 0) 1222 + if (afs_decode_status(call, &bp, &vnode->status, vnode, 1223 + &call->expected_version, NULL) < 0) 1236 1224 return afs_protocol_error(call, -EBADMSG); 1237 1225 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1238 1226 ··· 1407 1395 1408 1396 /* unmarshall the reply once we've received all of it */ 1409 1397 bp = call->buffer; 1410 - if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1411 - &call->expected_version, NULL) < 0) 1398 + if (afs_decode_status(call, &bp, &vnode->status, vnode, 1399 + &call->expected_version, NULL) < 0) 1412 1400 return afs_protocol_error(call, -EBADMSG); 1413 1401 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1414 1402 ··· 2109 2097 2110 2098 /* unmarshall the reply once we've received all of it */ 2111 2099 bp = call->buffer; 2112 - xdr_decode_AFSFetchStatus(call, &bp, status, vnode, 2113 - &call->expected_version, NULL); 2100 + afs_decode_status(call, &bp, status, vnode, 2101 + &call->expected_version, NULL); 2114 2102 callback[call->count].version = ntohl(bp[0]); 2115 2103 callback[call->count].expiry = ntohl(bp[1]); 2116 2104 callback[call->count].type = ntohl(bp[2]); ··· 2221 2209 2222 2210 bp = call->buffer; 2223 2211 statuses = call->reply[1]; 2224 - if (xdr_decode_AFSFetchStatus(call, &bp, &statuses[call->count], 2225 - call->count == 0 ? vnode : NULL, 2226 - NULL, NULL) < 0) 2212 + if (afs_decode_status(call, &bp, &statuses[call->count], 2213 + call->count == 0 ? vnode : NULL, 2214 + NULL, NULL) < 0) 2227 2215 return afs_protocol_error(call, -EBADMSG); 2228 2216 2229 2217 call->count++;
+54 -25
fs/afs/internal.h
··· 22 22 #include <linux/backing-dev.h> 23 23 #include <linux/uuid.h> 24 24 #include <net/net_namespace.h> 25 + #include <net/netns/generic.h> 26 + #include <net/sock.h> 25 27 #include <net/af_rxrpc.h> 26 28 27 29 #include "afs.h" ··· 42 40 afs_voltype_t type; /* type of volume requested */ 43 41 int volnamesz; /* size of volume name */ 44 42 const char *volname; /* name of volume to mount */ 45 - struct afs_net *net; /* Network namespace in effect */ 43 + struct net *net_ns; /* Network namespace in effect */ 44 + struct afs_net *net; /* the AFS net namespace stuff */ 46 45 struct afs_cell *cell; /* cell in which to find volume */ 47 46 struct afs_volume *volume; /* volume record */ 48 47 struct key *key; /* key to use for secure mounting */ ··· 192 189 * - there's one superblock per volume 193 190 */ 194 191 struct afs_super_info { 195 - struct afs_net *net; /* Network namespace */ 192 + struct net *net_ns; /* Network namespace */ 196 193 struct afs_cell *cell; /* The cell in which the volume resides */ 197 194 struct afs_volume *volume; /* volume record */ 198 195 bool dyn_root; /* True if dynamic root */ ··· 213 210 char *subs[AFS_NR_SYSNAME]; 214 211 refcount_t usage; 215 212 unsigned short nr; 216 - short error; 217 213 char blank[1]; 218 214 }; 219 215 ··· 220 218 * AFS network namespace record. 221 219 */ 222 220 struct afs_net { 221 + struct net *net; /* Backpointer to the owning net namespace */ 223 222 struct afs_uuid uuid; 224 223 bool live; /* F if this namespace is being removed */ 225 224 ··· 234 231 235 232 /* Cell database */ 236 233 struct rb_root cells; 237 - struct afs_cell *ws_cell; 234 + struct afs_cell __rcu *ws_cell; 238 235 struct work_struct cells_manager; 239 236 struct timer_list cells_timer; 240 237 atomic_t cells_outstanding; 241 238 seqlock_t cells_lock; 242 239 243 - spinlock_t proc_cells_lock; 240 + struct mutex proc_cells_lock; 244 241 struct list_head proc_cells; 245 242 246 243 /* Known servers. Theoretically each fileserver can only be in one ··· 264 261 struct mutex lock_manager_mutex; 265 262 266 263 /* Misc */ 264 + struct super_block *dynroot_sb; /* Dynamic root mount superblock */ 267 265 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */ 268 266 struct afs_sysnames *sysnames; 269 267 rwlock_t sysnames_lock; ··· 284 280 }; 285 281 286 282 extern const char afs_init_sysname[]; 287 - extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns 288 283 289 284 enum afs_cell_state { 290 285 AFS_CELL_UNSET, ··· 407 404 rwlock_t fs_lock; /* access lock */ 408 405 409 406 /* callback promise management */ 410 - struct list_head cb_interests; /* List of superblocks using this server */ 407 + struct hlist_head cb_volumes; /* List of volume interests on this server */ 411 408 unsigned cb_s_break; /* Break-everything counter. */ 412 409 rwlock_t cb_break_lock; /* Volume finding lock */ 410 + }; 411 + 412 + /* 413 + * Volume collation in the server's callback interest list. 414 + */ 415 + struct afs_vol_interest { 416 + struct hlist_node srv_link; /* Link in server->cb_volumes */ 417 + struct hlist_head cb_interests; /* List of callback interests on the server */ 418 + afs_volid_t vid; /* Volume ID to match */ 419 + unsigned int usage; 413 420 }; 414 421 415 422 /* 416 423 * Interest by a superblock on a server. 417 424 */ 418 425 struct afs_cb_interest { 419 - struct list_head cb_link; /* Link in server->cb_interests */ 426 + struct hlist_node cb_vlink; /* Link in vol_interest->cb_interests */ 427 + struct afs_vol_interest *vol_interest; 420 428 struct afs_server *server; /* Server on which this interest resides */ 421 429 struct super_block *sb; /* Superblock on which inodes reside */ 422 430 afs_volid_t vid; /* Volume ID to match */ ··· 734 720 extern const struct dentry_operations afs_dynroot_dentry_operations; 735 721 736 722 extern struct inode *afs_try_auto_mntpt(struct dentry *, struct inode *); 723 + extern int afs_dynroot_mkdir(struct afs_net *, struct afs_cell *); 724 + extern void afs_dynroot_rmdir(struct afs_net *, struct afs_cell *); 725 + extern int afs_dynroot_populate(struct super_block *); 726 + extern void afs_dynroot_depopulate(struct super_block *); 737 727 738 728 /* 739 729 * file.c ··· 824 806 * main.c 825 807 */ 826 808 extern struct workqueue_struct *afs_wq; 809 + extern int afs_net_id; 810 + 811 + static inline struct afs_net *afs_net(struct net *net) 812 + { 813 + return net_generic(net, afs_net_id); 814 + } 815 + 816 + static inline struct afs_net *afs_sb2net(struct super_block *sb) 817 + { 818 + return afs_net(AFS_FS_S(sb)->net_ns); 819 + } 827 820 828 821 static inline struct afs_net *afs_d2net(struct dentry *dentry) 829 822 { 830 - return &__afs_net; 823 + return afs_sb2net(dentry->d_sb); 831 824 } 832 825 833 826 static inline struct afs_net *afs_i2net(struct inode *inode) 834 827 { 835 - return &__afs_net; 828 + return afs_sb2net(inode->i_sb); 836 829 } 837 830 838 831 static inline struct afs_net *afs_v2net(struct afs_vnode *vnode) 839 832 { 840 - return &__afs_net; 833 + return afs_i2net(&vnode->vfs_inode); 841 834 } 842 835 843 836 static inline struct afs_net *afs_sock2net(struct sock *sk) 844 837 { 845 - return &__afs_net; 846 - } 847 - 848 - static inline struct afs_net *afs_get_net(struct afs_net *net) 849 - { 850 - return net; 851 - } 852 - 853 - static inline void afs_put_net(struct afs_net *net) 854 - { 838 + return net_generic(sock_net(sk), afs_net_id); 855 839 } 856 840 857 841 static inline void __afs_stat(atomic_t *s) ··· 881 861 /* 882 862 * netdevices.c 883 863 */ 884 - extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); 864 + extern int afs_get_ipv4_interfaces(struct afs_net *, struct afs_interface *, 865 + size_t, bool); 885 866 886 867 /* 887 868 * proc.c 888 869 */ 870 + #ifdef CONFIG_PROC_FS 889 871 extern int __net_init afs_proc_init(struct afs_net *); 890 872 extern void __net_exit afs_proc_cleanup(struct afs_net *); 891 - extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *); 892 - extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *); 873 + extern int afs_proc_cell_setup(struct afs_cell *); 874 + extern void afs_proc_cell_remove(struct afs_cell *); 893 875 extern void afs_put_sysnames(struct afs_sysnames *); 876 + #else 877 + static inline int afs_proc_init(struct afs_net *net) { return 0; } 878 + static inline void afs_proc_cleanup(struct afs_net *net) {} 879 + static inline int afs_proc_cell_setup(struct afs_cell *cell) { return 0; } 880 + static inline void afs_proc_cell_remove(struct afs_cell *cell) {} 881 + static inline void afs_put_sysnames(struct afs_sysnames *sysnames) {} 882 + #endif 894 883 895 884 /* 896 885 * rotate.c ··· 1031 1002 * super.c 1032 1003 */ 1033 1004 extern int __init afs_fs_init(void); 1034 - extern void __exit afs_fs_exit(void); 1005 + extern void afs_fs_exit(void); 1035 1006 1036 1007 /* 1037 1008 * vlclient.c
+28 -7
fs/afs/main.c
··· 15 15 #include <linux/completion.h> 16 16 #include <linux/sched.h> 17 17 #include <linux/random.h> 18 + #include <linux/proc_fs.h> 18 19 #define CREATE_TRACE_POINTS 19 20 #include "internal.h" 20 21 ··· 33 32 MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); 34 33 35 34 struct workqueue_struct *afs_wq; 36 - struct afs_net __afs_net; 35 + static struct proc_dir_entry *afs_proc_symlink; 37 36 38 37 #if defined(CONFIG_ALPHA) 39 38 const char afs_init_sysname[] = "alpha_linux26"; ··· 68 67 /* 69 68 * Initialise an AFS network namespace record. 70 69 */ 71 - static int __net_init afs_net_init(struct afs_net *net) 70 + static int __net_init afs_net_init(struct net *net_ns) 72 71 { 73 72 struct afs_sysnames *sysnames; 73 + struct afs_net *net = afs_net(net_ns); 74 74 int ret; 75 75 76 + net->net = net_ns; 76 77 net->live = true; 77 78 generate_random_uuid((unsigned char *)&net->uuid); 78 79 ··· 86 83 INIT_WORK(&net->cells_manager, afs_manage_cells); 87 84 timer_setup(&net->cells_timer, afs_cells_timer, 0); 88 85 89 - spin_lock_init(&net->proc_cells_lock); 86 + mutex_init(&net->proc_cells_lock); 90 87 INIT_LIST_HEAD(&net->proc_cells); 91 88 92 89 seqlock_init(&net->fs_lock); ··· 145 142 /* 146 143 * Clean up and destroy an AFS network namespace record. 147 144 */ 148 - static void __net_exit afs_net_exit(struct afs_net *net) 145 + static void __net_exit afs_net_exit(struct net *net_ns) 149 146 { 147 + struct afs_net *net = afs_net(net_ns); 148 + 150 149 net->live = false; 151 150 afs_cell_purge(net); 152 151 afs_purge_servers(net); ··· 156 151 afs_proc_cleanup(net); 157 152 afs_put_sysnames(net->sysnames); 158 153 } 154 + 155 + static struct pernet_operations afs_net_ops = { 156 + .init = afs_net_init, 157 + .exit = afs_net_exit, 158 + .id = &afs_net_id, 159 + .size = sizeof(struct afs_net), 160 + }; 159 161 160 162 /* 161 163 * initialise the AFS client FS module ··· 190 178 goto error_cache; 191 179 #endif 192 180 193 - ret = afs_net_init(&__afs_net); 181 + ret = register_pernet_subsys(&afs_net_ops); 194 182 if (ret < 0) 195 183 goto error_net; 196 184 ··· 199 187 if (ret < 0) 200 188 goto error_fs; 201 189 190 + afs_proc_symlink = proc_symlink("fs/afs", NULL, "../self/net/afs"); 191 + if (IS_ERR(afs_proc_symlink)) { 192 + ret = PTR_ERR(afs_proc_symlink); 193 + goto error_proc; 194 + } 195 + 202 196 return ret; 203 197 198 + error_proc: 199 + afs_fs_exit(); 204 200 error_fs: 205 - afs_net_exit(&__afs_net); 201 + unregister_pernet_subsys(&afs_net_ops); 206 202 error_net: 207 203 #ifdef CONFIG_AFS_FSCACHE 208 204 fscache_unregister_netfs(&afs_cache_netfs); ··· 239 219 { 240 220 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n"); 241 221 222 + proc_remove(afs_proc_symlink); 242 223 afs_fs_exit(); 243 - afs_net_exit(&__afs_net); 224 + unregister_pernet_subsys(&afs_net_ops); 244 225 #ifdef CONFIG_AFS_FSCACHE 245 226 fscache_unregister_netfs(&afs_cache_netfs); 246 227 #endif
+3 -3
fs/afs/netdevices.c
··· 17 17 * - maxbufs must be at least 1 18 18 * - returns the number of interface records in the buffer 19 19 */ 20 - int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, 21 - bool wantloopback) 20 + int afs_get_ipv4_interfaces(struct afs_net *net, struct afs_interface *bufs, 21 + size_t maxbufs, bool wantloopback) 22 22 { 23 23 struct net_device *dev; 24 24 struct in_device *idev; ··· 27 27 ASSERT(maxbufs > 0); 28 28 29 29 rtnl_lock(); 30 - for_each_netdev(&init_net, dev) { 30 + for_each_netdev(net->net, dev) { 31 31 if (dev->type == ARPHRD_LOOPBACK && !wantloopback) 32 32 continue; 33 33 idev = __in_dev_get_rtnl(dev);
+330 -527
fs/afs/proc.c
··· 17 17 #include <linux/uaccess.h> 18 18 #include "internal.h" 19 19 20 - static inline struct afs_net *afs_proc2net(struct file *f) 21 - { 22 - return &__afs_net; 23 - } 24 - 25 20 static inline struct afs_net *afs_seq2net(struct seq_file *m) 26 21 { 27 - return &__afs_net; // TODO: use seq_file_net(m) 22 + return afs_net(seq_file_net(m)); 28 23 } 29 24 30 - static int afs_proc_cells_open(struct inode *inode, struct file *file); 31 - static void *afs_proc_cells_start(struct seq_file *p, loff_t *pos); 32 - static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos); 33 - static void afs_proc_cells_stop(struct seq_file *p, void *v); 34 - static int afs_proc_cells_show(struct seq_file *m, void *v); 35 - static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, 36 - size_t size, loff_t *_pos); 37 - 38 - static const struct seq_operations afs_proc_cells_ops = { 39 - .start = afs_proc_cells_start, 40 - .next = afs_proc_cells_next, 41 - .stop = afs_proc_cells_stop, 42 - .show = afs_proc_cells_show, 43 - }; 44 - 45 - static const struct file_operations afs_proc_cells_fops = { 46 - .open = afs_proc_cells_open, 47 - .read = seq_read, 48 - .write = afs_proc_cells_write, 49 - .llseek = seq_lseek, 50 - .release = seq_release, 51 - }; 52 - 53 - static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, 54 - size_t size, loff_t *_pos); 55 - static ssize_t afs_proc_rootcell_write(struct file *file, 56 - const char __user *buf, 57 - size_t size, loff_t *_pos); 58 - 59 - static const struct file_operations afs_proc_rootcell_fops = { 60 - .read = afs_proc_rootcell_read, 61 - .write = afs_proc_rootcell_write, 62 - .llseek = no_llseek, 63 - }; 64 - 65 - static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos); 66 - static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, 67 - loff_t *pos); 68 - static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v); 69 - static int afs_proc_cell_volumes_show(struct seq_file *m, void *v); 70 - 71 - static const struct seq_operations afs_proc_cell_volumes_ops = { 72 - .start = afs_proc_cell_volumes_start, 73 - .next = afs_proc_cell_volumes_next, 74 - .stop = afs_proc_cell_volumes_stop, 75 - .show = afs_proc_cell_volumes_show, 76 - }; 77 - 78 - static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos); 79 - static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, 80 - loff_t *pos); 81 - static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v); 82 - static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v); 83 - 84 - static const struct seq_operations afs_proc_cell_vlservers_ops = { 85 - .start = afs_proc_cell_vlservers_start, 86 - .next = afs_proc_cell_vlservers_next, 87 - .stop = afs_proc_cell_vlservers_stop, 88 - .show = afs_proc_cell_vlservers_show, 89 - }; 90 - 91 - static void *afs_proc_servers_start(struct seq_file *p, loff_t *pos); 92 - static void *afs_proc_servers_next(struct seq_file *p, void *v, 93 - loff_t *pos); 94 - static void afs_proc_servers_stop(struct seq_file *p, void *v); 95 - static int afs_proc_servers_show(struct seq_file *m, void *v); 96 - 97 - static const struct seq_operations afs_proc_servers_ops = { 98 - .start = afs_proc_servers_start, 99 - .next = afs_proc_servers_next, 100 - .stop = afs_proc_servers_stop, 101 - .show = afs_proc_servers_show, 102 - }; 103 - 104 - static int afs_proc_sysname_open(struct inode *inode, struct file *file); 105 - static int afs_proc_sysname_release(struct inode *inode, struct file *file); 106 - static void *afs_proc_sysname_start(struct seq_file *p, loff_t *pos); 107 - static void *afs_proc_sysname_next(struct seq_file *p, void *v, 108 - loff_t *pos); 109 - static void afs_proc_sysname_stop(struct seq_file *p, void *v); 110 - static int afs_proc_sysname_show(struct seq_file *m, void *v); 111 - static ssize_t afs_proc_sysname_write(struct file *file, 112 - const char __user *buf, 113 - size_t size, loff_t *_pos); 114 - 115 - static const struct seq_operations afs_proc_sysname_ops = { 116 - .start = afs_proc_sysname_start, 117 - .next = afs_proc_sysname_next, 118 - .stop = afs_proc_sysname_stop, 119 - .show = afs_proc_sysname_show, 120 - }; 121 - 122 - static const struct file_operations afs_proc_sysname_fops = { 123 - .open = afs_proc_sysname_open, 124 - .read = seq_read, 125 - .llseek = seq_lseek, 126 - .release = afs_proc_sysname_release, 127 - .write = afs_proc_sysname_write, 128 - }; 129 - 130 - static int afs_proc_stats_show(struct seq_file *m, void *v); 131 - 132 - /* 133 - * initialise the /proc/fs/afs/ directory 134 - */ 135 - int afs_proc_init(struct afs_net *net) 25 + static inline struct afs_net *afs_seq2net_single(struct seq_file *m) 136 26 { 137 - _enter(""); 138 - 139 - net->proc_afs = proc_mkdir("fs/afs", NULL); 140 - if (!net->proc_afs) 141 - goto error_dir; 142 - 143 - if (!proc_create("cells", 0644, net->proc_afs, &afs_proc_cells_fops) || 144 - !proc_create("rootcell", 0644, net->proc_afs, &afs_proc_rootcell_fops) || 145 - !proc_create_seq("servers", 0644, net->proc_afs, &afs_proc_servers_ops) || 146 - !proc_create_single("stats", 0644, net->proc_afs, afs_proc_stats_show) || 147 - !proc_create("sysname", 0644, net->proc_afs, &afs_proc_sysname_fops)) 148 - goto error_tree; 149 - 150 - _leave(" = 0"); 151 - return 0; 152 - 153 - error_tree: 154 - proc_remove(net->proc_afs); 155 - error_dir: 156 - _leave(" = -ENOMEM"); 157 - return -ENOMEM; 27 + return afs_net(seq_file_single_net(m)); 158 28 } 159 29 160 30 /* 161 - * clean up the /proc/fs/afs/ directory 162 - */ 163 - void afs_proc_cleanup(struct afs_net *net) 164 - { 165 - proc_remove(net->proc_afs); 166 - net->proc_afs = NULL; 167 - } 168 - 169 - /* 170 - * open "/proc/fs/afs/cells" which provides a summary of extant cells 171 - */ 172 - static int afs_proc_cells_open(struct inode *inode, struct file *file) 173 - { 174 - return seq_open(file, &afs_proc_cells_ops); 175 - } 176 - 177 - /* 178 - * set up the iterator to start reading from the cells list and return the 179 - * first item 180 - */ 181 - static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) 182 - __acquires(rcu) 183 - { 184 - struct afs_net *net = afs_seq2net(m); 185 - 186 - rcu_read_lock(); 187 - return seq_list_start_head(&net->proc_cells, *_pos); 188 - } 189 - 190 - /* 191 - * move to next cell in cells list 192 - */ 193 - static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos) 194 - { 195 - struct afs_net *net = afs_seq2net(m); 196 - 197 - return seq_list_next(v, &net->proc_cells, pos); 198 - } 199 - 200 - /* 201 - * clean up after reading from the cells list 202 - */ 203 - static void afs_proc_cells_stop(struct seq_file *m, void *v) 204 - __releases(rcu) 205 - { 206 - rcu_read_unlock(); 207 - } 208 - 209 - /* 210 - * display a header line followed by a load of cell lines 31 + * Display the list of cells known to the namespace. 211 32 */ 212 33 static int afs_proc_cells_show(struct seq_file *m, void *v) 213 34 { ··· 46 225 return 0; 47 226 } 48 227 228 + static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) 229 + __acquires(rcu) 230 + { 231 + rcu_read_lock(); 232 + return seq_list_start_head(&afs_seq2net(m)->proc_cells, *_pos); 233 + } 234 + 235 + static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos) 236 + { 237 + return seq_list_next(v, &afs_seq2net(m)->proc_cells, pos); 238 + } 239 + 240 + static void afs_proc_cells_stop(struct seq_file *m, void *v) 241 + __releases(rcu) 242 + { 243 + rcu_read_unlock(); 244 + } 245 + 246 + static const struct seq_operations afs_proc_cells_ops = { 247 + .start = afs_proc_cells_start, 248 + .next = afs_proc_cells_next, 249 + .stop = afs_proc_cells_stop, 250 + .show = afs_proc_cells_show, 251 + }; 252 + 49 253 /* 50 254 * handle writes to /proc/fs/afs/cells 51 255 * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]" 52 256 */ 53 - static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, 54 - size_t size, loff_t *_pos) 257 + static int afs_proc_cells_write(struct file *file, char *buf, size_t size) 55 258 { 56 - struct afs_net *net = afs_proc2net(file); 57 - char *kbuf, *name, *args; 259 + struct seq_file *m = file->private_data; 260 + struct afs_net *net = afs_seq2net(m); 261 + char *name, *args; 58 262 int ret; 59 263 60 - /* start by dragging the command into memory */ 61 - if (size <= 1 || size >= PAGE_SIZE) 62 - return -EINVAL; 63 - 64 - kbuf = memdup_user_nul(buf, size); 65 - if (IS_ERR(kbuf)) 66 - return PTR_ERR(kbuf); 67 - 68 264 /* trim to first NL */ 69 - name = memchr(kbuf, '\n', size); 265 + name = memchr(buf, '\n', size); 70 266 if (name) 71 267 *name = 0; 72 268 73 269 /* split into command, name and argslist */ 74 - name = strchr(kbuf, ' '); 270 + name = strchr(buf, ' '); 75 271 if (!name) 76 272 goto inval; 77 273 do { ··· 107 269 goto inval; 108 270 109 271 /* determine command to perform */ 110 - _debug("cmd=%s name=%s args=%s", kbuf, name, args); 272 + _debug("cmd=%s name=%s args=%s", buf, name, args); 111 273 112 - if (strcmp(kbuf, "add") == 0) { 274 + if (strcmp(buf, "add") == 0) { 113 275 struct afs_cell *cell; 114 276 115 277 cell = afs_lookup_cell(net, name, strlen(name), args, true); ··· 125 287 goto inval; 126 288 } 127 289 128 - ret = size; 290 + ret = 0; 129 291 130 292 done: 131 - kfree(kbuf); 132 293 _leave(" = %d", ret); 133 294 return ret; 134 295 ··· 137 300 goto done; 138 301 } 139 302 140 - static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, 141 - size_t size, loff_t *_pos) 303 + /* 304 + * Display the name of the current workstation cell. 305 + */ 306 + static int afs_proc_rootcell_show(struct seq_file *m, void *v) 142 307 { 143 308 struct afs_cell *cell; 144 - struct afs_net *net = afs_proc2net(file); 145 - unsigned int seq = 0; 146 - char name[AFS_MAXCELLNAME + 1]; 147 - int len; 309 + struct afs_net *net; 148 310 149 - if (*_pos > 0) 150 - return 0; 151 - if (!net->ws_cell) 152 - return 0; 153 - 154 - rcu_read_lock(); 155 - do { 156 - read_seqbegin_or_lock(&net->cells_lock, &seq); 157 - len = 0; 158 - cell = rcu_dereference_raw(net->ws_cell); 159 - if (cell) { 160 - len = cell->name_len; 161 - memcpy(name, cell->name, len); 162 - } 163 - } while (need_seqretry(&net->cells_lock, seq)); 164 - done_seqretry(&net->cells_lock, seq); 165 - rcu_read_unlock(); 166 - 167 - if (!len) 168 - return 0; 169 - 170 - name[len++] = '\n'; 171 - if (len > size) 172 - len = size; 173 - if (copy_to_user(buf, name, len) != 0) 174 - return -EFAULT; 175 - *_pos = 1; 176 - return len; 311 + net = afs_seq2net_single(m); 312 + if (rcu_access_pointer(net->ws_cell)) { 313 + rcu_read_lock(); 314 + cell = rcu_dereference(net->ws_cell); 315 + if (cell) 316 + seq_printf(m, "%s\n", cell->name); 317 + rcu_read_unlock(); 318 + } 319 + return 0; 177 320 } 178 321 179 322 /* 180 - * handle writes to /proc/fs/afs/rootcell 181 - * - to initialize rootcell: echo "cell.name:192.168.231.14" 323 + * Set the current workstation cell and optionally supply its list of volume 324 + * location servers. 325 + * 326 + * echo "cell.name:192.168.231.14" >/proc/fs/afs/rootcell 182 327 */ 183 - static ssize_t afs_proc_rootcell_write(struct file *file, 184 - const char __user *buf, 185 - size_t size, loff_t *_pos) 328 + static int afs_proc_rootcell_write(struct file *file, char *buf, size_t size) 186 329 { 187 - struct afs_net *net = afs_proc2net(file); 188 - char *kbuf, *s; 330 + struct seq_file *m = file->private_data; 331 + struct afs_net *net = afs_seq2net_single(m); 332 + char *s; 189 333 int ret; 190 334 191 - /* start by dragging the command into memory */ 192 - if (size <= 1 || size >= PAGE_SIZE) 193 - return -EINVAL; 194 - 195 - kbuf = memdup_user_nul(buf, size); 196 - if (IS_ERR(kbuf)) 197 - return PTR_ERR(kbuf); 198 - 199 335 ret = -EINVAL; 200 - if (kbuf[0] == '.') 336 + if (buf[0] == '.') 201 337 goto out; 202 - if (memchr(kbuf, '/', size)) 338 + if (memchr(buf, '/', size)) 203 339 goto out; 204 340 205 341 /* trim to first NL */ 206 - s = memchr(kbuf, '\n', size); 342 + s = memchr(buf, '\n', size); 207 343 if (s) 208 344 *s = 0; 209 345 210 346 /* determine command to perform */ 211 - _debug("rootcell=%s", kbuf); 347 + _debug("rootcell=%s", buf); 212 348 213 - ret = afs_cell_init(net, kbuf); 214 - if (ret >= 0) 215 - ret = size; /* consume everything, always */ 349 + ret = afs_cell_init(net, buf); 216 350 217 351 out: 218 - kfree(kbuf); 219 352 _leave(" = %d", ret); 220 353 return ret; 221 - } 222 - 223 - /* 224 - * initialise /proc/fs/afs/<cell>/ 225 - */ 226 - int afs_proc_cell_setup(struct afs_net *net, struct afs_cell *cell) 227 - { 228 - struct proc_dir_entry *dir; 229 - 230 - _enter("%p{%s},%p", cell, cell->name, net->proc_afs); 231 - 232 - dir = proc_mkdir(cell->name, net->proc_afs); 233 - if (!dir) 234 - goto error_dir; 235 - 236 - if (!proc_create_seq_data("vlservers", 0, dir, 237 - &afs_proc_cell_vlservers_ops, cell)) 238 - goto error_tree; 239 - if (!proc_create_seq_data("volumes", 0, dir, &afs_proc_cell_volumes_ops, 240 - cell)) 241 - goto error_tree; 242 - 243 - _leave(" = 0"); 244 - return 0; 245 - 246 - error_tree: 247 - remove_proc_subtree(cell->name, net->proc_afs); 248 - error_dir: 249 - _leave(" = -ENOMEM"); 250 - return -ENOMEM; 251 - } 252 - 253 - /* 254 - * remove /proc/fs/afs/<cell>/ 255 - */ 256 - void afs_proc_cell_remove(struct afs_net *net, struct afs_cell *cell) 257 - { 258 - _enter(""); 259 - 260 - remove_proc_subtree(cell->name, net->proc_afs); 261 - 262 - _leave(""); 263 - } 264 - 265 - /* 266 - * set up the iterator to start reading from the cells list and return the 267 - * first item 268 - */ 269 - static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) 270 - __acquires(cell->proc_lock) 271 - { 272 - struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 273 - 274 - _enter("cell=%p pos=%Ld", cell, *_pos); 275 - 276 - read_lock(&cell->proc_lock); 277 - return seq_list_start_head(&cell->proc_volumes, *_pos); 278 - } 279 - 280 - /* 281 - * move to next cell in cells list 282 - */ 283 - static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, 284 - loff_t *_pos) 285 - { 286 - struct afs_cell *cell = PDE_DATA(file_inode(p->file)); 287 - 288 - _enter("cell=%p pos=%Ld", cell, *_pos); 289 - return seq_list_next(v, &cell->proc_volumes, _pos); 290 - } 291 - 292 - /* 293 - * clean up after reading from the cells list 294 - */ 295 - static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v) 296 - __releases(cell->proc_lock) 297 - { 298 - struct afs_cell *cell = PDE_DATA(file_inode(p->file)); 299 - 300 - read_unlock(&cell->proc_lock); 301 354 } 302 355 303 356 static const char afs_vol_types[3][3] = { ··· 197 470 }; 198 471 199 472 /* 200 - * display a header line followed by a load of volume lines 473 + * Display the list of volumes known to a cell. 201 474 */ 202 475 static int afs_proc_cell_volumes_show(struct seq_file *m, void *v) 203 476 { ··· 217 490 return 0; 218 491 } 219 492 493 + static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) 494 + __acquires(cell->proc_lock) 495 + { 496 + struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 497 + 498 + read_lock(&cell->proc_lock); 499 + return seq_list_start_head(&cell->proc_volumes, *_pos); 500 + } 501 + 502 + static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v, 503 + loff_t *_pos) 504 + { 505 + struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 506 + 507 + return seq_list_next(v, &cell->proc_volumes, _pos); 508 + } 509 + 510 + static void afs_proc_cell_volumes_stop(struct seq_file *m, void *v) 511 + __releases(cell->proc_lock) 512 + { 513 + struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 514 + 515 + read_unlock(&cell->proc_lock); 516 + } 517 + 518 + static const struct seq_operations afs_proc_cell_volumes_ops = { 519 + .start = afs_proc_cell_volumes_start, 520 + .next = afs_proc_cell_volumes_next, 521 + .stop = afs_proc_cell_volumes_stop, 522 + .show = afs_proc_cell_volumes_show, 523 + }; 524 + 220 525 /* 221 - * set up the iterator to start reading from the cells list and return the 222 - * first item 526 + * Display the list of Volume Location servers we're using for a cell. 223 527 */ 528 + static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) 529 + { 530 + struct sockaddr_rxrpc *addr = v; 531 + 532 + /* display header on line 1 */ 533 + if (v == (void *)1) { 534 + seq_puts(m, "ADDRESS\n"); 535 + return 0; 536 + } 537 + 538 + /* display one cell per line on subsequent lines */ 539 + seq_printf(m, "%pISp\n", &addr->transport); 540 + return 0; 541 + } 542 + 224 543 static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) 225 544 __acquires(rcu) 226 545 { ··· 289 516 return alist->addrs + pos; 290 517 } 291 518 292 - /* 293 - * move to next cell in cells list 294 - */ 295 - static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, 519 + static void *afs_proc_cell_vlservers_next(struct seq_file *m, void *v, 296 520 loff_t *_pos) 297 521 { 298 522 struct afs_addr_list *alist; 299 - struct afs_cell *cell = PDE_DATA(file_inode(p->file)); 523 + struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 300 524 loff_t pos; 301 525 302 526 alist = rcu_dereference(cell->vl_addrs); ··· 306 536 return alist->addrs + pos; 307 537 } 308 538 309 - /* 310 - * clean up after reading from the cells list 311 - */ 312 - static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v) 539 + static void afs_proc_cell_vlservers_stop(struct seq_file *m, void *v) 313 540 __releases(rcu) 314 541 { 315 542 rcu_read_unlock(); 316 543 } 317 544 318 - /* 319 - * display a header line followed by a load of volume lines 320 - */ 321 - static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) 322 - { 323 - struct sockaddr_rxrpc *addr = v; 324 - 325 - /* display header on line 1 */ 326 - if (v == (void *)1) { 327 - seq_puts(m, "ADDRESS\n"); 328 - return 0; 329 - } 330 - 331 - /* display one cell per line on subsequent lines */ 332 - seq_printf(m, "%pISp\n", &addr->transport); 333 - return 0; 334 - } 545 + static const struct seq_operations afs_proc_cell_vlservers_ops = { 546 + .start = afs_proc_cell_vlservers_start, 547 + .next = afs_proc_cell_vlservers_next, 548 + .stop = afs_proc_cell_vlservers_stop, 549 + .show = afs_proc_cell_vlservers_show, 550 + }; 335 551 336 552 /* 337 - * Set up the iterator to start reading from the server list and return the 338 - * first item. 339 - */ 340 - static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos) 341 - __acquires(rcu) 342 - { 343 - struct afs_net *net = afs_seq2net(m); 344 - 345 - rcu_read_lock(); 346 - return seq_hlist_start_head_rcu(&net->fs_proc, *_pos); 347 - } 348 - 349 - /* 350 - * move to next cell in cells list 351 - */ 352 - static void *afs_proc_servers_next(struct seq_file *m, void *v, loff_t *_pos) 353 - { 354 - struct afs_net *net = afs_seq2net(m); 355 - 356 - return seq_hlist_next_rcu(v, &net->fs_proc, _pos); 357 - } 358 - 359 - /* 360 - * clean up after reading from the cells list 361 - */ 362 - static void afs_proc_servers_stop(struct seq_file *p, void *v) 363 - __releases(rcu) 364 - { 365 - rcu_read_unlock(); 366 - } 367 - 368 - /* 369 - * display a header line followed by a load of volume lines 553 + * Display the list of fileservers we're using within a namespace. 370 554 */ 371 555 static int afs_proc_servers_show(struct seq_file *m, void *v) 372 556 { 373 557 struct afs_server *server; 374 558 struct afs_addr_list *alist; 559 + int i; 375 560 376 561 if (v == SEQ_START_TOKEN) { 377 562 seq_puts(m, "UUID USE ADDR\n"); ··· 335 610 336 611 server = list_entry(v, struct afs_server, proc_link); 337 612 alist = rcu_dereference(server->addresses); 338 - seq_printf(m, "%pU %3d %pISp\n", 613 + seq_printf(m, "%pU %3d %pISpc%s\n", 339 614 &server->uuid, 340 615 atomic_read(&server->usage), 341 - &alist->addrs[alist->index].transport); 616 + &alist->addrs[0].transport, 617 + alist->index == 0 ? "*" : ""); 618 + for (i = 1; i < alist->nr_addrs; i++) 619 + seq_printf(m, " %pISpc%s\n", 620 + &alist->addrs[i].transport, 621 + alist->index == i ? "*" : ""); 342 622 return 0; 343 623 } 344 624 345 - void afs_put_sysnames(struct afs_sysnames *sysnames) 625 + static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos) 626 + __acquires(rcu) 346 627 { 347 - int i; 348 - 349 - if (sysnames && refcount_dec_and_test(&sysnames->usage)) { 350 - for (i = 0; i < sysnames->nr; i++) 351 - if (sysnames->subs[i] != afs_init_sysname && 352 - sysnames->subs[i] != sysnames->blank) 353 - kfree(sysnames->subs[i]); 354 - } 628 + rcu_read_lock(); 629 + return seq_hlist_start_head_rcu(&afs_seq2net(m)->fs_proc, *_pos); 355 630 } 356 631 357 - /* 358 - * Handle opening of /proc/fs/afs/sysname. If it is opened for writing, we 359 - * assume the caller wants to change the substitution list and we allocate a 360 - * buffer to hold the list. 361 - */ 362 - static int afs_proc_sysname_open(struct inode *inode, struct file *file) 632 + static void *afs_proc_servers_next(struct seq_file *m, void *v, loff_t *_pos) 363 633 { 364 - struct afs_sysnames *sysnames; 365 - struct seq_file *m; 366 - int ret; 634 + return seq_hlist_next_rcu(v, &afs_seq2net(m)->fs_proc, _pos); 635 + } 367 636 368 - ret = seq_open(file, &afs_proc_sysname_ops); 369 - if (ret < 0) 370 - return ret; 637 + static void afs_proc_servers_stop(struct seq_file *m, void *v) 638 + __releases(rcu) 639 + { 640 + rcu_read_unlock(); 641 + } 371 642 372 - if (file->f_mode & FMODE_WRITE) { 373 - sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); 374 - if (!sysnames) { 375 - seq_release(inode, file); 376 - return -ENOMEM; 377 - } 643 + static const struct seq_operations afs_proc_servers_ops = { 644 + .start = afs_proc_servers_start, 645 + .next = afs_proc_servers_next, 646 + .stop = afs_proc_servers_stop, 647 + .show = afs_proc_servers_show, 648 + }; 378 649 379 - refcount_set(&sysnames->usage, 1); 380 - m = file->private_data; 381 - m->private = sysnames; 382 - } 650 + /* 651 + * Display the list of strings that may be substituted for the @sys pathname 652 + * macro. 653 + */ 654 + static int afs_proc_sysname_show(struct seq_file *m, void *v) 655 + { 656 + struct afs_net *net = afs_seq2net(m); 657 + struct afs_sysnames *sysnames = net->sysnames; 658 + unsigned int i = (unsigned long)v - 1; 383 659 660 + if (i < sysnames->nr) 661 + seq_printf(m, "%s\n", sysnames->subs[i]); 384 662 return 0; 385 663 } 386 664 387 - /* 388 - * Handle writes to /proc/fs/afs/sysname to set the @sys substitution. 389 - */ 390 - static ssize_t afs_proc_sysname_write(struct file *file, 391 - const char __user *buf, 392 - size_t size, loff_t *_pos) 665 + static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos) 666 + __acquires(&net->sysnames_lock) 393 667 { 394 - struct afs_sysnames *sysnames; 668 + struct afs_net *net = afs_seq2net(m); 669 + struct afs_sysnames *names; 670 + 671 + read_lock(&net->sysnames_lock); 672 + 673 + names = net->sysnames; 674 + if (*pos >= names->nr) 675 + return NULL; 676 + return (void *)(unsigned long)(*pos + 1); 677 + } 678 + 679 + static void *afs_proc_sysname_next(struct seq_file *m, void *v, loff_t *pos) 680 + { 681 + struct afs_net *net = afs_seq2net(m); 682 + struct afs_sysnames *names = net->sysnames; 683 + 684 + *pos += 1; 685 + if (*pos >= names->nr) 686 + return NULL; 687 + return (void *)(unsigned long)(*pos + 1); 688 + } 689 + 690 + static void afs_proc_sysname_stop(struct seq_file *m, void *v) 691 + __releases(&net->sysnames_lock) 692 + { 693 + struct afs_net *net = afs_seq2net(m); 694 + 695 + read_unlock(&net->sysnames_lock); 696 + } 697 + 698 + static const struct seq_operations afs_proc_sysname_ops = { 699 + .start = afs_proc_sysname_start, 700 + .next = afs_proc_sysname_next, 701 + .stop = afs_proc_sysname_stop, 702 + .show = afs_proc_sysname_show, 703 + }; 704 + 705 + /* 706 + * Allow the @sys substitution to be configured. 707 + */ 708 + static int afs_proc_sysname_write(struct file *file, char *buf, size_t size) 709 + { 710 + struct afs_sysnames *sysnames, *kill; 395 711 struct seq_file *m = file->private_data; 396 - char *kbuf = NULL, *s, *p, *sub; 712 + struct afs_net *net = afs_seq2net(m); 713 + char *s, *p, *sub; 397 714 int ret, len; 398 715 399 - sysnames = m->private; 716 + sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); 400 717 if (!sysnames) 401 - return -EINVAL; 402 - if (sysnames->error) 403 - return sysnames->error; 718 + return -ENOMEM; 719 + refcount_set(&sysnames->usage, 1); 720 + kill = sysnames; 404 721 405 - if (size >= PAGE_SIZE - 1) { 406 - sysnames->error = -EINVAL; 407 - return -EINVAL; 408 - } 409 - if (size == 0) 410 - return 0; 411 - 412 - kbuf = memdup_user_nul(buf, size); 413 - if (IS_ERR(kbuf)) 414 - return PTR_ERR(kbuf); 415 - 416 - inode_lock(file_inode(file)); 417 - 418 - p = kbuf; 722 + p = buf; 419 723 while ((s = strsep(&p, " \t\n"))) { 420 724 len = strlen(s); 421 725 if (len == 0) ··· 485 731 sysnames->nr++; 486 732 } 487 733 488 - ret = size; /* consume everything, always */ 734 + if (sysnames->nr == 0) { 735 + sysnames->subs[0] = sysnames->blank; 736 + sysnames->nr++; 737 + } 738 + 739 + write_lock(&net->sysnames_lock); 740 + kill = net->sysnames; 741 + net->sysnames = sysnames; 742 + write_unlock(&net->sysnames_lock); 743 + ret = 0; 489 744 out: 490 - inode_unlock(file_inode(file)); 491 - kfree(kbuf); 745 + afs_put_sysnames(kill); 492 746 return ret; 493 747 494 748 invalid: 495 749 ret = -EINVAL; 496 750 error: 497 - sysnames->error = ret; 498 751 goto out; 499 752 } 500 753 501 - static int afs_proc_sysname_release(struct inode *inode, struct file *file) 754 + void afs_put_sysnames(struct afs_sysnames *sysnames) 502 755 { 503 - struct afs_sysnames *sysnames, *kill = NULL; 504 - struct seq_file *m = file->private_data; 505 - struct afs_net *net = afs_seq2net(m); 756 + int i; 506 757 507 - sysnames = m->private; 508 - if (sysnames) { 509 - if (!sysnames->error) { 510 - kill = sysnames; 511 - if (sysnames->nr == 0) { 512 - sysnames->subs[0] = sysnames->blank; 513 - sysnames->nr++; 514 - } 515 - write_lock(&net->sysnames_lock); 516 - kill = net->sysnames; 517 - net->sysnames = sysnames; 518 - write_unlock(&net->sysnames_lock); 519 - } 520 - afs_put_sysnames(kill); 758 + if (sysnames && refcount_dec_and_test(&sysnames->usage)) { 759 + for (i = 0; i < sysnames->nr; i++) 760 + if (sysnames->subs[i] != afs_init_sysname && 761 + sysnames->subs[i] != sysnames->blank) 762 + kfree(sysnames->subs[i]); 521 763 } 522 - 523 - return seq_release(inode, file); 524 - } 525 - 526 - static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos) 527 - __acquires(&net->sysnames_lock) 528 - { 529 - struct afs_net *net = afs_seq2net(m); 530 - struct afs_sysnames *names = net->sysnames; 531 - 532 - read_lock(&net->sysnames_lock); 533 - 534 - if (*pos >= names->nr) 535 - return NULL; 536 - return (void *)(unsigned long)(*pos + 1); 537 - } 538 - 539 - static void *afs_proc_sysname_next(struct seq_file *m, void *v, loff_t *pos) 540 - { 541 - struct afs_net *net = afs_seq2net(m); 542 - struct afs_sysnames *names = net->sysnames; 543 - 544 - *pos += 1; 545 - if (*pos >= names->nr) 546 - return NULL; 547 - return (void *)(unsigned long)(*pos + 1); 548 - } 549 - 550 - static void afs_proc_sysname_stop(struct seq_file *m, void *v) 551 - __releases(&net->sysnames_lock) 552 - { 553 - struct afs_net *net = afs_seq2net(m); 554 - 555 - read_unlock(&net->sysnames_lock); 556 - } 557 - 558 - static int afs_proc_sysname_show(struct seq_file *m, void *v) 559 - { 560 - struct afs_net *net = afs_seq2net(m); 561 - struct afs_sysnames *sysnames = net->sysnames; 562 - unsigned int i = (unsigned long)v - 1; 563 - 564 - if (i < sysnames->nr) 565 - seq_printf(m, "%s\n", sysnames->subs[i]); 566 - return 0; 567 764 } 568 765 569 766 /* ··· 522 817 */ 523 818 static int afs_proc_stats_show(struct seq_file *m, void *v) 524 819 { 525 - struct afs_net *net = afs_seq2net(m); 820 + struct afs_net *net = afs_seq2net_single(m); 526 821 527 822 seq_puts(m, "kAFS statistics\n"); 528 823 ··· 546 841 atomic_read(&net->n_stores), 547 842 atomic_long_read(&net->n_store_bytes)); 548 843 return 0; 844 + } 845 + 846 + /* 847 + * initialise /proc/fs/afs/<cell>/ 848 + */ 849 + int afs_proc_cell_setup(struct afs_cell *cell) 850 + { 851 + struct proc_dir_entry *dir; 852 + struct afs_net *net = cell->net; 853 + 854 + _enter("%p{%s},%p", cell, cell->name, net->proc_afs); 855 + 856 + dir = proc_net_mkdir(net->net, cell->name, net->proc_afs); 857 + if (!dir) 858 + goto error_dir; 859 + 860 + if (!proc_create_net_data("vlservers", 0444, dir, 861 + &afs_proc_cell_vlservers_ops, 862 + sizeof(struct seq_net_private), 863 + cell) || 864 + !proc_create_net_data("volumes", 0444, dir, 865 + &afs_proc_cell_volumes_ops, 866 + sizeof(struct seq_net_private), 867 + cell)) 868 + goto error_tree; 869 + 870 + _leave(" = 0"); 871 + return 0; 872 + 873 + error_tree: 874 + remove_proc_subtree(cell->name, net->proc_afs); 875 + error_dir: 876 + _leave(" = -ENOMEM"); 877 + return -ENOMEM; 878 + } 879 + 880 + /* 881 + * remove /proc/fs/afs/<cell>/ 882 + */ 883 + void afs_proc_cell_remove(struct afs_cell *cell) 884 + { 885 + struct afs_net *net = cell->net; 886 + 887 + _enter(""); 888 + remove_proc_subtree(cell->name, net->proc_afs); 889 + _leave(""); 890 + } 891 + 892 + /* 893 + * initialise the /proc/fs/afs/ directory 894 + */ 895 + int afs_proc_init(struct afs_net *net) 896 + { 897 + struct proc_dir_entry *p; 898 + 899 + _enter(""); 900 + 901 + p = proc_net_mkdir(net->net, "afs", net->net->proc_net); 902 + if (!p) 903 + goto error_dir; 904 + 905 + if (!proc_create_net_data_write("cells", 0644, p, 906 + &afs_proc_cells_ops, 907 + afs_proc_cells_write, 908 + sizeof(struct seq_net_private), 909 + NULL) || 910 + !proc_create_net_single_write("rootcell", 0644, p, 911 + afs_proc_rootcell_show, 912 + afs_proc_rootcell_write, 913 + NULL) || 914 + !proc_create_net("servers", 0444, p, &afs_proc_servers_ops, 915 + sizeof(struct seq_net_private)) || 916 + !proc_create_net_single("stats", 0444, p, afs_proc_stats_show, NULL) || 917 + !proc_create_net_data_write("sysname", 0644, p, 918 + &afs_proc_sysname_ops, 919 + afs_proc_sysname_write, 920 + sizeof(struct seq_net_private), 921 + NULL)) 922 + goto error_tree; 923 + 924 + net->proc_afs = p; 925 + _leave(" = 0"); 926 + return 0; 927 + 928 + error_tree: 929 + proc_remove(p); 930 + error_dir: 931 + _leave(" = -ENOMEM"); 932 + return -ENOMEM; 933 + } 934 + 935 + /* 936 + * clean up the /proc/fs/afs/ directory 937 + */ 938 + void afs_proc_cleanup(struct afs_net *net) 939 + { 940 + proc_remove(net->proc_afs); 941 + net->proc_afs = NULL; 549 942 }
+1 -1
fs/afs/rxrpc.c
··· 46 46 47 47 _enter(""); 48 48 49 - ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET6, &socket); 49 + ret = sock_create_kern(net->net, AF_RXRPC, SOCK_DGRAM, PF_INET6, &socket); 50 50 if (ret < 0) 51 51 goto error_1; 52 52
+1 -1
fs/afs/server.c
··· 228 228 server->flags = (1UL << AFS_SERVER_FL_NEW); 229 229 server->update_at = ktime_get_real_seconds() + afs_server_update_delay; 230 230 rwlock_init(&server->fs_lock); 231 - INIT_LIST_HEAD(&server->cb_interests); 231 + INIT_HLIST_HEAD(&server->cb_volumes); 232 232 rwlock_init(&server->cb_break_lock); 233 233 234 234 afs_inc_servers_outstanding(net);
+42 -26
fs/afs/super.c
··· 48 48 }; 49 49 MODULE_ALIAS_FS("afs"); 50 50 51 + int afs_net_id; 52 + 51 53 static const struct super_operations afs_super_ops = { 52 54 .statfs = afs_statfs, 53 55 .alloc_inode = afs_alloc_inode, ··· 119 117 /* 120 118 * clean up the filesystem 121 119 */ 122 - void __exit afs_fs_exit(void) 120 + void afs_fs_exit(void) 123 121 { 124 122 _enter(""); 125 123 ··· 353 351 struct afs_super_info *as1 = data; 354 352 struct afs_super_info *as = AFS_FS_S(sb); 355 353 356 - return (as->net == as1->net && 354 + return (as->net_ns == as1->net_ns && 357 355 as->volume && 358 - as->volume->vid == as1->volume->vid); 356 + as->volume->vid == as1->volume->vid && 357 + !as->dyn_root); 359 358 } 360 359 361 360 static int afs_dynroot_test_super(struct super_block *sb, void *data) 362 361 { 363 - return false; 362 + struct afs_super_info *as1 = data; 363 + struct afs_super_info *as = AFS_FS_S(sb); 364 + 365 + return (as->net_ns == as1->net_ns && 366 + as->dyn_root); 364 367 } 365 368 366 369 static int afs_set_super(struct super_block *sb, void *data) ··· 425 418 if (!sb->s_root) 426 419 goto error; 427 420 428 - if (params->dyn_root) 421 + if (as->dyn_root) { 429 422 sb->s_d_op = &afs_dynroot_dentry_operations; 430 - else 423 + ret = afs_dynroot_populate(sb); 424 + if (ret < 0) 425 + goto error; 426 + } else { 431 427 sb->s_d_op = &afs_fs_dentry_operations; 428 + } 432 429 433 430 _leave(" = 0"); 434 431 return 0; ··· 448 437 449 438 as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); 450 439 if (as) { 451 - as->net = afs_get_net(params->net); 440 + as->net_ns = get_net(params->net_ns); 452 441 if (params->dyn_root) 453 442 as->dyn_root = true; 454 443 else ··· 461 450 { 462 451 if (as) { 463 452 afs_put_volume(as->cell, as->volume); 464 - afs_put_cell(as->net, as->cell); 465 - afs_put_net(as->net); 453 + afs_put_cell(afs_net(as->net_ns), as->cell); 454 + put_net(as->net_ns); 466 455 kfree(as); 467 456 } 457 + } 458 + 459 + static void afs_kill_super(struct super_block *sb) 460 + { 461 + struct afs_super_info *as = AFS_FS_S(sb); 462 + struct afs_net *net = afs_net(as->net_ns); 463 + 464 + if (as->dyn_root) 465 + afs_dynroot_depopulate(sb); 466 + 467 + /* Clear the callback interests (which will do ilookup5) before 468 + * deactivating the superblock. 469 + */ 470 + if (as->volume) 471 + afs_clear_callback_interests(net, as->volume->servers); 472 + kill_anon_super(sb); 473 + if (as->volume) 474 + afs_deactivate_volume(as->volume); 475 + afs_destroy_sbi(as); 468 476 } 469 477 470 478 /* ··· 502 472 _enter(",,%s,%p", dev_name, options); 503 473 504 474 memset(&params, 0, sizeof(params)); 505 - params.net = &__afs_net; 506 475 507 476 ret = -EINVAL; 508 477 if (current->nsproxy->net_ns != &init_net) 509 478 goto error; 510 - 479 + params.net_ns = current->nsproxy->net_ns; 480 + params.net = afs_net(params.net_ns); 481 + 511 482 /* parse the options and device name */ 512 483 if (options) { 513 484 ret = afs_parse_options(&params, options, &dev_name); ··· 592 561 afs_put_cell(params.net, params.cell); 593 562 _leave(" = %d", ret); 594 563 return ERR_PTR(ret); 595 - } 596 - 597 - static void afs_kill_super(struct super_block *sb) 598 - { 599 - struct afs_super_info *as = AFS_FS_S(sb); 600 - 601 - /* Clear the callback interests (which will do ilookup5) before 602 - * deactivating the superblock. 603 - */ 604 - if (as->volume) 605 - afs_clear_callback_interests(as->net, as->volume->servers); 606 - kill_anon_super(sb); 607 - if (as->volume) 608 - afs_deactivate_volume(as->volume); 609 - afs_destroy_sbi(as); 610 564 } 611 565 612 566 /*
+29
fs/namei.c
··· 2464 2464 } 2465 2465 2466 2466 /** 2467 + * try_lookup_one_len - filesystem helper to lookup single pathname component 2468 + * @name: pathname component to lookup 2469 + * @base: base directory to lookup from 2470 + * @len: maximum length @len should be interpreted to 2471 + * 2472 + * Look up a dentry by name in the dcache, returning NULL if it does not 2473 + * currently exist. The function does not try to create a dentry. 2474 + * 2475 + * Note that this routine is purely a helper for filesystem usage and should 2476 + * not be called by generic code. 2477 + * 2478 + * The caller must hold base->i_mutex. 2479 + */ 2480 + struct dentry *try_lookup_one_len(const char *name, struct dentry *base, int len) 2481 + { 2482 + struct qstr this; 2483 + int err; 2484 + 2485 + WARN_ON_ONCE(!inode_is_locked(base->d_inode)); 2486 + 2487 + err = lookup_one_len_common(name, base, len, &this); 2488 + if (err) 2489 + return ERR_PTR(err); 2490 + 2491 + return lookup_dcache(&this, base, 0); 2492 + } 2493 + EXPORT_SYMBOL(try_lookup_one_len); 2494 + 2495 + /** 2467 2496 * lookup_one_len - filesystem helper to lookup single pathname component 2468 2497 * @name: pathname component to lookup 2469 2498 * @base: base directory to lookup from
+25 -1
fs/proc/generic.c
··· 409 409 if (!ent) 410 410 goto out; 411 411 412 - if (qstr.len + 1 <= sizeof(ent->inline_name)) { 412 + if (qstr.len + 1 <= SIZEOF_PDE_INLINE_NAME) { 413 413 ent->name = ent->inline_name; 414 414 } else { 415 415 ent->name = kmalloc(qstr.len + 1, GFP_KERNEL); ··· 740 740 return __PDE_DATA(inode); 741 741 } 742 742 EXPORT_SYMBOL(PDE_DATA); 743 + 744 + /* 745 + * Pull a user buffer into memory and pass it to the file's write handler if 746 + * one is supplied. The ->write() method is permitted to modify the 747 + * kernel-side buffer. 748 + */ 749 + ssize_t proc_simple_write(struct file *f, const char __user *ubuf, size_t size, 750 + loff_t *_pos) 751 + { 752 + struct proc_dir_entry *pde = PDE(file_inode(f)); 753 + char *buf; 754 + int ret; 755 + 756 + if (!pde->write) 757 + return -EACCES; 758 + if (size == 0 || size > PAGE_SIZE - 1) 759 + return -EINVAL; 760 + buf = memdup_user_nul(ubuf, size); 761 + if (IS_ERR(buf)) 762 + return PTR_ERR(buf); 763 + ret = pde->write(f, buf, size); 764 + kfree(buf); 765 + return ret == 0 ? size : ret; 766 + }
+2 -3
fs/proc/inode.c
··· 105 105 kmem_cache_create("pde_opener", sizeof(struct pde_opener), 0, 106 106 SLAB_ACCOUNT|SLAB_PANIC, NULL); 107 107 proc_dir_entry_cache = kmem_cache_create_usercopy( 108 - "proc_dir_entry", sizeof(struct proc_dir_entry), 0, SLAB_PANIC, 109 - offsetof(struct proc_dir_entry, inline_name), 110 - sizeof_field(struct proc_dir_entry, inline_name), NULL); 108 + "proc_dir_entry", SIZEOF_PDE_SLOT, 0, SLAB_PANIC, 109 + OFFSETOF_PDE_NAME, SIZEOF_PDE_INLINE_NAME, NULL); 111 110 } 112 111 113 112 static int proc_show_options(struct seq_file *seq, struct dentry *root)
+14 -6
fs/proc/internal.h
··· 48 48 const struct seq_operations *seq_ops; 49 49 int (*single_show)(struct seq_file *, void *); 50 50 }; 51 + proc_write_t write; 51 52 void *data; 52 53 unsigned int state_size; 53 54 unsigned int low_ino; ··· 62 61 char *name; 63 62 umode_t mode; 64 63 u8 namelen; 65 - #ifdef CONFIG_64BIT 66 - #define SIZEOF_PDE_INLINE_NAME (192-155) 67 - #else 68 - #define SIZEOF_PDE_INLINE_NAME (128-95) 69 - #endif 70 - char inline_name[SIZEOF_PDE_INLINE_NAME]; 64 + char inline_name[]; 71 65 } __randomize_layout; 66 + 67 + #define OFFSETOF_PDE_NAME offsetof(struct proc_dir_entry, inline_name) 68 + #define SIZEOF_PDE_SLOT \ 69 + (OFFSETOF_PDE_NAME + 34 <= 64 ? 64 : \ 70 + OFFSETOF_PDE_NAME + 34 <= 128 ? 128 : \ 71 + OFFSETOF_PDE_NAME + 34 <= 192 ? 192 : \ 72 + OFFSETOF_PDE_NAME + 34 <= 256 ? 256 : \ 73 + OFFSETOF_PDE_NAME + 34 <= 512 ? 512 : \ 74 + 0) 75 + 76 + #define SIZEOF_PDE_INLINE_NAME (SIZEOF_PDE_SLOT - OFFSETOF_PDE_NAME) 72 77 73 78 extern struct kmem_cache *proc_dir_entry_cache; 74 79 void pde_free(struct proc_dir_entry *pde); ··· 196 189 { 197 190 return S_ISDIR(pde->mode) && !pde->proc_iops; 198 191 } 192 + extern ssize_t proc_simple_write(struct file *, const char __user *, size_t, loff_t *); 199 193 200 194 /* 201 195 * inode.c
+92
fs/proc/proc_net.c
··· 46 46 47 47 WARN_ON_ONCE(state_size < sizeof(*p)); 48 48 49 + if (file->f_mode & FMODE_WRITE && !PDE(inode)->write) 50 + return -EACCES; 51 + 49 52 net = get_proc_net(inode); 50 53 if (!net) 51 54 return -ENXIO; ··· 76 73 static const struct file_operations proc_net_seq_fops = { 77 74 .open = seq_open_net, 78 75 .read = seq_read, 76 + .write = proc_simple_write, 79 77 .llseek = seq_lseek, 80 78 .release = seq_release_net, 81 79 }; ··· 96 92 return proc_register(parent, p); 97 93 } 98 94 EXPORT_SYMBOL_GPL(proc_create_net_data); 95 + 96 + /** 97 + * proc_create_net_data_write - Create a writable net_ns-specific proc file 98 + * @name: The name of the file. 99 + * @mode: The file's access mode. 100 + * @parent: The parent directory in which to create. 101 + * @ops: The seq_file ops with which to read the file. 102 + * @write: The write method which which to 'modify' the file. 103 + * @data: Data for retrieval by PDE_DATA(). 104 + * 105 + * Create a network namespaced proc file in the @parent directory with the 106 + * specified @name and @mode that allows reading of a file that displays a 107 + * series of elements and also provides for the file accepting writes that have 108 + * some arbitrary effect. 109 + * 110 + * The functions in the @ops table are used to iterate over items to be 111 + * presented and extract the readable content using the seq_file interface. 112 + * 113 + * The @write function is called with the data copied into a kernel space 114 + * scratch buffer and has a NUL appended for convenience. The buffer may be 115 + * modified by the @write function. @write should return 0 on success. 116 + * 117 + * The @data value is accessible from the @show and @write functions by calling 118 + * PDE_DATA() on the file inode. The network namespace must be accessed by 119 + * calling seq_file_net() on the seq_file struct. 120 + */ 121 + struct proc_dir_entry *proc_create_net_data_write(const char *name, umode_t mode, 122 + struct proc_dir_entry *parent, 123 + const struct seq_operations *ops, 124 + proc_write_t write, 125 + unsigned int state_size, void *data) 126 + { 127 + struct proc_dir_entry *p; 128 + 129 + p = proc_create_reg(name, mode, &parent, data); 130 + if (!p) 131 + return NULL; 132 + p->proc_fops = &proc_net_seq_fops; 133 + p->seq_ops = ops; 134 + p->state_size = state_size; 135 + p->write = write; 136 + return proc_register(parent, p); 137 + } 138 + EXPORT_SYMBOL_GPL(proc_create_net_data_write); 99 139 100 140 static int single_open_net(struct inode *inode, struct file *file) 101 141 { ··· 167 119 static const struct file_operations proc_net_single_fops = { 168 120 .open = single_open_net, 169 121 .read = seq_read, 122 + .write = proc_simple_write, 170 123 .llseek = seq_lseek, 171 124 .release = single_release_net, 172 125 }; ··· 186 137 return proc_register(parent, p); 187 138 } 188 139 EXPORT_SYMBOL_GPL(proc_create_net_single); 140 + 141 + /** 142 + * proc_create_net_single_write - Create a writable net_ns-specific proc file 143 + * @name: The name of the file. 144 + * @mode: The file's access mode. 145 + * @parent: The parent directory in which to create. 146 + * @show: The seqfile show method with which to read the file. 147 + * @write: The write method which which to 'modify' the file. 148 + * @data: Data for retrieval by PDE_DATA(). 149 + * 150 + * Create a network-namespaced proc file in the @parent directory with the 151 + * specified @name and @mode that allows reading of a file that displays a 152 + * single element rather than a series and also provides for the file accepting 153 + * writes that have some arbitrary effect. 154 + * 155 + * The @show function is called to extract the readable content via the 156 + * seq_file interface. 157 + * 158 + * The @write function is called with the data copied into a kernel space 159 + * scratch buffer and has a NUL appended for convenience. The buffer may be 160 + * modified by the @write function. @write should return 0 on success. 161 + * 162 + * The @data value is accessible from the @show and @write functions by calling 163 + * PDE_DATA() on the file inode. The network namespace must be accessed by 164 + * calling seq_file_single_net() on the seq_file struct. 165 + */ 166 + struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mode, 167 + struct proc_dir_entry *parent, 168 + int (*show)(struct seq_file *, void *), 169 + proc_write_t write, 170 + void *data) 171 + { 172 + struct proc_dir_entry *p; 173 + 174 + p = proc_create_reg(name, mode, &parent, data); 175 + if (!p) 176 + return NULL; 177 + p->proc_fops = &proc_net_single_fops; 178 + p->single_show = show; 179 + p->write = write; 180 + return proc_register(parent, p); 181 + } 182 + EXPORT_SYMBOL_GPL(proc_create_net_single_write); 189 183 190 184 static struct net *get_proc_task_net(struct inode *dir) 191 185 {
+1 -2
fs/proc/root.c
··· 204 204 .proc_fops = &proc_root_operations, 205 205 .parent = &proc_root, 206 206 .subdir = RB_ROOT, 207 - .name = proc_root.inline_name, 208 - .inline_name = "/proc", 207 + .name = "/proc", 209 208 }; 210 209 211 210 int pid_ns_prepare_proc(struct pid_namespace *ns)
+1
include/linux/namei.h
··· 81 81 extern struct dentry *kern_path_locked(const char *, struct path *); 82 82 extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int); 83 83 84 + extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); 84 85 extern struct dentry *lookup_one_len(const char *, struct dentry *, int); 85 86 extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); 86 87
+12
include/linux/proc_fs.h
··· 14 14 15 15 #ifdef CONFIG_PROC_FS 16 16 17 + typedef int (*proc_write_t)(struct file *, char *, size_t); 18 + 17 19 extern void proc_root_init(void); 18 20 extern void proc_flush_task(struct task_struct *); 19 21 ··· 63 61 struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode, 64 62 struct proc_dir_entry *parent, 65 63 int (*show)(struct seq_file *, void *), void *data); 64 + struct proc_dir_entry *proc_create_net_data_write(const char *name, umode_t mode, 65 + struct proc_dir_entry *parent, 66 + const struct seq_operations *ops, 67 + proc_write_t write, 68 + unsigned int state_size, void *data); 69 + struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mode, 70 + struct proc_dir_entry *parent, 71 + int (*show)(struct seq_file *, void *), 72 + proc_write_t write, 73 + void *data); 66 74 67 75 #else /* CONFIG_PROC_FS */ 68 76