Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'afs-next-20200604' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

Pull AFS updates from David Howells:
"There's some core VFS changes which affect a couple of filesystems:

- Make the inode hash table RCU safe and providing some RCU-safe
accessor functions. The search can then be done without taking the
inode_hash_lock. Care must be taken because the object may be being
deleted and no wait is made.

- Allow iunique() to avoid taking the inode_hash_lock.

- Allow AFS's callback processing to avoid taking the inode_hash_lock
when using the inode table to find an inode to notify.

- Improve Ext4's time updating. Konstantin Khlebnikov said "For now,
I've plugged this issue with try-lock in ext4 lazy time update.
This solution is much better."

Then there's a set of changes to make a number of improvements to the
AFS driver:

- Improve callback (ie. third party change notification) processing
by:

(a) Relying more on the fact we're doing this under RCU and by
using fewer locks. This makes use of the RCU-based inode
searching outlined above.

(b) Moving to keeping volumes in a tree indexed by volume ID
rather than a flat list.

(c) Making the server and volume records logically part of the
cell. This means that a server record now points directly at
the cell and the tree of volumes is there. This removes an N:M
mapping table, simplifying things.

- Improve keeping NAT or firewall channels open for the server
callbacks to reach the client by actively polling the fileserver on
a timed basis, instead of only doing it when we have an operation
to process.

- Improving detection of delayed or lost callbacks by including the
parent directory in the list of file IDs to be queried when doing a
bulk status fetch from lookup. We can then check to see if our copy
of the directory has changed under us without us getting notified.

- Determine aliasing of cells (such as a cell that is pointed to be a
DNS alias). This allows us to avoid having ambiguity due to
apparently different cells using the same volume and file servers.

- Improve the fileserver rotation to do more probing when it detects
that all of the addresses to a server are listed as non-responsive.
It's possible that an address that previously stopped responding
has become responsive again.

Beyond that, lay some foundations for making some calls asynchronous:

- Turn the fileserver cursor struct into a general operation struct
and hang the parameters off of that rather than keeping them in
local variables and hang results off of that rather than the call
struct.

- Implement some general operation handling code and simplify the
callers of operations that affect a volume or a volume component
(such as a file). Most of the operation is now done by core code.

- Operations are supplied with a table of operations to issue
different variants of RPCs and to manage the completion, where all
the required data is held in the operation object, thereby allowing
these to be called from a workqueue.

- Put the standard "if (begin), while(select), call op, end" sequence
into a canned function that just emulates the current behaviour for
now.

There are also some fixes interspersed:

- Don't let the EACCES from ICMP6 mapping reach the user as such,
since it's confusing as to whether it's a filesystem error. Convert
it to EHOSTUNREACH.

- Don't use the epoch value acquired through probing a server. If we
have two servers with the same UUID but in different cells, it's
hard to draw conclusions from them having different epoch values.

- Don't interpret the argument to the CB.ProbeUuid RPC as a
fileserver UUID and look up a fileserver from it.

- Deal with servers in different cells having the same UUIDs. In the
event that a CB.InitCallBackState3 RPC is received, we have to
break the callback promises for every server record matching that
UUID.

- Don't let afs_statfs return values that go below 0.

- Don't use running fileserver probe state to make server selection
and address selection decisions on. Only make decisions on final
state as the running state is cleared at the start of probing"

Acked-by: Al Viro <viro@zeniv.linux.org.uk> (fs/inode.c part)

* tag 'afs-next-20200604' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: (27 commits)
afs: Adjust the fileserver rotation algorithm to reprobe/retry more quickly
afs: Show more a bit more server state in /proc/net/afs/servers
afs: Don't use probe running state to make decisions outside probe code
afs: Fix afs_statfs() to not let the values go below zero
afs: Fix the by-UUID server tree to allow servers with the same UUID
afs: Reorganise volume and server trees to be rooted on the cell
afs: Add a tracepoint to track the lifetime of the afs_volume struct
afs: Detect cell aliases 3 - YFS Cells with a canonical cell name op
afs: Detect cell aliases 2 - Cells with no root volumes
afs: Detect cell aliases 1 - Cells with root volumes
afs: Implement client support for the YFSVL.GetCellName RPC op
afs: Retain more of the VLDB record for alias detection
afs: Fix handling of CB.ProbeUuid cache manager op
afs: Don't get epoch from a server because it may be ambiguous
afs: Build an abstraction around an "operation" concept
afs: Rename struct afs_fs_cursor to afs_operation
afs: Remove the error argument from afs_protocol_error()
afs: Set error flag rather than return error from file status decode
afs: Make callback processing more efficient.
afs: Show more information in /proc/net/afs/servers
...

+4453 -3939
+2
fs/afs/Makefile
··· 18 18 file.o \ 19 19 flock.o \ 20 20 fsclient.o \ 21 + fs_operation.o \ 21 22 fs_probe.o \ 22 23 inode.o \ 23 24 main.o \ ··· 31 30 server_list.o \ 32 31 super.o \ 33 32 vlclient.o \ 33 + vl_alias.o \ 34 34 vl_list.o \ 35 35 vl_probe.o \ 36 36 vl_rotate.o \
+1 -2
fs/afs/afs.h
··· 10 10 11 11 #include <linux/in.h> 12 12 13 - #define AFS_MAXCELLNAME 64 /* Maximum length of a cell name */ 13 + #define AFS_MAXCELLNAME 256 /* Maximum length of a cell name */ 14 14 #define AFS_MAXVOLNAME 64 /* Maximum length of a volume name */ 15 15 #define AFS_MAXNSERVERS 8 /* Maximum servers in a basic volume record */ 16 16 #define AFS_NMAXNSERVERS 13 /* Maximum servers in a N/U-class volume record */ ··· 146 146 struct afs_status_cb { 147 147 struct afs_file_status status; 148 148 struct afs_callback callback; 149 - unsigned int cb_break; /* Pre-op callback break counter */ 150 149 bool have_status; /* True if status record was retrieved */ 151 150 bool have_cb; /* True if cb record was retrieved */ 152 151 bool have_error; /* True if status.abort_code indicates an error */
+1
fs/afs/afs_vl.h
··· 22 22 VLGETENTRYBYNAMEU = 527, /* AFS Get VLDB entry by name (UUID-variant) */ 23 23 VLGETADDRSU = 533, /* AFS Get addrs for fileserver */ 24 24 YVLGETENDPOINTS = 64002, /* YFS Get endpoints for file/volume server */ 25 + YVLGETCELLNAME = 64014, /* YFS Get actual cell name */ 25 26 VLGETCAPABILITIES = 65537, /* AFS Get server capabilities */ 26 27 }; 27 28
+96 -249
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, afs_server_trace_get_new_cbi); 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 - /* 84 - * Set up an interest-in-callbacks record for a volume on a server and 85 - * register it with the server. 86 - * - Called with vnode->io_lock held. 87 - */ 88 - int afs_register_server_cb_interest(struct afs_vnode *vnode, 89 - struct afs_server_list *slist, 90 - unsigned int index) 91 - { 92 - struct afs_server_entry *entry = &slist->servers[index]; 93 - struct afs_cb_interest *cbi, *vcbi, *new, *old; 94 - struct afs_server *server = entry->server; 95 - 96 - again: 97 - vcbi = rcu_dereference_protected(vnode->cb_interest, 98 - lockdep_is_held(&vnode->io_lock)); 99 - if (vcbi && likely(vcbi == entry->cb_interest)) 100 - return 0; 101 - 102 - read_lock(&slist->lock); 103 - cbi = afs_get_cb_interest(entry->cb_interest); 104 - read_unlock(&slist->lock); 105 - 106 - if (vcbi) { 107 - if (vcbi == cbi) { 108 - afs_put_cb_interest(afs_v2net(vnode), cbi); 109 - return 0; 110 - } 111 - 112 - /* Use a new interest in the server list for the same server 113 - * rather than an old one that's still attached to a vnode. 114 - */ 115 - if (cbi && vcbi->server == cbi->server) { 116 - write_seqlock(&vnode->cb_lock); 117 - old = rcu_dereference_protected(vnode->cb_interest, 118 - lockdep_is_held(&vnode->cb_lock.lock)); 119 - rcu_assign_pointer(vnode->cb_interest, cbi); 120 - write_sequnlock(&vnode->cb_lock); 121 - afs_put_cb_interest(afs_v2net(vnode), old); 122 - return 0; 123 - } 124 - 125 - /* Re-use the one attached to the vnode. */ 126 - if (!cbi && vcbi->server == server) { 127 - write_lock(&slist->lock); 128 - if (entry->cb_interest) { 129 - write_unlock(&slist->lock); 130 - afs_put_cb_interest(afs_v2net(vnode), cbi); 131 - goto again; 132 - } 133 - 134 - entry->cb_interest = cbi; 135 - write_unlock(&slist->lock); 136 - return 0; 137 - } 138 - } 139 - 140 - if (!cbi) { 141 - new = afs_create_interest(server, vnode); 142 - if (!new) 143 - return -ENOMEM; 144 - 145 - write_lock(&slist->lock); 146 - if (!entry->cb_interest) { 147 - entry->cb_interest = afs_get_cb_interest(new); 148 - cbi = new; 149 - new = NULL; 150 - } else { 151 - cbi = afs_get_cb_interest(entry->cb_interest); 152 - } 153 - write_unlock(&slist->lock); 154 - afs_put_cb_interest(afs_v2net(vnode), new); 155 - } 156 - 157 - ASSERT(cbi); 158 - 159 - /* Change the server the vnode is using. This entails scrubbing any 160 - * interest the vnode had in the previous server it was using. 161 - */ 162 - write_seqlock(&vnode->cb_lock); 163 - 164 - old = rcu_dereference_protected(vnode->cb_interest, 165 - lockdep_is_held(&vnode->cb_lock.lock)); 166 - rcu_assign_pointer(vnode->cb_interest, cbi); 167 - vnode->cb_s_break = cbi->server->cb_s_break; 168 - vnode->cb_v_break = vnode->volume->cb_v_break; 169 - clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 170 - 171 - write_sequnlock(&vnode->cb_lock); 172 - afs_put_cb_interest(afs_v2net(vnode), old); 173 - return 0; 174 - } 175 - 176 - /* 177 - * Remove an interest on a server. 178 - */ 179 - void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi) 180 - { 181 - struct afs_vol_interest *vi; 182 - 183 - if (cbi && refcount_dec_and_test(&cbi->usage)) { 184 - if (!hlist_unhashed(&cbi->cb_vlink)) { 185 - write_lock(&cbi->server->cb_break_lock); 186 - 187 - hlist_del_init(&cbi->cb_vlink); 188 - vi = cbi->vol_interest; 189 - cbi->vol_interest = NULL; 190 - if (--vi->usage == 0) 191 - hlist_del(&vi->srv_link); 192 - else 193 - vi = NULL; 194 - 195 - write_unlock(&cbi->server->cb_break_lock); 196 - if (vi) 197 - kfree_rcu(vi, rcu); 198 - afs_put_server(net, cbi->server, afs_server_trace_put_cbi); 199 - } 200 - kfree_rcu(cbi, rcu); 201 - } 202 - } 203 - 204 - /* 205 - * allow the fileserver to request callback state (re-)initialisation 24 + * Allow the fileserver to request callback state (re-)initialisation. 25 + * Unfortunately, UUIDs are not guaranteed unique. 206 26 */ 207 27 void afs_init_callback_state(struct afs_server *server) 208 28 { 209 - server->cb_s_break++; 29 + rcu_read_lock(); 30 + do { 31 + server->cb_s_break++; 32 + server = rcu_dereference(server->uuid_next); 33 + } while (0); 34 + rcu_read_unlock(); 210 35 } 211 36 212 37 /* ··· 63 238 } 64 239 65 240 /* 241 + * Look up a volume by volume ID under RCU conditions. 242 + */ 243 + static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell, 244 + afs_volid_t vid) 245 + { 246 + struct afs_volume *volume = NULL; 247 + struct rb_node *p; 248 + int seq = 0; 249 + 250 + do { 251 + /* Unfortunately, rbtree walking doesn't give reliable results 252 + * under just the RCU read lock, so we have to check for 253 + * changes. 254 + */ 255 + read_seqbegin_or_lock(&cell->volume_lock, &seq); 256 + 257 + p = rcu_dereference_raw(cell->volumes.rb_node); 258 + while (p) { 259 + volume = rb_entry(p, struct afs_volume, cell_node); 260 + 261 + if (volume->vid < vid) 262 + p = rcu_dereference_raw(p->rb_left); 263 + else if (volume->vid > vid) 264 + p = rcu_dereference_raw(p->rb_right); 265 + else 266 + break; 267 + volume = NULL; 268 + } 269 + 270 + } while (need_seqretry(&cell->volume_lock, seq)); 271 + 272 + done_seqretry(&cell->volume_lock, seq); 273 + return volume; 274 + } 275 + 276 + /* 66 277 * allow the fileserver to explicitly break one callback 67 278 * - happens when 68 279 * - the backing file is changed 69 280 * - a lock is released 70 281 */ 71 - static void afs_break_one_callback(struct afs_server *server, 282 + static void afs_break_one_callback(struct afs_volume *volume, 72 283 struct afs_fid *fid) 73 284 { 74 - struct afs_vol_interest *vi; 75 - struct afs_cb_interest *cbi; 76 - struct afs_iget_data data; 285 + struct super_block *sb; 77 286 struct afs_vnode *vnode; 78 287 struct inode *inode; 79 288 80 - read_lock(&server->cb_break_lock); 81 - hlist_for_each_entry(vi, &server->cb_volumes, srv_link) { 82 - if (vi->vid < fid->vid) 83 - continue; 84 - if (vi->vid > fid->vid) { 85 - vi = NULL; 86 - break; 87 - } 88 - //atomic_inc(&vi->usage); 89 - break; 289 + if (fid->vnode == 0 && fid->unique == 0) { 290 + /* The callback break applies to an entire volume. */ 291 + write_lock(&volume->cb_v_break_lock); 292 + volume->cb_v_break++; 293 + trace_afs_cb_break(fid, volume->cb_v_break, 294 + afs_cb_break_for_volume_callback, false); 295 + write_unlock(&volume->cb_v_break_lock); 296 + return; 90 297 } 298 + 299 + /* See if we can find a matching inode - even an I_NEW inode needs to 300 + * be marked as it can have its callback broken before we finish 301 + * setting up the local inode. 302 + */ 303 + sb = rcu_dereference(volume->sb); 304 + if (!sb) 305 + return; 306 + 307 + inode = find_inode_rcu(sb, fid->vnode, afs_ilookup5_test_by_fid, fid); 308 + if (inode) { 309 + vnode = AFS_FS_I(inode); 310 + afs_break_callback(vnode, afs_cb_break_for_callback); 311 + } else { 312 + trace_afs_cb_miss(fid, afs_cb_break_for_callback); 313 + } 314 + } 315 + 316 + static void afs_break_some_callbacks(struct afs_server *server, 317 + struct afs_callback_break *cbb, 318 + size_t *_count) 319 + { 320 + struct afs_callback_break *residue = cbb; 321 + struct afs_volume *volume; 322 + afs_volid_t vid = cbb->fid.vid; 323 + size_t i; 324 + 325 + volume = afs_lookup_volume_rcu(server->cell, vid); 91 326 92 327 /* TODO: Find all matching volumes if we couldn't match the server and 93 328 * break them anyway. 94 329 */ 95 - if (!vi) 96 - goto out; 97 330 98 - /* Step through all interested superblocks. There may be more than one 99 - * because of cell aliasing. 100 - */ 101 - hlist_for_each_entry(cbi, &vi->cb_interests, cb_vlink) { 102 - if (fid->vnode == 0 && fid->unique == 0) { 103 - /* The callback break applies to an entire volume. */ 104 - struct afs_super_info *as = AFS_FS_S(cbi->sb); 105 - struct afs_volume *volume = as->volume; 106 - 107 - write_lock(&volume->cb_v_break_lock); 108 - volume->cb_v_break++; 109 - trace_afs_cb_break(fid, volume->cb_v_break, 110 - afs_cb_break_for_volume_callback, false); 111 - write_unlock(&volume->cb_v_break_lock); 331 + for (i = *_count; i > 0; cbb++, i--) { 332 + if (cbb->fid.vid == vid) { 333 + _debug("- Fid { vl=%08llx n=%llu u=%u }", 334 + cbb->fid.vid, 335 + cbb->fid.vnode, 336 + cbb->fid.unique); 337 + --*_count; 338 + if (volume) 339 + afs_break_one_callback(volume, &cbb->fid); 112 340 } else { 113 - data.volume = NULL; 114 - data.fid = *fid; 115 - inode = ilookup5_nowait(cbi->sb, fid->vnode, 116 - afs_iget5_test, &data); 117 - if (inode) { 118 - vnode = AFS_FS_I(inode); 119 - afs_break_callback(vnode, afs_cb_break_for_callback); 120 - iput(inode); 121 - } else { 122 - trace_afs_cb_miss(fid, afs_cb_break_for_callback); 123 - } 341 + *residue++ = *cbb; 124 342 } 125 343 } 126 - 127 - out: 128 - read_unlock(&server->cb_break_lock); 129 344 } 130 345 131 346 /* ··· 178 313 179 314 ASSERT(server != NULL); 180 315 181 - /* TODO: Sort the callback break list by volume ID */ 316 + rcu_read_lock(); 182 317 183 - for (; count > 0; callbacks++, count--) { 184 - _debug("- Fid { vl=%08llx n=%llu u=%u }", 185 - callbacks->fid.vid, 186 - callbacks->fid.vnode, 187 - callbacks->fid.unique); 188 - afs_break_one_callback(server, &callbacks->fid); 189 - } 318 + while (count > 0) 319 + afs_break_some_callbacks(server, callbacks, &count); 190 320 191 - _leave(""); 321 + rcu_read_unlock(); 192 322 return; 193 - } 194 - 195 - /* 196 - * Clear the callback interests in a server list. 197 - */ 198 - void afs_clear_callback_interests(struct afs_net *net, struct afs_server_list *slist) 199 - { 200 - int i; 201 - 202 - for (i = 0; i < slist->nr_servers; i++) { 203 - afs_put_cb_interest(net, slist->servers[i].cb_interest); 204 - slist->servers[i].cb_interest = NULL; 205 - } 206 323 }
+8 -2
fs/afs/cell.c
··· 161 161 162 162 atomic_set(&cell->usage, 2); 163 163 INIT_WORK(&cell->manager, afs_manage_cell); 164 - INIT_LIST_HEAD(&cell->proc_volumes); 165 - rwlock_init(&cell->proc_lock); 164 + cell->volumes = RB_ROOT; 165 + INIT_HLIST_HEAD(&cell->proc_volumes); 166 + seqlock_init(&cell->volume_lock); 167 + cell->fs_servers = RB_ROOT; 168 + seqlock_init(&cell->fs_lock); 166 169 rwlock_init(&cell->vl_servers_lock); 170 + cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS); 167 171 168 172 /* Provide a VL server list, filling it in if we were given a list of 169 173 * addresses to use. ··· 485 481 486 482 ASSERTCMP(atomic_read(&cell->usage), ==, 0); 487 483 484 + afs_put_volume(cell->net, cell->root_volume, afs_volume_trace_put_cell_root); 488 485 afs_put_vlserverlist(cell->net, rcu_access_pointer(cell->vl_servers)); 486 + afs_put_cell(cell->net, cell->alias_of); 489 487 key_put(cell->anonymous_key); 490 488 kfree(cell); 491 489
+11 -56
fs/afs/cmservice.c
··· 118 118 { 119 119 _enter("{%u, CB.OP %u}", call->service_id, call->operation_ID); 120 120 121 - call->epoch = rxrpc_kernel_get_epoch(call->net->socket, call->rxcall); 122 - 123 121 switch (call->operation_ID) { 124 122 case CBCallBack: 125 123 call->type = &afs_SRXCBCallBack; ··· 148 150 } 149 151 150 152 /* 151 - * Record a probe to the cache manager from a server. 152 - */ 153 - static int afs_record_cm_probe(struct afs_call *call, struct afs_server *server) 154 - { 155 - _enter(""); 156 - 157 - if (test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags) && 158 - !test_bit(AFS_SERVER_FL_PROBING, &server->flags)) { 159 - if (server->cm_epoch == call->epoch) 160 - return 0; 161 - 162 - if (!server->probe.said_rebooted) { 163 - pr_notice("kAFS: FS rebooted %pU\n", &server->uuid); 164 - server->probe.said_rebooted = true; 165 - } 166 - } 167 - 168 - spin_lock(&server->probe_lock); 169 - 170 - if (!test_and_set_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) { 171 - server->cm_epoch = call->epoch; 172 - server->probe.cm_epoch = call->epoch; 173 - goto out; 174 - } 175 - 176 - if (server->probe.cm_probed && 177 - call->epoch != server->probe.cm_epoch && 178 - !server->probe.said_inconsistent) { 179 - pr_notice("kAFS: FS endpoints inconsistent %pU\n", 180 - &server->uuid); 181 - server->probe.said_inconsistent = true; 182 - } 183 - 184 - if (!server->probe.cm_probed || call->epoch == server->cm_epoch) 185 - server->probe.cm_epoch = server->cm_epoch; 186 - 187 - out: 188 - server->probe.cm_probed = true; 189 - spin_unlock(&server->probe_lock); 190 - return 0; 191 - } 192 - 193 - /* 194 153 * Find the server record by peer address and record a probe to the cache 195 154 * manager from a server. 196 155 */ ··· 165 210 } 166 211 167 212 call->server = server; 168 - return afs_record_cm_probe(call, server); 213 + return 0; 169 214 } 170 215 171 216 /* ··· 186 231 } 187 232 188 233 call->server = server; 189 - return afs_record_cm_probe(call, server); 234 + return 0; 190 235 } 191 236 192 237 /* ··· 223 268 * to maintain cache coherency. 224 269 */ 225 270 if (call->server) { 226 - trace_afs_server(call->server, atomic_read(&call->server->usage), 271 + trace_afs_server(call->server, 272 + atomic_read(&call->server->ref), 273 + atomic_read(&call->server->active), 227 274 afs_server_trace_callback); 228 275 afs_break_callbacks(call->server, call->count, call->request); 229 276 } ··· 262 305 call->count = ntohl(call->tmp); 263 306 _debug("FID count: %u", call->count); 264 307 if (call->count > AFSCBMAX) 265 - return afs_protocol_error(call, -EBADMSG, 266 - afs_eproto_cb_fid_count); 308 + return afs_protocol_error(call, afs_eproto_cb_fid_count); 267 309 268 310 call->buffer = kmalloc(array3_size(call->count, 3, 4), 269 311 GFP_KERNEL); ··· 307 351 call->count2 = ntohl(call->tmp); 308 352 _debug("CB count: %u", call->count2); 309 353 if (call->count2 != call->count && call->count2 != 0) 310 - return afs_protocol_error(call, -EBADMSG, 311 - afs_eproto_cb_count); 354 + return afs_protocol_error(call, afs_eproto_cb_count); 312 355 call->iter = &call->def_iter; 313 356 iov_iter_discard(&call->def_iter, READ, call->count2 * 3 * 4); 314 357 call->unmarshall++; ··· 464 509 } 465 510 466 511 /* 467 - * allow the fileserver to quickly find out if the fileserver has been rebooted 512 + * Allow the fileserver to quickly find out if the cache manager has been 513 + * rebooted. 468 514 */ 469 515 static void SRXAFSCB_ProbeUuid(struct work_struct *work) 470 516 { ··· 537 581 538 582 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 539 583 return afs_io_error(call, afs_io_error_cm_reply); 540 - return afs_find_cm_server_by_uuid(call, call->request); 584 + return afs_find_cm_server_by_peer(call); 541 585 } 542 586 543 587 /* ··· 628 672 call->count = ntohl(call->tmp); 629 673 _debug("FID count: %u", call->count); 630 674 if (call->count > YFSCBMAX) 631 - return afs_protocol_error(call, -EBADMSG, 632 - afs_eproto_cb_fid_count); 675 + return afs_protocol_error(call, afs_eproto_cb_fid_count); 633 676 634 677 size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid)); 635 678 call->buffer = kmalloc(size, GFP_KERNEL);
+582 -675
fs/afs/dir.c
··· 99 99 bool found; 100 100 bool one_only; 101 101 unsigned short nr_fids; 102 - struct inode **inodes; 103 - struct afs_status_cb *statuses; 104 102 struct afs_fid fids[50]; 105 103 }; 106 104 ··· 616 618 } 617 619 } else if (cookie->name.len == nlen && 618 620 memcmp(cookie->name.name, name, nlen) == 0) { 619 - cookie->fids[0].vnode = ino; 620 - cookie->fids[0].unique = dtype; 621 + cookie->fids[1].vnode = ino; 622 + cookie->fids[1].unique = dtype; 621 623 cookie->found = 1; 622 624 if (cookie->one_only) 623 625 return -1; ··· 625 627 626 628 ret = cookie->nr_fids >= 50 ? -1 : 0; 627 629 _leave(" = %d", ret); 630 + return ret; 631 + } 632 + 633 + /* 634 + * Deal with the result of a successful lookup operation. Turn all the files 635 + * into inodes and save the first one - which is the one we actually want. 636 + */ 637 + static void afs_do_lookup_success(struct afs_operation *op) 638 + { 639 + struct afs_vnode_param *vp; 640 + struct afs_vnode *vnode; 641 + struct inode *inode; 642 + u32 abort_code; 643 + int i; 644 + 645 + _enter(""); 646 + 647 + for (i = 0; i < op->nr_files; i++) { 648 + switch (i) { 649 + case 0: 650 + vp = &op->file[0]; 651 + abort_code = vp->scb.status.abort_code; 652 + if (abort_code != 0) { 653 + op->abort_code = abort_code; 654 + op->error = afs_abort_to_error(abort_code); 655 + } 656 + break; 657 + 658 + case 1: 659 + vp = &op->file[1]; 660 + break; 661 + 662 + default: 663 + vp = &op->more_files[i - 2]; 664 + break; 665 + } 666 + 667 + if (!vp->scb.have_status && !vp->scb.have_error) 668 + continue; 669 + 670 + _debug("do [%u]", i); 671 + if (vp->vnode) { 672 + if (!test_bit(AFS_VNODE_UNSET, &vp->vnode->flags)) 673 + afs_vnode_commit_status(op, vp); 674 + } else if (vp->scb.status.abort_code == 0) { 675 + inode = afs_iget(op, vp); 676 + if (!IS_ERR(inode)) { 677 + vnode = AFS_FS_I(inode); 678 + afs_cache_permit(vnode, op->key, 679 + 0 /* Assume vnode->cb_break is 0 */ + 680 + op->cb_v_break, 681 + &vp->scb); 682 + vp->vnode = vnode; 683 + vp->put_vnode = true; 684 + } 685 + } else { 686 + _debug("- abort %d %llx:%llx.%x", 687 + vp->scb.status.abort_code, 688 + vp->fid.vid, vp->fid.vnode, vp->fid.unique); 689 + } 690 + } 691 + 692 + _leave(""); 693 + } 694 + 695 + static const struct afs_operation_ops afs_inline_bulk_status_operation = { 696 + .issue_afs_rpc = afs_fs_inline_bulk_status, 697 + .issue_yfs_rpc = yfs_fs_inline_bulk_status, 698 + .success = afs_do_lookup_success, 699 + }; 700 + 701 + static const struct afs_operation_ops afs_fetch_status_operation = { 702 + .issue_afs_rpc = afs_fs_fetch_status, 703 + .issue_yfs_rpc = yfs_fs_fetch_status, 704 + .success = afs_do_lookup_success, 705 + }; 706 + 707 + /* 708 + * See if we know that the server we expect to use doesn't support 709 + * FS.InlineBulkStatus. 710 + */ 711 + static bool afs_server_supports_ibulk(struct afs_vnode *dvnode) 712 + { 713 + struct afs_server_list *slist; 714 + struct afs_volume *volume = dvnode->volume; 715 + struct afs_server *server; 716 + bool ret = true; 717 + int i; 718 + 719 + if (!test_bit(AFS_VOLUME_MAYBE_NO_IBULK, &volume->flags)) 720 + return true; 721 + 722 + rcu_read_lock(); 723 + slist = rcu_dereference(volume->servers); 724 + 725 + for (i = 0; i < slist->nr_servers; i++) { 726 + server = slist->servers[i].server; 727 + if (server == dvnode->cb_server) { 728 + if (test_bit(AFS_SERVER_FL_NO_IBULK, &server->flags)) 729 + ret = false; 730 + break; 731 + } 732 + } 733 + 734 + rcu_read_unlock(); 628 735 return ret; 629 736 } 630 737 ··· 742 639 struct key *key) 743 640 { 744 641 struct afs_lookup_cookie *cookie; 745 - struct afs_cb_interest *dcbi, *cbi = NULL; 746 - struct afs_super_info *as = dir->i_sb->s_fs_info; 747 - struct afs_status_cb *scb; 748 - struct afs_iget_data iget_data; 749 - struct afs_fs_cursor fc; 750 - struct afs_server *server; 642 + struct afs_vnode_param *vp; 643 + struct afs_operation *op; 751 644 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; 752 645 struct inode *inode = NULL, *ti; 753 646 afs_dataversion_t data_version = READ_ONCE(dvnode->status.data_version); 754 - int ret, i; 647 + long ret; 648 + int i; 755 649 756 650 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); 757 651 ··· 756 656 if (!cookie) 757 657 return ERR_PTR(-ENOMEM); 758 658 659 + for (i = 0; i < ARRAY_SIZE(cookie->fids); i++) 660 + cookie->fids[i].vid = dvnode->fid.vid; 759 661 cookie->ctx.actor = afs_lookup_filldir; 760 662 cookie->name = dentry->d_name; 761 - cookie->nr_fids = 1; /* slot 0 is saved for the fid we actually want */ 663 + cookie->nr_fids = 2; /* slot 0 is saved for the fid we actually want 664 + * and slot 1 for the directory */ 762 665 763 - read_seqlock_excl(&dvnode->cb_lock); 764 - dcbi = rcu_dereference_protected(dvnode->cb_interest, 765 - lockdep_is_held(&dvnode->cb_lock.lock)); 766 - if (dcbi) { 767 - server = dcbi->server; 768 - if (server && 769 - test_bit(AFS_SERVER_FL_NO_IBULK, &server->flags)) 770 - cookie->one_only = true; 771 - } 772 - read_sequnlock_excl(&dvnode->cb_lock); 773 - 774 - for (i = 0; i < 50; i++) 775 - cookie->fids[i].vid = as->volume->vid; 666 + if (!afs_server_supports_ibulk(dvnode)) 667 + cookie->one_only = true; 776 668 777 669 /* search the directory */ 778 670 ret = afs_dir_iterate(dir, &cookie->ctx, key, &data_version); 779 - if (ret < 0) { 780 - inode = ERR_PTR(ret); 671 + if (ret < 0) 781 672 goto out; 782 - } 783 673 784 674 dentry->d_fsdata = (void *)(unsigned long)data_version; 785 675 786 - inode = ERR_PTR(-ENOENT); 676 + ret = -ENOENT; 787 677 if (!cookie->found) 788 678 goto out; 789 679 790 680 /* Check to see if we already have an inode for the primary fid. */ 791 - iget_data.fid = cookie->fids[0]; 792 - iget_data.volume = dvnode->volume; 793 - iget_data.cb_v_break = dvnode->volume->cb_v_break; 794 - iget_data.cb_s_break = 0; 795 - inode = ilookup5(dir->i_sb, cookie->fids[0].vnode, 796 - afs_iget5_test, &iget_data); 681 + inode = ilookup5(dir->i_sb, cookie->fids[1].vnode, 682 + afs_ilookup5_test_by_fid, &cookie->fids[1]); 797 683 if (inode) 684 + goto out; /* We do */ 685 + 686 + /* Okay, we didn't find it. We need to query the server - and whilst 687 + * we're doing that, we're going to attempt to look up a bunch of other 688 + * vnodes also. 689 + */ 690 + op = afs_alloc_operation(NULL, dvnode->volume); 691 + if (IS_ERR(op)) { 692 + ret = PTR_ERR(op); 798 693 goto out; 694 + } 695 + 696 + afs_op_set_vnode(op, 0, dvnode); 697 + afs_op_set_fid(op, 1, &cookie->fids[1]); 698 + 699 + op->nr_files = cookie->nr_fids; 700 + _debug("nr_files %u", op->nr_files); 799 701 800 702 /* Need space for examining all the selected files */ 801 - inode = ERR_PTR(-ENOMEM); 802 - cookie->statuses = kvcalloc(cookie->nr_fids, sizeof(struct afs_status_cb), 803 - GFP_KERNEL); 804 - if (!cookie->statuses) 805 - goto out; 703 + op->error = -ENOMEM; 704 + if (op->nr_files > 2) { 705 + op->more_files = kvcalloc(op->nr_files - 2, 706 + sizeof(struct afs_vnode_param), 707 + GFP_KERNEL); 708 + if (!op->more_files) 709 + goto out_op; 806 710 807 - cookie->inodes = kcalloc(cookie->nr_fids, sizeof(struct inode *), 808 - GFP_KERNEL); 809 - if (!cookie->inodes) 810 - goto out_s; 711 + for (i = 2; i < op->nr_files; i++) { 712 + vp = &op->more_files[i - 2]; 713 + vp->fid = cookie->fids[i]; 811 714 812 - for (i = 1; i < cookie->nr_fids; i++) { 813 - scb = &cookie->statuses[i]; 814 - 815 - /* Find any inodes that already exist and get their 816 - * callback counters. 817 - */ 818 - iget_data.fid = cookie->fids[i]; 819 - ti = ilookup5_nowait(dir->i_sb, iget_data.fid.vnode, 820 - afs_iget5_test, &iget_data); 821 - if (!IS_ERR_OR_NULL(ti)) { 822 - vnode = AFS_FS_I(ti); 823 - scb->cb_break = afs_calc_vnode_cb_break(vnode); 824 - cookie->inodes[i] = ti; 715 + /* Find any inodes that already exist and get their 716 + * callback counters. 717 + */ 718 + ti = ilookup5_nowait(dir->i_sb, vp->fid.vnode, 719 + afs_ilookup5_test_by_fid, &vp->fid); 720 + if (!IS_ERR_OR_NULL(ti)) { 721 + vnode = AFS_FS_I(ti); 722 + vp->dv_before = vnode->status.data_version; 723 + vp->cb_break_before = afs_calc_vnode_cb_break(vnode); 724 + vp->vnode = vnode; 725 + vp->put_vnode = true; 726 + } 825 727 } 826 728 } 827 729 ··· 831 729 * lookups contained therein are stored in the reply without aborting 832 730 * the whole operation. 833 731 */ 834 - if (cookie->one_only) 835 - goto no_inline_bulk_status; 836 - 837 - inode = ERR_PTR(-ERESTARTSYS); 838 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 839 - while (afs_select_fileserver(&fc)) { 840 - if (test_bit(AFS_SERVER_FL_NO_IBULK, 841 - &fc.cbi->server->flags)) { 842 - fc.ac.abort_code = RX_INVALID_OPERATION; 843 - fc.ac.error = -ECONNABORTED; 844 - break; 845 - } 846 - iget_data.cb_v_break = dvnode->volume->cb_v_break; 847 - iget_data.cb_s_break = fc.cbi->server->cb_s_break; 848 - afs_fs_inline_bulk_status(&fc, 849 - afs_v2net(dvnode), 850 - cookie->fids, 851 - cookie->statuses, 852 - cookie->nr_fids, NULL); 853 - } 854 - 855 - if (fc.ac.error == 0) 856 - cbi = afs_get_cb_interest(fc.cbi); 857 - if (fc.ac.abort_code == RX_INVALID_OPERATION) 858 - set_bit(AFS_SERVER_FL_NO_IBULK, &fc.cbi->server->flags); 859 - inode = ERR_PTR(afs_end_vnode_operation(&fc)); 732 + op->error = -ENOTSUPP; 733 + if (!cookie->one_only) { 734 + op->ops = &afs_inline_bulk_status_operation; 735 + afs_begin_vnode_operation(op); 736 + afs_wait_for_operation(op); 860 737 } 861 738 862 - if (!IS_ERR(inode)) 863 - goto success; 864 - if (fc.ac.abort_code != RX_INVALID_OPERATION) 865 - goto out_c; 739 + if (op->error == -ENOTSUPP) { 740 + /* We could try FS.BulkStatus next, but this aborts the entire 741 + * op if any of the lookups fails - so, for the moment, revert 742 + * to FS.FetchStatus for op->file[1]. 743 + */ 744 + op->fetch_status.which = 1; 745 + op->ops = &afs_fetch_status_operation; 746 + afs_begin_vnode_operation(op); 747 + afs_wait_for_operation(op); 748 + } 749 + inode = ERR_PTR(op->error); 866 750 867 - no_inline_bulk_status: 868 - /* We could try FS.BulkStatus next, but this aborts the entire op if 869 - * any of the lookups fails - so, for the moment, revert to 870 - * FS.FetchStatus for just the primary fid. 871 - */ 872 - inode = ERR_PTR(-ERESTARTSYS); 873 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 874 - while (afs_select_fileserver(&fc)) { 875 - iget_data.cb_v_break = dvnode->volume->cb_v_break; 876 - iget_data.cb_s_break = fc.cbi->server->cb_s_break; 877 - scb = &cookie->statuses[0]; 878 - afs_fs_fetch_status(&fc, 879 - afs_v2net(dvnode), 880 - cookie->fids, 881 - scb, 882 - NULL); 883 - } 884 - 885 - if (fc.ac.error == 0) 886 - cbi = afs_get_cb_interest(fc.cbi); 887 - inode = ERR_PTR(afs_end_vnode_operation(&fc)); 751 + out_op: 752 + if (op->error == 0) { 753 + inode = &op->file[1].vnode->vfs_inode; 754 + op->file[1].vnode = NULL; 888 755 } 889 756 890 - if (IS_ERR(inode)) 891 - goto out_c; 892 - 893 - success: 894 - /* Turn all the files into inodes and save the first one - which is the 895 - * one we actually want. 896 - */ 897 - scb = &cookie->statuses[0]; 898 - if (scb->status.abort_code != 0) 899 - inode = ERR_PTR(afs_abort_to_error(scb->status.abort_code)); 900 - 901 - for (i = 0; i < cookie->nr_fids; i++) { 902 - struct afs_status_cb *scb = &cookie->statuses[i]; 903 - 904 - if (!scb->have_status && !scb->have_error) 905 - continue; 906 - 907 - if (cookie->inodes[i]) { 908 - struct afs_vnode *iv = AFS_FS_I(cookie->inodes[i]); 909 - 910 - if (test_bit(AFS_VNODE_UNSET, &iv->flags)) 911 - continue; 912 - 913 - afs_vnode_commit_status(&fc, iv, 914 - scb->cb_break, NULL, scb); 915 - continue; 916 - } 917 - 918 - if (scb->status.abort_code != 0) 919 - continue; 920 - 921 - iget_data.fid = cookie->fids[i]; 922 - ti = afs_iget(dir->i_sb, key, &iget_data, scb, cbi, dvnode); 923 - if (!IS_ERR(ti)) 924 - afs_cache_permit(AFS_FS_I(ti), key, 925 - 0 /* Assume vnode->cb_break is 0 */ + 926 - iget_data.cb_v_break, 927 - scb); 928 - if (i == 0) { 929 - inode = ti; 930 - } else { 931 - if (!IS_ERR(ti)) 932 - iput(ti); 933 - } 934 - } 935 - 936 - out_c: 937 - afs_put_cb_interest(afs_v2net(dvnode), cbi); 938 - if (cookie->inodes) { 939 - for (i = 0; i < cookie->nr_fids; i++) 940 - iput(cookie->inodes[i]); 941 - kfree(cookie->inodes); 942 - } 943 - out_s: 944 - kvfree(cookie->statuses); 757 + if (op->file[0].scb.have_status) 758 + dentry->d_fsdata = (void *)(unsigned long)op->file[0].scb.status.data_version; 759 + else 760 + dentry->d_fsdata = (void *)(unsigned long)op->file[0].dv_before; 761 + ret = afs_put_operation(op); 945 762 out: 946 763 kfree(cookie); 947 - return inode; 764 + _leave(""); 765 + return inode ?: ERR_PTR(ret); 948 766 } 949 767 950 768 /* ··· 980 958 if (!IS_ERR_OR_NULL(inode)) 981 959 fid = AFS_FS_I(inode)->fid; 982 960 961 + _debug("splice %px", dentry->d_inode); 983 962 d = d_splice_alias(inode, dentry); 984 963 if (!IS_ERR_OR_NULL(d)) { 985 964 d->d_fsdata = dentry->d_fsdata; ··· 988 965 } else { 989 966 trace_afs_lookup(dvnode, &dentry->d_name, &fid); 990 967 } 968 + _leave(""); 991 969 return d; 992 970 } 993 971 ··· 1239 1215 /* 1240 1216 * Create a new inode for create/mkdir/symlink 1241 1217 */ 1242 - static void afs_vnode_new_inode(struct afs_fs_cursor *fc, 1243 - struct dentry *new_dentry, 1244 - struct afs_iget_data *new_data, 1245 - struct afs_status_cb *new_scb) 1218 + static void afs_vnode_new_inode(struct afs_operation *op) 1246 1219 { 1220 + struct afs_vnode_param *vp = &op->file[1]; 1247 1221 struct afs_vnode *vnode; 1248 1222 struct inode *inode; 1249 1223 1250 - if (fc->ac.error < 0) 1251 - return; 1224 + _enter(""); 1252 1225 1253 - inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, 1254 - new_data, new_scb, fc->cbi, fc->vnode); 1226 + ASSERTCMP(op->error, ==, 0); 1227 + 1228 + inode = afs_iget(op, vp); 1255 1229 if (IS_ERR(inode)) { 1256 1230 /* ENOMEM or EINTR at a really inconvenient time - just abandon 1257 1231 * the new directory on the server. 1258 1232 */ 1259 - fc->ac.error = PTR_ERR(inode); 1233 + op->error = PTR_ERR(inode); 1260 1234 return; 1261 1235 } 1262 1236 1263 1237 vnode = AFS_FS_I(inode); 1264 1238 set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 1265 - if (fc->ac.error == 0) 1266 - afs_cache_permit(vnode, fc->key, vnode->cb_break, new_scb); 1267 - d_instantiate(new_dentry, inode); 1239 + if (!op->error) 1240 + afs_cache_permit(vnode, op->key, vnode->cb_break, &vp->scb); 1241 + d_instantiate(op->dentry, inode); 1268 1242 } 1269 1243 1270 - static void afs_prep_for_new_inode(struct afs_fs_cursor *fc, 1271 - struct afs_iget_data *iget_data) 1244 + static void afs_create_success(struct afs_operation *op) 1272 1245 { 1273 - iget_data->volume = fc->vnode->volume; 1274 - iget_data->cb_v_break = fc->vnode->volume->cb_v_break; 1275 - iget_data->cb_s_break = fc->cbi->server->cb_s_break; 1246 + _enter("op=%08x", op->debug_id); 1247 + afs_check_for_remote_deletion(op, op->file[0].vnode); 1248 + afs_vnode_commit_status(op, &op->file[0]); 1249 + afs_update_dentry_version(op, &op->file[0], op->dentry); 1250 + afs_vnode_new_inode(op); 1276 1251 } 1277 1252 1278 - /* 1279 - * Note that a dentry got changed. We need to set d_fsdata to the data version 1280 - * number derived from the result of the operation. It doesn't matter if 1281 - * d_fsdata goes backwards as we'll just revalidate. 1282 - */ 1283 - static void afs_update_dentry_version(struct afs_fs_cursor *fc, 1284 - struct dentry *dentry, 1285 - struct afs_status_cb *scb) 1253 + static void afs_create_edit_dir(struct afs_operation *op) 1286 1254 { 1287 - if (fc->ac.error == 0) 1288 - dentry->d_fsdata = 1289 - (void *)(unsigned long)scb->status.data_version; 1255 + struct afs_vnode_param *dvp = &op->file[0]; 1256 + struct afs_vnode_param *vp = &op->file[1]; 1257 + struct afs_vnode *dvnode = dvp->vnode; 1258 + 1259 + _enter("op=%08x", op->debug_id); 1260 + 1261 + down_write(&dvnode->validate_lock); 1262 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1263 + dvnode->status.data_version == dvp->dv_before + dvp->dv_delta) 1264 + afs_edit_dir_add(dvnode, &op->dentry->d_name, &vp->fid, 1265 + op->create.reason); 1266 + up_write(&dvnode->validate_lock); 1290 1267 } 1268 + 1269 + static void afs_create_put(struct afs_operation *op) 1270 + { 1271 + _enter("op=%08x", op->debug_id); 1272 + 1273 + if (op->error) 1274 + d_drop(op->dentry); 1275 + } 1276 + 1277 + static const struct afs_operation_ops afs_mkdir_operation = { 1278 + .issue_afs_rpc = afs_fs_make_dir, 1279 + .issue_yfs_rpc = yfs_fs_make_dir, 1280 + .success = afs_create_success, 1281 + .edit_dir = afs_create_edit_dir, 1282 + .put = afs_create_put, 1283 + }; 1291 1284 1292 1285 /* 1293 1286 * create a directory on an AFS filesystem 1294 1287 */ 1295 1288 static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 1296 1289 { 1297 - struct afs_iget_data iget_data; 1298 - struct afs_status_cb *scb; 1299 - struct afs_fs_cursor fc; 1290 + struct afs_operation *op; 1300 1291 struct afs_vnode *dvnode = AFS_FS_I(dir); 1301 - struct key *key; 1302 - afs_dataversion_t data_version; 1303 - int ret; 1304 - 1305 - mode |= S_IFDIR; 1306 1292 1307 1293 _enter("{%llx:%llu},{%pd},%ho", 1308 1294 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode); 1309 1295 1310 - ret = -ENOMEM; 1311 - scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL); 1312 - if (!scb) 1313 - goto error; 1314 - 1315 - key = afs_request_key(dvnode->volume->cell); 1316 - if (IS_ERR(key)) { 1317 - ret = PTR_ERR(key); 1318 - goto error_scb; 1296 + op = afs_alloc_operation(NULL, dvnode->volume); 1297 + if (IS_ERR(op)) { 1298 + d_drop(dentry); 1299 + return PTR_ERR(op); 1319 1300 } 1320 1301 1321 - ret = -ERESTARTSYS; 1322 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 1323 - data_version = dvnode->status.data_version + 1; 1324 - 1325 - while (afs_select_fileserver(&fc)) { 1326 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1327 - afs_prep_for_new_inode(&fc, &iget_data); 1328 - afs_fs_create(&fc, dentry->d_name.name, mode, 1329 - &scb[0], &iget_data.fid, &scb[1]); 1330 - } 1331 - 1332 - afs_check_for_remote_deletion(&fc, dvnode); 1333 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1334 - &data_version, &scb[0]); 1335 - afs_update_dentry_version(&fc, dentry, &scb[0]); 1336 - afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); 1337 - ret = afs_end_vnode_operation(&fc); 1338 - if (ret < 0) 1339 - goto error_key; 1340 - } else { 1341 - goto error_key; 1342 - } 1343 - 1344 - if (ret == 0) { 1345 - down_write(&dvnode->validate_lock); 1346 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1347 - dvnode->status.data_version == data_version) 1348 - afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, 1349 - afs_edit_dir_for_create); 1350 - up_write(&dvnode->validate_lock); 1351 - } 1352 - 1353 - key_put(key); 1354 - kfree(scb); 1355 - _leave(" = 0"); 1356 - return 0; 1357 - 1358 - error_key: 1359 - key_put(key); 1360 - error_scb: 1361 - kfree(scb); 1362 - error: 1363 - d_drop(dentry); 1364 - _leave(" = %d", ret); 1365 - return ret; 1302 + afs_op_set_vnode(op, 0, dvnode); 1303 + op->file[0].dv_delta = 1; 1304 + op->dentry = dentry; 1305 + op->create.mode = S_IFDIR | mode; 1306 + op->create.reason = afs_edit_dir_for_mkdir; 1307 + op->ops = &afs_mkdir_operation; 1308 + return afs_do_sync_operation(op); 1366 1309 } 1367 1310 1368 1311 /* ··· 1347 1356 } 1348 1357 } 1349 1358 1359 + static void afs_rmdir_success(struct afs_operation *op) 1360 + { 1361 + _enter("op=%08x", op->debug_id); 1362 + afs_check_for_remote_deletion(op, op->file[0].vnode); 1363 + afs_vnode_commit_status(op, &op->file[0]); 1364 + afs_update_dentry_version(op, &op->file[0], op->dentry); 1365 + } 1366 + 1367 + static void afs_rmdir_edit_dir(struct afs_operation *op) 1368 + { 1369 + struct afs_vnode_param *dvp = &op->file[0]; 1370 + struct afs_vnode *dvnode = dvp->vnode; 1371 + 1372 + _enter("op=%08x", op->debug_id); 1373 + afs_dir_remove_subdir(op->dentry); 1374 + 1375 + down_write(&dvnode->validate_lock); 1376 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1377 + dvnode->status.data_version == dvp->dv_before + dvp->dv_delta) 1378 + afs_edit_dir_remove(dvnode, &op->dentry->d_name, 1379 + afs_edit_dir_for_rmdir); 1380 + up_write(&dvnode->validate_lock); 1381 + } 1382 + 1383 + static void afs_rmdir_put(struct afs_operation *op) 1384 + { 1385 + _enter("op=%08x", op->debug_id); 1386 + if (op->file[1].vnode) 1387 + up_write(&op->file[1].vnode->rmdir_lock); 1388 + } 1389 + 1390 + static const struct afs_operation_ops afs_rmdir_operation = { 1391 + .issue_afs_rpc = afs_fs_remove_dir, 1392 + .issue_yfs_rpc = yfs_fs_remove_dir, 1393 + .success = afs_rmdir_success, 1394 + .edit_dir = afs_rmdir_edit_dir, 1395 + .put = afs_rmdir_put, 1396 + }; 1397 + 1350 1398 /* 1351 1399 * remove a directory from an AFS filesystem 1352 1400 */ 1353 1401 static int afs_rmdir(struct inode *dir, struct dentry *dentry) 1354 1402 { 1355 - struct afs_status_cb *scb; 1356 - struct afs_fs_cursor fc; 1403 + struct afs_operation *op; 1357 1404 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; 1358 - struct key *key; 1359 - afs_dataversion_t data_version; 1360 1405 int ret; 1361 1406 1362 1407 _enter("{%llx:%llu},{%pd}", 1363 1408 dvnode->fid.vid, dvnode->fid.vnode, dentry); 1364 1409 1365 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 1366 - if (!scb) 1367 - return -ENOMEM; 1410 + op = afs_alloc_operation(NULL, dvnode->volume); 1411 + if (IS_ERR(op)) 1412 + return PTR_ERR(op); 1368 1413 1369 - key = afs_request_key(dvnode->volume->cell); 1370 - if (IS_ERR(key)) { 1371 - ret = PTR_ERR(key); 1372 - goto error; 1373 - } 1414 + afs_op_set_vnode(op, 0, dvnode); 1415 + op->file[0].dv_delta = 1; 1416 + 1417 + op->dentry = dentry; 1418 + op->ops = &afs_rmdir_operation; 1374 1419 1375 1420 /* Try to make sure we have a callback promise on the victim. */ 1376 1421 if (d_really_is_positive(dentry)) { 1377 1422 vnode = AFS_FS_I(d_inode(dentry)); 1378 - ret = afs_validate(vnode, key); 1423 + ret = afs_validate(vnode, op->key); 1379 1424 if (ret < 0) 1380 - goto error_key; 1425 + goto error; 1381 1426 } 1382 1427 1383 1428 if (vnode) { 1384 1429 ret = down_write_killable(&vnode->rmdir_lock); 1385 1430 if (ret < 0) 1386 - goto error_key; 1431 + goto error; 1432 + op->file[1].vnode = vnode; 1387 1433 } 1388 1434 1389 - ret = -ERESTARTSYS; 1390 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 1391 - data_version = dvnode->status.data_version + 1; 1435 + return afs_do_sync_operation(op); 1392 1436 1393 - while (afs_select_fileserver(&fc)) { 1394 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1395 - afs_fs_remove(&fc, vnode, dentry->d_name.name, true, scb); 1396 - } 1397 - 1398 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1399 - &data_version, scb); 1400 - afs_update_dentry_version(&fc, dentry, scb); 1401 - ret = afs_end_vnode_operation(&fc); 1402 - if (ret == 0) { 1403 - afs_dir_remove_subdir(dentry); 1404 - down_write(&dvnode->validate_lock); 1405 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1406 - dvnode->status.data_version == data_version) 1407 - afs_edit_dir_remove(dvnode, &dentry->d_name, 1408 - afs_edit_dir_for_rmdir); 1409 - up_write(&dvnode->validate_lock); 1410 - } 1411 - } 1412 - 1413 - if (vnode) 1414 - up_write(&vnode->rmdir_lock); 1415 - error_key: 1416 - key_put(key); 1417 1437 error: 1418 - kfree(scb); 1419 - return ret; 1438 + return afs_put_operation(op); 1420 1439 } 1421 1440 1422 1441 /* ··· 1439 1438 * However, if we didn't have a callback promise outstanding, or it was 1440 1439 * outstanding on a different server, then it won't break it either... 1441 1440 */ 1442 - static int afs_dir_remove_link(struct afs_vnode *dvnode, struct dentry *dentry, 1443 - struct key *key) 1441 + static void afs_dir_remove_link(struct afs_operation *op) 1444 1442 { 1445 - int ret = 0; 1443 + struct afs_vnode *dvnode = op->file[0].vnode; 1444 + struct afs_vnode *vnode = op->file[1].vnode; 1445 + struct dentry *dentry = op->dentry; 1446 + int ret; 1446 1447 1447 - if (d_really_is_positive(dentry)) { 1448 - struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); 1448 + if (op->error != 0 || 1449 + (op->file[1].scb.have_status && op->file[1].scb.have_error)) 1450 + return; 1451 + if (d_really_is_positive(dentry)) 1452 + return; 1449 1453 1450 - if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 1451 - /* Already done */ 1452 - } else if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { 1453 - write_seqlock(&vnode->cb_lock); 1454 - drop_nlink(&vnode->vfs_inode); 1455 - if (vnode->vfs_inode.i_nlink == 0) { 1456 - set_bit(AFS_VNODE_DELETED, &vnode->flags); 1457 - __afs_break_callback(vnode, afs_cb_break_for_unlink); 1458 - } 1459 - write_sequnlock(&vnode->cb_lock); 1460 - ret = 0; 1461 - } else { 1462 - afs_break_callback(vnode, afs_cb_break_for_unlink); 1463 - 1464 - if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) 1465 - kdebug("AFS_VNODE_DELETED"); 1466 - 1467 - ret = afs_validate(vnode, key); 1468 - if (ret == -ESTALE) 1469 - ret = 0; 1454 + if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 1455 + /* Already done */ 1456 + } else if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { 1457 + write_seqlock(&vnode->cb_lock); 1458 + drop_nlink(&vnode->vfs_inode); 1459 + if (vnode->vfs_inode.i_nlink == 0) { 1460 + set_bit(AFS_VNODE_DELETED, &vnode->flags); 1461 + __afs_break_callback(vnode, afs_cb_break_for_unlink); 1470 1462 } 1471 - _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, ret); 1463 + write_sequnlock(&vnode->cb_lock); 1464 + } else { 1465 + afs_break_callback(vnode, afs_cb_break_for_unlink); 1466 + 1467 + if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) 1468 + _debug("AFS_VNODE_DELETED"); 1469 + 1470 + ret = afs_validate(vnode, op->key); 1471 + if (ret != -ESTALE) 1472 + op->error = ret; 1472 1473 } 1473 1474 1474 - return ret; 1475 + _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, op->error); 1475 1476 } 1477 + 1478 + static void afs_unlink_success(struct afs_operation *op) 1479 + { 1480 + _enter("op=%08x", op->debug_id); 1481 + afs_check_for_remote_deletion(op, op->file[0].vnode); 1482 + afs_vnode_commit_status(op, &op->file[0]); 1483 + afs_vnode_commit_status(op, &op->file[1]); 1484 + afs_update_dentry_version(op, &op->file[0], op->dentry); 1485 + afs_dir_remove_link(op); 1486 + } 1487 + 1488 + static void afs_unlink_edit_dir(struct afs_operation *op) 1489 + { 1490 + struct afs_vnode_param *dvp = &op->file[0]; 1491 + struct afs_vnode *dvnode = dvp->vnode; 1492 + 1493 + _enter("op=%08x", op->debug_id); 1494 + down_write(&dvnode->validate_lock); 1495 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1496 + dvnode->status.data_version == dvp->dv_before + dvp->dv_delta) 1497 + afs_edit_dir_remove(dvnode, &op->dentry->d_name, 1498 + afs_edit_dir_for_unlink); 1499 + up_write(&dvnode->validate_lock); 1500 + } 1501 + 1502 + static void afs_unlink_put(struct afs_operation *op) 1503 + { 1504 + _enter("op=%08x", op->debug_id); 1505 + if (op->unlink.need_rehash && op->error < 0 && op->error != -ENOENT) 1506 + d_rehash(op->dentry); 1507 + } 1508 + 1509 + static const struct afs_operation_ops afs_unlink_operation = { 1510 + .issue_afs_rpc = afs_fs_remove_file, 1511 + .issue_yfs_rpc = yfs_fs_remove_file, 1512 + .success = afs_unlink_success, 1513 + .edit_dir = afs_unlink_edit_dir, 1514 + .put = afs_unlink_put, 1515 + }; 1476 1516 1477 1517 /* 1478 1518 * Remove a file or symlink from an AFS filesystem. 1479 1519 */ 1480 1520 static int afs_unlink(struct inode *dir, struct dentry *dentry) 1481 1521 { 1482 - struct afs_fs_cursor fc; 1483 - struct afs_status_cb *scb; 1522 + struct afs_operation *op; 1484 1523 struct afs_vnode *dvnode = AFS_FS_I(dir); 1485 1524 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); 1486 - struct key *key; 1487 - bool need_rehash = false; 1488 1525 int ret; 1489 1526 1490 1527 _enter("{%llx:%llu},{%pd}", ··· 1531 1492 if (dentry->d_name.len >= AFSNAMEMAX) 1532 1493 return -ENAMETOOLONG; 1533 1494 1534 - ret = -ENOMEM; 1535 - scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL); 1536 - if (!scb) 1537 - goto error; 1495 + op = afs_alloc_operation(NULL, dvnode->volume); 1496 + if (IS_ERR(op)) 1497 + return PTR_ERR(op); 1538 1498 1539 - key = afs_request_key(dvnode->volume->cell); 1540 - if (IS_ERR(key)) { 1541 - ret = PTR_ERR(key); 1542 - goto error_scb; 1543 - } 1499 + afs_op_set_vnode(op, 0, dvnode); 1500 + op->file[0].dv_delta = 1; 1544 1501 1545 1502 /* Try to make sure we have a callback promise on the victim. */ 1546 - ret = afs_validate(vnode, key); 1547 - if (ret < 0) 1548 - goto error_key; 1503 + ret = afs_validate(vnode, op->key); 1504 + if (ret < 0) { 1505 + op->error = ret; 1506 + goto error; 1507 + } 1549 1508 1550 1509 spin_lock(&dentry->d_lock); 1551 1510 if (d_count(dentry) > 1) { 1552 1511 spin_unlock(&dentry->d_lock); 1553 1512 /* Start asynchronous writeout of the inode */ 1554 1513 write_inode_now(d_inode(dentry), 0); 1555 - ret = afs_sillyrename(dvnode, vnode, dentry, key); 1556 - goto error_key; 1514 + op->error = afs_sillyrename(dvnode, vnode, dentry, op->key); 1515 + goto error; 1557 1516 } 1558 1517 if (!d_unhashed(dentry)) { 1559 1518 /* Prevent a race with RCU lookup. */ 1560 1519 __d_drop(dentry); 1561 - need_rehash = true; 1520 + op->unlink.need_rehash = true; 1562 1521 } 1563 1522 spin_unlock(&dentry->d_lock); 1564 1523 1565 - ret = -ERESTARTSYS; 1566 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 1567 - afs_dataversion_t data_version = dvnode->status.data_version + 1; 1568 - afs_dataversion_t data_version_2 = vnode->status.data_version; 1524 + op->file[1].vnode = vnode; 1525 + op->dentry = dentry; 1526 + op->ops = &afs_unlink_operation; 1527 + return afs_do_sync_operation(op); 1569 1528 1570 - while (afs_select_fileserver(&fc)) { 1571 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1572 - fc.cb_break_2 = afs_calc_vnode_cb_break(vnode); 1573 - 1574 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) && 1575 - !test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) { 1576 - yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name, 1577 - &scb[0], &scb[1]); 1578 - if (fc.ac.error != -ECONNABORTED || 1579 - fc.ac.abort_code != RXGEN_OPCODE) 1580 - continue; 1581 - set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags); 1582 - } 1583 - 1584 - afs_fs_remove(&fc, vnode, dentry->d_name.name, false, &scb[0]); 1585 - } 1586 - 1587 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1588 - &data_version, &scb[0]); 1589 - afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, 1590 - &data_version_2, &scb[1]); 1591 - afs_update_dentry_version(&fc, dentry, &scb[0]); 1592 - ret = afs_end_vnode_operation(&fc); 1593 - if (ret == 0 && !(scb[1].have_status || scb[1].have_error)) 1594 - ret = afs_dir_remove_link(dvnode, dentry, key); 1595 - 1596 - if (ret == 0) { 1597 - down_write(&dvnode->validate_lock); 1598 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1599 - dvnode->status.data_version == data_version) 1600 - afs_edit_dir_remove(dvnode, &dentry->d_name, 1601 - afs_edit_dir_for_unlink); 1602 - up_write(&dvnode->validate_lock); 1603 - } 1604 - } 1605 - 1606 - if (need_rehash && ret < 0 && ret != -ENOENT) 1607 - d_rehash(dentry); 1608 - 1609 - error_key: 1610 - key_put(key); 1611 - error_scb: 1612 - kfree(scb); 1613 1529 error: 1614 - _leave(" = %d", ret); 1615 - return ret; 1530 + return afs_put_operation(op); 1616 1531 } 1532 + 1533 + static const struct afs_operation_ops afs_create_operation = { 1534 + .issue_afs_rpc = afs_fs_create_file, 1535 + .issue_yfs_rpc = yfs_fs_create_file, 1536 + .success = afs_create_success, 1537 + .edit_dir = afs_create_edit_dir, 1538 + .put = afs_create_put, 1539 + }; 1617 1540 1618 1541 /* 1619 1542 * create a regular file on an AFS filesystem ··· 1583 1582 static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, 1584 1583 bool excl) 1585 1584 { 1586 - struct afs_iget_data iget_data; 1587 - struct afs_fs_cursor fc; 1588 - struct afs_status_cb *scb; 1585 + struct afs_operation *op; 1589 1586 struct afs_vnode *dvnode = AFS_FS_I(dir); 1590 - struct key *key; 1591 - afs_dataversion_t data_version; 1592 - int ret; 1587 + int ret = -ENAMETOOLONG; 1593 1588 1594 - mode |= S_IFREG; 1595 - 1596 - _enter("{%llx:%llu},{%pd},%ho,", 1589 + _enter("{%llx:%llu},{%pd},%ho", 1597 1590 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode); 1598 1591 1599 - ret = -ENAMETOOLONG; 1600 1592 if (dentry->d_name.len >= AFSNAMEMAX) 1601 1593 goto error; 1602 1594 1603 - key = afs_request_key(dvnode->volume->cell); 1604 - if (IS_ERR(key)) { 1605 - ret = PTR_ERR(key); 1595 + op = afs_alloc_operation(NULL, dvnode->volume); 1596 + if (IS_ERR(op)) { 1597 + ret = PTR_ERR(op); 1606 1598 goto error; 1607 1599 } 1608 1600 1609 - ret = -ENOMEM; 1610 - scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL); 1611 - if (!scb) 1612 - goto error_scb; 1601 + afs_op_set_vnode(op, 0, dvnode); 1602 + op->file[0].dv_delta = 1; 1613 1603 1614 - ret = -ERESTARTSYS; 1615 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 1616 - data_version = dvnode->status.data_version + 1; 1604 + op->dentry = dentry; 1605 + op->create.mode = S_IFREG | mode; 1606 + op->create.reason = afs_edit_dir_for_create; 1607 + op->ops = &afs_create_operation; 1608 + return afs_do_sync_operation(op); 1617 1609 1618 - while (afs_select_fileserver(&fc)) { 1619 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1620 - afs_prep_for_new_inode(&fc, &iget_data); 1621 - afs_fs_create(&fc, dentry->d_name.name, mode, 1622 - &scb[0], &iget_data.fid, &scb[1]); 1623 - } 1624 - 1625 - afs_check_for_remote_deletion(&fc, dvnode); 1626 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1627 - &data_version, &scb[0]); 1628 - afs_update_dentry_version(&fc, dentry, &scb[0]); 1629 - afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); 1630 - ret = afs_end_vnode_operation(&fc); 1631 - if (ret < 0) 1632 - goto error_key; 1633 - } else { 1634 - goto error_key; 1635 - } 1636 - 1637 - down_write(&dvnode->validate_lock); 1638 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1639 - dvnode->status.data_version == data_version) 1640 - afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, 1641 - afs_edit_dir_for_create); 1642 - up_write(&dvnode->validate_lock); 1643 - 1644 - kfree(scb); 1645 - key_put(key); 1646 - _leave(" = 0"); 1647 - return 0; 1648 - 1649 - error_scb: 1650 - kfree(scb); 1651 - error_key: 1652 - key_put(key); 1653 1610 error: 1654 1611 d_drop(dentry); 1655 1612 _leave(" = %d", ret); 1656 1613 return ret; 1657 1614 } 1615 + 1616 + static void afs_link_success(struct afs_operation *op) 1617 + { 1618 + struct afs_vnode_param *dvp = &op->file[0]; 1619 + struct afs_vnode_param *vp = &op->file[1]; 1620 + 1621 + _enter("op=%08x", op->debug_id); 1622 + afs_vnode_commit_status(op, dvp); 1623 + afs_vnode_commit_status(op, vp); 1624 + afs_update_dentry_version(op, dvp, op->dentry); 1625 + if (op->dentry_2->d_parent == op->dentry->d_parent) 1626 + afs_update_dentry_version(op, dvp, op->dentry_2); 1627 + ihold(&vp->vnode->vfs_inode); 1628 + d_instantiate(op->dentry, &vp->vnode->vfs_inode); 1629 + } 1630 + 1631 + static void afs_link_put(struct afs_operation *op) 1632 + { 1633 + _enter("op=%08x", op->debug_id); 1634 + if (op->error) 1635 + d_drop(op->dentry); 1636 + } 1637 + 1638 + static const struct afs_operation_ops afs_link_operation = { 1639 + .issue_afs_rpc = afs_fs_link, 1640 + .issue_yfs_rpc = yfs_fs_link, 1641 + .success = afs_link_success, 1642 + .edit_dir = afs_create_edit_dir, 1643 + .put = afs_link_put, 1644 + }; 1658 1645 1659 1646 /* 1660 1647 * create a hard link between files in an AFS filesystem ··· 1650 1661 static int afs_link(struct dentry *from, struct inode *dir, 1651 1662 struct dentry *dentry) 1652 1663 { 1653 - struct afs_fs_cursor fc; 1654 - struct afs_status_cb *scb; 1664 + struct afs_operation *op; 1655 1665 struct afs_vnode *dvnode = AFS_FS_I(dir); 1656 1666 struct afs_vnode *vnode = AFS_FS_I(d_inode(from)); 1657 - struct key *key; 1658 - afs_dataversion_t data_version; 1659 - int ret; 1667 + int ret = -ENAMETOOLONG; 1660 1668 1661 1669 _enter("{%llx:%llu},{%llx:%llu},{%pd}", 1662 1670 vnode->fid.vid, vnode->fid.vnode, 1663 1671 dvnode->fid.vid, dvnode->fid.vnode, 1664 1672 dentry); 1665 1673 1666 - ret = -ENAMETOOLONG; 1667 1674 if (dentry->d_name.len >= AFSNAMEMAX) 1668 1675 goto error; 1669 1676 1670 - ret = -ENOMEM; 1671 - scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL); 1672 - if (!scb) 1677 + op = afs_alloc_operation(NULL, dvnode->volume); 1678 + if (IS_ERR(op)) { 1679 + ret = PTR_ERR(op); 1673 1680 goto error; 1674 - 1675 - key = afs_request_key(dvnode->volume->cell); 1676 - if (IS_ERR(key)) { 1677 - ret = PTR_ERR(key); 1678 - goto error_scb; 1679 1681 } 1680 1682 1681 - ret = -ERESTARTSYS; 1682 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 1683 - data_version = dvnode->status.data_version + 1; 1683 + afs_op_set_vnode(op, 0, dvnode); 1684 + afs_op_set_vnode(op, 1, vnode); 1685 + op->file[0].dv_delta = 1; 1684 1686 1685 - if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) { 1686 - afs_end_vnode_operation(&fc); 1687 - goto error_key; 1688 - } 1687 + op->dentry = dentry; 1688 + op->dentry_2 = from; 1689 + op->ops = &afs_link_operation; 1690 + op->create.reason = afs_edit_dir_for_link; 1691 + return afs_do_sync_operation(op); 1689 1692 1690 - while (afs_select_fileserver(&fc)) { 1691 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1692 - fc.cb_break_2 = afs_calc_vnode_cb_break(vnode); 1693 - afs_fs_link(&fc, vnode, dentry->d_name.name, 1694 - &scb[0], &scb[1]); 1695 - } 1696 - 1697 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1698 - &data_version, &scb[0]); 1699 - afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, 1700 - NULL, &scb[1]); 1701 - ihold(&vnode->vfs_inode); 1702 - afs_update_dentry_version(&fc, dentry, &scb[0]); 1703 - d_instantiate(dentry, &vnode->vfs_inode); 1704 - 1705 - mutex_unlock(&vnode->io_lock); 1706 - ret = afs_end_vnode_operation(&fc); 1707 - if (ret < 0) 1708 - goto error_key; 1709 - } else { 1710 - goto error_key; 1711 - } 1712 - 1713 - down_write(&dvnode->validate_lock); 1714 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1715 - dvnode->status.data_version == data_version) 1716 - afs_edit_dir_add(dvnode, &dentry->d_name, &vnode->fid, 1717 - afs_edit_dir_for_link); 1718 - up_write(&dvnode->validate_lock); 1719 - 1720 - key_put(key); 1721 - kfree(scb); 1722 - _leave(" = 0"); 1723 - return 0; 1724 - 1725 - error_key: 1726 - key_put(key); 1727 - error_scb: 1728 - kfree(scb); 1729 1693 error: 1730 1694 d_drop(dentry); 1731 1695 _leave(" = %d", ret); 1732 1696 return ret; 1733 1697 } 1698 + 1699 + static const struct afs_operation_ops afs_symlink_operation = { 1700 + .issue_afs_rpc = afs_fs_symlink, 1701 + .issue_yfs_rpc = yfs_fs_symlink, 1702 + .success = afs_create_success, 1703 + .edit_dir = afs_create_edit_dir, 1704 + .put = afs_create_put, 1705 + }; 1734 1706 1735 1707 /* 1736 1708 * create a symlink in an AFS filesystem ··· 1699 1749 static int afs_symlink(struct inode *dir, struct dentry *dentry, 1700 1750 const char *content) 1701 1751 { 1702 - struct afs_iget_data iget_data; 1703 - struct afs_fs_cursor fc; 1704 - struct afs_status_cb *scb; 1752 + struct afs_operation *op; 1705 1753 struct afs_vnode *dvnode = AFS_FS_I(dir); 1706 - struct key *key; 1707 - afs_dataversion_t data_version; 1708 1754 int ret; 1709 1755 1710 1756 _enter("{%llx:%llu},{%pd},%s", ··· 1715 1769 if (strlen(content) >= AFSPATHMAX) 1716 1770 goto error; 1717 1771 1718 - ret = -ENOMEM; 1719 - scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL); 1720 - if (!scb) 1772 + op = afs_alloc_operation(NULL, dvnode->volume); 1773 + if (IS_ERR(op)) { 1774 + ret = PTR_ERR(op); 1721 1775 goto error; 1722 - 1723 - key = afs_request_key(dvnode->volume->cell); 1724 - if (IS_ERR(key)) { 1725 - ret = PTR_ERR(key); 1726 - goto error_scb; 1727 1776 } 1728 1777 1729 - ret = -ERESTARTSYS; 1730 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 1731 - data_version = dvnode->status.data_version + 1; 1778 + afs_op_set_vnode(op, 0, dvnode); 1779 + op->file[0].dv_delta = 1; 1732 1780 1733 - while (afs_select_fileserver(&fc)) { 1734 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1735 - afs_prep_for_new_inode(&fc, &iget_data); 1736 - afs_fs_symlink(&fc, dentry->d_name.name, content, 1737 - &scb[0], &iget_data.fid, &scb[1]); 1738 - } 1781 + op->dentry = dentry; 1782 + op->ops = &afs_symlink_operation; 1783 + op->create.reason = afs_edit_dir_for_symlink; 1784 + op->create.symlink = content; 1785 + return afs_do_sync_operation(op); 1739 1786 1740 - afs_check_for_remote_deletion(&fc, dvnode); 1741 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1742 - &data_version, &scb[0]); 1743 - afs_update_dentry_version(&fc, dentry, &scb[0]); 1744 - afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); 1745 - ret = afs_end_vnode_operation(&fc); 1746 - if (ret < 0) 1747 - goto error_key; 1748 - } else { 1749 - goto error_key; 1750 - } 1751 - 1752 - down_write(&dvnode->validate_lock); 1753 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 1754 - dvnode->status.data_version == data_version) 1755 - afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, 1756 - afs_edit_dir_for_symlink); 1757 - up_write(&dvnode->validate_lock); 1758 - 1759 - key_put(key); 1760 - kfree(scb); 1761 - _leave(" = 0"); 1762 - return 0; 1763 - 1764 - error_key: 1765 - key_put(key); 1766 - error_scb: 1767 - kfree(scb); 1768 1787 error: 1769 1788 d_drop(dentry); 1770 1789 _leave(" = %d", ret); 1771 1790 return ret; 1772 1791 } 1792 + 1793 + static void afs_rename_success(struct afs_operation *op) 1794 + { 1795 + _enter("op=%08x", op->debug_id); 1796 + 1797 + afs_vnode_commit_status(op, &op->file[0]); 1798 + if (op->file[1].vnode != op->file[0].vnode) 1799 + afs_vnode_commit_status(op, &op->file[1]); 1800 + } 1801 + 1802 + static void afs_rename_edit_dir(struct afs_operation *op) 1803 + { 1804 + struct afs_vnode_param *orig_dvp = &op->file[0]; 1805 + struct afs_vnode_param *new_dvp = &op->file[1]; 1806 + struct afs_vnode *orig_dvnode = orig_dvp->vnode; 1807 + struct afs_vnode *new_dvnode = new_dvp->vnode; 1808 + struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry)); 1809 + struct dentry *old_dentry = op->dentry; 1810 + struct dentry *new_dentry = op->dentry_2; 1811 + struct inode *new_inode; 1812 + 1813 + _enter("op=%08x", op->debug_id); 1814 + 1815 + if (op->rename.rehash) { 1816 + d_rehash(op->rename.rehash); 1817 + op->rename.rehash = NULL; 1818 + } 1819 + 1820 + down_write(&orig_dvnode->validate_lock); 1821 + if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) && 1822 + orig_dvnode->status.data_version == orig_dvp->dv_before + orig_dvp->dv_delta) 1823 + afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, 1824 + afs_edit_dir_for_rename_0); 1825 + 1826 + if (new_dvnode != orig_dvnode) { 1827 + up_write(&orig_dvnode->validate_lock); 1828 + down_write(&new_dvnode->validate_lock); 1829 + } 1830 + 1831 + if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) && 1832 + new_dvnode->status.data_version == new_dvp->dv_before + new_dvp->dv_delta) { 1833 + if (!op->rename.new_negative) 1834 + afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, 1835 + afs_edit_dir_for_rename_1); 1836 + 1837 + afs_edit_dir_add(new_dvnode, &new_dentry->d_name, 1838 + &vnode->fid, afs_edit_dir_for_rename_2); 1839 + } 1840 + 1841 + new_inode = d_inode(new_dentry); 1842 + if (new_inode) { 1843 + spin_lock(&new_inode->i_lock); 1844 + if (new_inode->i_nlink > 0) 1845 + drop_nlink(new_inode); 1846 + spin_unlock(&new_inode->i_lock); 1847 + } 1848 + 1849 + /* Now we can update d_fsdata on the dentries to reflect their 1850 + * new parent's data_version. 1851 + * 1852 + * Note that if we ever implement RENAME_EXCHANGE, we'll have 1853 + * to update both dentries with opposing dir versions. 1854 + */ 1855 + afs_update_dentry_version(op, new_dvp, op->dentry); 1856 + afs_update_dentry_version(op, new_dvp, op->dentry_2); 1857 + 1858 + d_move(old_dentry, new_dentry); 1859 + 1860 + up_write(&new_dvnode->validate_lock); 1861 + } 1862 + 1863 + static void afs_rename_put(struct afs_operation *op) 1864 + { 1865 + _enter("op=%08x", op->debug_id); 1866 + if (op->rename.rehash) 1867 + d_rehash(op->rename.rehash); 1868 + dput(op->rename.tmp); 1869 + if (op->error) 1870 + d_rehash(op->dentry); 1871 + } 1872 + 1873 + static const struct afs_operation_ops afs_rename_operation = { 1874 + .issue_afs_rpc = afs_fs_rename, 1875 + .issue_yfs_rpc = yfs_fs_rename, 1876 + .success = afs_rename_success, 1877 + .edit_dir = afs_rename_edit_dir, 1878 + .put = afs_rename_put, 1879 + }; 1773 1880 1774 1881 /* 1775 1882 * rename a file in an AFS filesystem and/or move it between directories ··· 1831 1832 struct inode *new_dir, struct dentry *new_dentry, 1832 1833 unsigned int flags) 1833 1834 { 1834 - struct afs_fs_cursor fc; 1835 - struct afs_status_cb *scb; 1835 + struct afs_operation *op; 1836 1836 struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; 1837 - struct dentry *tmp = NULL, *rehash = NULL; 1838 - struct inode *new_inode; 1839 - struct key *key; 1840 - afs_dataversion_t orig_data_version; 1841 - afs_dataversion_t new_data_version; 1842 - bool new_negative = d_is_negative(new_dentry); 1843 1837 int ret; 1844 1838 1845 1839 if (flags) ··· 1852 1860 new_dvnode->fid.vid, new_dvnode->fid.vnode, 1853 1861 new_dentry); 1854 1862 1855 - ret = -ENOMEM; 1856 - scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL); 1857 - if (!scb) 1858 - goto error; 1863 + op = afs_alloc_operation(NULL, orig_dvnode->volume); 1864 + if (IS_ERR(op)) 1865 + return PTR_ERR(op); 1859 1866 1860 - key = afs_request_key(orig_dvnode->volume->cell); 1861 - if (IS_ERR(key)) { 1862 - ret = PTR_ERR(key); 1863 - goto error_scb; 1864 - } 1867 + afs_op_set_vnode(op, 0, orig_dvnode); 1868 + afs_op_set_vnode(op, 1, new_dvnode); /* May be same as orig_dvnode */ 1869 + op->file[0].dv_delta = 1; 1870 + op->file[1].dv_delta = 1; 1871 + 1872 + op->dentry = old_dentry; 1873 + op->dentry_2 = new_dentry; 1874 + op->rename.new_negative = d_is_negative(new_dentry); 1875 + op->ops = &afs_rename_operation; 1865 1876 1866 1877 /* For non-directories, check whether the target is busy and if so, 1867 1878 * make a copy of the dentry and then do a silly-rename. If the ··· 1877 1882 */ 1878 1883 if (!d_unhashed(new_dentry)) { 1879 1884 d_drop(new_dentry); 1880 - rehash = new_dentry; 1885 + op->rename.rehash = new_dentry; 1881 1886 } 1882 1887 1883 1888 if (d_count(new_dentry) > 2) { 1884 1889 /* copy the target dentry's name */ 1885 1890 ret = -ENOMEM; 1886 - tmp = d_alloc(new_dentry->d_parent, 1887 - &new_dentry->d_name); 1888 - if (!tmp) 1889 - goto error_rehash; 1891 + op->rename.tmp = d_alloc(new_dentry->d_parent, 1892 + &new_dentry->d_name); 1893 + if (!op->rename.tmp) 1894 + goto error; 1890 1895 1891 1896 ret = afs_sillyrename(new_dvnode, 1892 1897 AFS_FS_I(d_inode(new_dentry)), 1893 - new_dentry, key); 1898 + new_dentry, op->key); 1894 1899 if (ret) 1895 - goto error_rehash; 1900 + goto error; 1896 1901 1897 - new_dentry = tmp; 1898 - rehash = NULL; 1899 - new_negative = true; 1902 + op->dentry_2 = op->rename.tmp; 1903 + op->rename.rehash = NULL; 1904 + op->rename.new_negative = true; 1900 1905 } 1901 1906 } 1902 1907 ··· 1911 1916 */ 1912 1917 d_drop(old_dentry); 1913 1918 1914 - ret = -ERESTARTSYS; 1915 - if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { 1916 - orig_data_version = orig_dvnode->status.data_version + 1; 1919 + return afs_do_sync_operation(op); 1917 1920 1918 - if (orig_dvnode != new_dvnode) { 1919 - if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) { 1920 - afs_end_vnode_operation(&fc); 1921 - goto error_rehash_old; 1922 - } 1923 - new_data_version = new_dvnode->status.data_version + 1; 1924 - } else { 1925 - new_data_version = orig_data_version; 1926 - } 1927 - 1928 - while (afs_select_fileserver(&fc)) { 1929 - fc.cb_break = afs_calc_vnode_cb_break(orig_dvnode); 1930 - fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode); 1931 - afs_fs_rename(&fc, old_dentry->d_name.name, 1932 - new_dvnode, new_dentry->d_name.name, 1933 - &scb[0], &scb[1]); 1934 - } 1935 - 1936 - afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break, 1937 - &orig_data_version, &scb[0]); 1938 - if (new_dvnode != orig_dvnode) { 1939 - afs_vnode_commit_status(&fc, new_dvnode, fc.cb_break_2, 1940 - &new_data_version, &scb[1]); 1941 - mutex_unlock(&new_dvnode->io_lock); 1942 - } 1943 - ret = afs_end_vnode_operation(&fc); 1944 - if (ret < 0) 1945 - goto error_rehash_old; 1946 - } 1947 - 1948 - if (ret == 0) { 1949 - if (rehash) 1950 - d_rehash(rehash); 1951 - down_write(&orig_dvnode->validate_lock); 1952 - if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) && 1953 - orig_dvnode->status.data_version == orig_data_version) 1954 - afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, 1955 - afs_edit_dir_for_rename_0); 1956 - if (orig_dvnode != new_dvnode) { 1957 - up_write(&orig_dvnode->validate_lock); 1958 - 1959 - down_write(&new_dvnode->validate_lock); 1960 - } 1961 - if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) && 1962 - orig_dvnode->status.data_version == new_data_version) { 1963 - if (!new_negative) 1964 - afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, 1965 - afs_edit_dir_for_rename_1); 1966 - 1967 - afs_edit_dir_add(new_dvnode, &new_dentry->d_name, 1968 - &vnode->fid, afs_edit_dir_for_rename_2); 1969 - } 1970 - 1971 - new_inode = d_inode(new_dentry); 1972 - if (new_inode) { 1973 - spin_lock(&new_inode->i_lock); 1974 - if (new_inode->i_nlink > 0) 1975 - drop_nlink(new_inode); 1976 - spin_unlock(&new_inode->i_lock); 1977 - } 1978 - 1979 - /* Now we can update d_fsdata on the dentries to reflect their 1980 - * new parent's data_version. 1981 - * 1982 - * Note that if we ever implement RENAME_EXCHANGE, we'll have 1983 - * to update both dentries with opposing dir versions. 1984 - */ 1985 - afs_update_dentry_version(&fc, old_dentry, &scb[1]); 1986 - afs_update_dentry_version(&fc, new_dentry, &scb[1]); 1987 - d_move(old_dentry, new_dentry); 1988 - up_write(&new_dvnode->validate_lock); 1989 - goto error_tmp; 1990 - } 1991 - 1992 - error_rehash_old: 1993 - d_rehash(new_dentry); 1994 - error_rehash: 1995 - if (rehash) 1996 - d_rehash(rehash); 1997 - error_tmp: 1998 - if (tmp) 1999 - dput(tmp); 2000 - key_put(key); 2001 - error_scb: 2002 - kfree(scb); 2003 1921 error: 2004 - _leave(" = %d", ret); 2005 - return ret; 1922 + return afs_put_operation(op); 2006 1923 } 2007 1924 2008 1925 /*
+101 -93
fs/afs/dir_silly.c
··· 12 12 #include <linux/fsnotify.h> 13 13 #include "internal.h" 14 14 15 + static void afs_silly_rename_success(struct afs_operation *op) 16 + { 17 + _enter("op=%08x", op->debug_id); 18 + 19 + afs_vnode_commit_status(op, &op->file[0]); 20 + } 21 + 22 + static void afs_silly_rename_edit_dir(struct afs_operation *op) 23 + { 24 + struct afs_vnode_param *dvp = &op->file[0]; 25 + struct afs_vnode *dvnode = dvp->vnode; 26 + struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry)); 27 + struct dentry *old = op->dentry; 28 + struct dentry *new = op->dentry_2; 29 + 30 + spin_lock(&old->d_lock); 31 + old->d_flags |= DCACHE_NFSFS_RENAMED; 32 + spin_unlock(&old->d_lock); 33 + if (dvnode->silly_key != op->key) { 34 + key_put(dvnode->silly_key); 35 + dvnode->silly_key = key_get(op->key); 36 + } 37 + 38 + down_write(&dvnode->validate_lock); 39 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 40 + dvnode->status.data_version == dvp->dv_before + dvp->dv_delta) { 41 + afs_edit_dir_remove(dvnode, &old->d_name, 42 + afs_edit_dir_for_silly_0); 43 + afs_edit_dir_add(dvnode, &new->d_name, 44 + &vnode->fid, afs_edit_dir_for_silly_1); 45 + } 46 + up_write(&dvnode->validate_lock); 47 + } 48 + 49 + static const struct afs_operation_ops afs_silly_rename_operation = { 50 + .issue_afs_rpc = afs_fs_rename, 51 + .issue_yfs_rpc = yfs_fs_rename, 52 + .success = afs_silly_rename_success, 53 + .edit_dir = afs_silly_rename_edit_dir, 54 + }; 55 + 15 56 /* 16 57 * Actually perform the silly rename step. 17 58 */ ··· 60 19 struct dentry *old, struct dentry *new, 61 20 struct key *key) 62 21 { 63 - struct afs_fs_cursor fc; 64 - struct afs_status_cb *scb; 65 - afs_dataversion_t dir_data_version; 66 - int ret = -ERESTARTSYS; 22 + struct afs_operation *op; 67 23 68 24 _enter("%pd,%pd", old, new); 69 25 70 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 71 - if (!scb) 72 - return -ENOMEM; 26 + op = afs_alloc_operation(key, dvnode->volume); 27 + if (IS_ERR(op)) 28 + return PTR_ERR(op); 29 + 30 + afs_op_set_vnode(op, 0, dvnode); 31 + 32 + op->dentry = old; 33 + op->dentry_2 = new; 34 + op->ops = &afs_silly_rename_operation; 73 35 74 36 trace_afs_silly_rename(vnode, false); 75 - if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { 76 - dir_data_version = dvnode->status.data_version + 1; 77 - 78 - while (afs_select_fileserver(&fc)) { 79 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 80 - afs_fs_rename(&fc, old->d_name.name, 81 - dvnode, new->d_name.name, 82 - scb, scb); 83 - } 84 - 85 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 86 - &dir_data_version, scb); 87 - ret = afs_end_vnode_operation(&fc); 88 - } 89 - 90 - if (ret == 0) { 91 - spin_lock(&old->d_lock); 92 - old->d_flags |= DCACHE_NFSFS_RENAMED; 93 - spin_unlock(&old->d_lock); 94 - if (dvnode->silly_key != key) { 95 - key_put(dvnode->silly_key); 96 - dvnode->silly_key = key_get(key); 97 - } 98 - 99 - down_write(&dvnode->validate_lock); 100 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 101 - dvnode->status.data_version == dir_data_version) { 102 - afs_edit_dir_remove(dvnode, &old->d_name, 103 - afs_edit_dir_for_silly_0); 104 - afs_edit_dir_add(dvnode, &new->d_name, 105 - &vnode->fid, afs_edit_dir_for_silly_1); 106 - } 107 - up_write(&dvnode->validate_lock); 108 - } 109 - 110 - kfree(scb); 111 - _leave(" = %d", ret); 112 - return ret; 37 + return afs_do_sync_operation(op); 113 38 } 114 39 115 40 /** ··· 146 139 return ret; 147 140 } 148 141 142 + static void afs_silly_unlink_success(struct afs_operation *op) 143 + { 144 + struct afs_vnode *vnode = op->file[1].vnode; 145 + 146 + _enter("op=%08x", op->debug_id); 147 + afs_check_for_remote_deletion(op, op->file[0].vnode); 148 + afs_vnode_commit_status(op, &op->file[0]); 149 + afs_vnode_commit_status(op, &op->file[1]); 150 + afs_update_dentry_version(op, &op->file[0], op->dentry); 151 + 152 + drop_nlink(&vnode->vfs_inode); 153 + if (vnode->vfs_inode.i_nlink == 0) { 154 + set_bit(AFS_VNODE_DELETED, &vnode->flags); 155 + clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 156 + } 157 + } 158 + 159 + static void afs_silly_unlink_edit_dir(struct afs_operation *op) 160 + { 161 + struct afs_vnode_param *dvp = &op->file[0]; 162 + struct afs_vnode *dvnode = dvp->vnode; 163 + 164 + _enter("op=%08x", op->debug_id); 165 + down_write(&dvnode->validate_lock); 166 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 167 + dvnode->status.data_version == dvp->dv_before + dvp->dv_delta) 168 + afs_edit_dir_remove(dvnode, &op->dentry->d_name, 169 + afs_edit_dir_for_unlink); 170 + up_write(&dvnode->validate_lock); 171 + } 172 + 173 + static const struct afs_operation_ops afs_silly_unlink_operation = { 174 + .issue_afs_rpc = afs_fs_remove_file, 175 + .issue_yfs_rpc = yfs_fs_remove_file, 176 + .success = afs_silly_unlink_success, 177 + .edit_dir = afs_silly_unlink_edit_dir, 178 + }; 179 + 149 180 /* 150 181 * Tell the server to remove a sillyrename file. 151 182 */ 152 183 static int afs_do_silly_unlink(struct afs_vnode *dvnode, struct afs_vnode *vnode, 153 184 struct dentry *dentry, struct key *key) 154 185 { 155 - struct afs_fs_cursor fc; 156 - struct afs_status_cb *scb; 157 - int ret = -ERESTARTSYS; 186 + struct afs_operation *op; 158 187 159 188 _enter(""); 160 189 161 - scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL); 162 - if (!scb) 163 - return -ENOMEM; 190 + op = afs_alloc_operation(NULL, dvnode->volume); 191 + if (IS_ERR(op)) 192 + return PTR_ERR(op); 193 + 194 + afs_op_set_vnode(op, 0, dvnode); 195 + afs_op_set_vnode(op, 1, vnode); 196 + 197 + op->dentry = dentry; 198 + op->ops = &afs_silly_unlink_operation; 164 199 165 200 trace_afs_silly_rename(vnode, true); 166 - if (afs_begin_vnode_operation(&fc, dvnode, key, false)) { 167 - afs_dataversion_t dir_data_version = dvnode->status.data_version + 1; 168 - 169 - while (afs_select_fileserver(&fc)) { 170 - fc.cb_break = afs_calc_vnode_cb_break(dvnode); 171 - 172 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) && 173 - !test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) { 174 - yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name, 175 - &scb[0], &scb[1]); 176 - if (fc.ac.error != -ECONNABORTED || 177 - fc.ac.abort_code != RXGEN_OPCODE) 178 - continue; 179 - set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags); 180 - } 181 - 182 - afs_fs_remove(&fc, vnode, dentry->d_name.name, false, &scb[0]); 183 - } 184 - 185 - afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 186 - &dir_data_version, &scb[0]); 187 - ret = afs_end_vnode_operation(&fc); 188 - if (ret == 0) { 189 - drop_nlink(&vnode->vfs_inode); 190 - if (vnode->vfs_inode.i_nlink == 0) { 191 - set_bit(AFS_VNODE_DELETED, &vnode->flags); 192 - clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 193 - } 194 - } 195 - if (ret == 0) { 196 - down_write(&dvnode->validate_lock); 197 - if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && 198 - dvnode->status.data_version == dir_data_version) 199 - afs_edit_dir_remove(dvnode, &dentry->d_name, 200 - afs_edit_dir_for_unlink); 201 - up_write(&dvnode->validate_lock); 202 - } 203 - } 204 - 205 - kfree(scb); 206 - _leave(" = %d", ret); 207 - return ret; 201 + return afs_do_sync_operation(op); 208 202 } 209 203 210 204 /*
+93
fs/afs/dynroot.c
··· 10 10 #include <linux/dns_resolver.h> 11 11 #include "internal.h" 12 12 13 + static atomic_t afs_autocell_ino; 14 + 15 + /* 16 + * iget5() comparator for inode created by autocell operations 17 + * 18 + * These pseudo inodes don't match anything. 19 + */ 20 + static int afs_iget5_pseudo_test(struct inode *inode, void *opaque) 21 + { 22 + return 0; 23 + } 24 + 25 + /* 26 + * iget5() inode initialiser 27 + */ 28 + static int afs_iget5_pseudo_set(struct inode *inode, void *opaque) 29 + { 30 + struct afs_super_info *as = AFS_FS_S(inode->i_sb); 31 + struct afs_vnode *vnode = AFS_FS_I(inode); 32 + struct afs_fid *fid = opaque; 33 + 34 + vnode->volume = as->volume; 35 + vnode->fid = *fid; 36 + inode->i_ino = fid->vnode; 37 + inode->i_generation = fid->unique; 38 + return 0; 39 + } 40 + 41 + /* 42 + * Create an inode for a dynamic root directory or an autocell dynamic 43 + * automount dir. 44 + */ 45 + struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) 46 + { 47 + struct afs_super_info *as = AFS_FS_S(sb); 48 + struct afs_vnode *vnode; 49 + struct inode *inode; 50 + struct afs_fid fid = {}; 51 + 52 + _enter(""); 53 + 54 + if (as->volume) 55 + fid.vid = as->volume->vid; 56 + if (root) { 57 + fid.vnode = 1; 58 + fid.unique = 1; 59 + } else { 60 + fid.vnode = atomic_inc_return(&afs_autocell_ino); 61 + fid.unique = 0; 62 + } 63 + 64 + inode = iget5_locked(sb, fid.vnode, 65 + afs_iget5_pseudo_test, afs_iget5_pseudo_set, &fid); 66 + if (!inode) { 67 + _leave(" = -ENOMEM"); 68 + return ERR_PTR(-ENOMEM); 69 + } 70 + 71 + _debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }", 72 + inode, inode->i_ino, fid.vid, fid.vnode, fid.unique); 73 + 74 + vnode = AFS_FS_I(inode); 75 + 76 + /* there shouldn't be an existing inode */ 77 + BUG_ON(!(inode->i_state & I_NEW)); 78 + 79 + inode->i_size = 0; 80 + inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; 81 + if (root) { 82 + inode->i_op = &afs_dynroot_inode_operations; 83 + inode->i_fop = &simple_dir_operations; 84 + } else { 85 + inode->i_op = &afs_autocell_inode_operations; 86 + } 87 + set_nlink(inode, 2); 88 + inode->i_uid = GLOBAL_ROOT_UID; 89 + inode->i_gid = GLOBAL_ROOT_GID; 90 + inode->i_ctime = inode->i_atime = inode->i_mtime = current_time(inode); 91 + inode->i_blocks = 0; 92 + inode->i_generation = 0; 93 + 94 + set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags); 95 + if (!root) { 96 + set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags); 97 + inode->i_flags |= S_AUTOMOUNT; 98 + } 99 + 100 + inode->i_flags |= S_NOATIME; 101 + unlock_new_inode(inode); 102 + _leave(" = %p", inode); 103 + return inode; 104 + } 105 + 13 106 /* 14 107 * Probe to see if a cell may exist. This prevents positive dentries from 15 108 * being created unnecessarily.
+32 -30
fs/afs/file.c
··· 69 69 */ 70 70 void afs_put_wb_key(struct afs_wb_key *wbk) 71 71 { 72 - if (refcount_dec_and_test(&wbk->usage)) { 72 + if (wbk && refcount_dec_and_test(&wbk->usage)) { 73 73 key_put(wbk->key); 74 74 kfree(wbk); 75 75 } ··· 220 220 } 221 221 #endif 222 222 223 + static void afs_fetch_data_success(struct afs_operation *op) 224 + { 225 + struct afs_vnode *vnode = op->file[0].vnode; 226 + 227 + _enter("op=%08x", op->debug_id); 228 + afs_check_for_remote_deletion(op, vnode); 229 + afs_vnode_commit_status(op, &op->file[0]); 230 + afs_stat_v(vnode, n_fetches); 231 + atomic_long_add(op->fetch.req->actual_len, &op->net->n_fetch_bytes); 232 + } 233 + 234 + static void afs_fetch_data_put(struct afs_operation *op) 235 + { 236 + afs_put_read(op->fetch.req); 237 + } 238 + 239 + static const struct afs_operation_ops afs_fetch_data_operation = { 240 + .issue_afs_rpc = afs_fs_fetch_data, 241 + .issue_yfs_rpc = yfs_fs_fetch_data, 242 + .success = afs_fetch_data_success, 243 + .put = afs_fetch_data_put, 244 + }; 245 + 223 246 /* 224 247 * Fetch file data from the volume. 225 248 */ 226 249 int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *req) 227 250 { 228 - struct afs_fs_cursor fc; 229 - struct afs_status_cb *scb; 230 - int ret; 251 + struct afs_operation *op; 231 252 232 253 _enter("%s{%llx:%llu.%u},%x,,,", 233 254 vnode->volume->name, ··· 257 236 vnode->fid.unique, 258 237 key_serial(key)); 259 238 260 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 261 - if (!scb) 262 - return -ENOMEM; 239 + op = afs_alloc_operation(key, vnode->volume); 240 + if (IS_ERR(op)) 241 + return PTR_ERR(op); 263 242 264 - ret = -ERESTARTSYS; 265 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 266 - afs_dataversion_t data_version = vnode->status.data_version; 243 + afs_op_set_vnode(op, 0, vnode); 267 244 268 - while (afs_select_fileserver(&fc)) { 269 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 270 - afs_fs_fetch_data(&fc, scb, req); 271 - } 272 - 273 - afs_check_for_remote_deletion(&fc, vnode); 274 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 275 - &data_version, scb); 276 - ret = afs_end_vnode_operation(&fc); 277 - } 278 - 279 - if (ret == 0) { 280 - afs_stat_v(vnode, n_fetches); 281 - atomic_long_add(req->actual_len, 282 - &afs_v2net(vnode)->n_fetch_bytes); 283 - } 284 - 285 - kfree(scb); 286 - _leave(" = %d", ret); 287 - return ret; 245 + op->fetch.req = afs_get_read(req); 246 + op->ops = &afs_fetch_data_operation; 247 + return afs_do_sync_operation(op); 288 248 } 289 249 290 250 /*
+53 -61
fs/afs/flock.c
··· 70 70 */ 71 71 void afs_lock_op_done(struct afs_call *call) 72 72 { 73 - struct afs_vnode *vnode = call->lvnode; 73 + struct afs_operation *op = call->op; 74 + struct afs_vnode *vnode = op->lock.lvnode; 74 75 75 76 if (call->error == 0) { 76 77 spin_lock(&vnode->lock); ··· 173 172 vnode->lock_key = NULL; 174 173 } 175 174 175 + static void afs_lock_success(struct afs_operation *op) 176 + { 177 + struct afs_vnode *vnode = op->file[0].vnode; 178 + 179 + _enter("op=%08x", op->debug_id); 180 + afs_check_for_remote_deletion(op, vnode); 181 + afs_vnode_commit_status(op, &op->file[0]); 182 + } 183 + 184 + static const struct afs_operation_ops afs_set_lock_operation = { 185 + .issue_afs_rpc = afs_fs_set_lock, 186 + .issue_yfs_rpc = yfs_fs_set_lock, 187 + .success = afs_lock_success, 188 + }; 189 + 176 190 /* 177 191 * Get a lock on a file 178 192 */ 179 193 static int afs_set_lock(struct afs_vnode *vnode, struct key *key, 180 194 afs_lock_type_t type) 181 195 { 182 - struct afs_status_cb *scb; 183 - struct afs_fs_cursor fc; 184 - int ret; 196 + struct afs_operation *op; 185 197 186 198 _enter("%s{%llx:%llu.%u},%x,%u", 187 199 vnode->volume->name, ··· 203 189 vnode->fid.unique, 204 190 key_serial(key), type); 205 191 206 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 207 - if (!scb) 208 - return -ENOMEM; 192 + op = afs_alloc_operation(key, vnode->volume); 193 + if (IS_ERR(op)) 194 + return PTR_ERR(op); 209 195 210 - ret = -ERESTARTSYS; 211 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 212 - while (afs_select_fileserver(&fc)) { 213 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 214 - afs_fs_set_lock(&fc, type, scb); 215 - } 196 + afs_op_set_vnode(op, 0, vnode); 216 197 217 - afs_check_for_remote_deletion(&fc, vnode); 218 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, NULL, scb); 219 - ret = afs_end_vnode_operation(&fc); 220 - } 221 - 222 - kfree(scb); 223 - _leave(" = %d", ret); 224 - return ret; 198 + op->lock.type = type; 199 + op->ops = &afs_set_lock_operation; 200 + return afs_do_sync_operation(op); 225 201 } 202 + 203 + static const struct afs_operation_ops afs_extend_lock_operation = { 204 + .issue_afs_rpc = afs_fs_extend_lock, 205 + .issue_yfs_rpc = yfs_fs_extend_lock, 206 + .success = afs_lock_success, 207 + }; 226 208 227 209 /* 228 210 * Extend a lock on a file 229 211 */ 230 212 static int afs_extend_lock(struct afs_vnode *vnode, struct key *key) 231 213 { 232 - struct afs_status_cb *scb; 233 - struct afs_fs_cursor fc; 234 - int ret; 214 + struct afs_operation *op; 235 215 236 216 _enter("%s{%llx:%llu.%u},%x", 237 217 vnode->volume->name, ··· 234 226 vnode->fid.unique, 235 227 key_serial(key)); 236 228 237 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 238 - if (!scb) 239 - return -ENOMEM; 229 + op = afs_alloc_operation(key, vnode->volume); 230 + if (IS_ERR(op)) 231 + return PTR_ERR(op); 240 232 241 - ret = -ERESTARTSYS; 242 - if (afs_begin_vnode_operation(&fc, vnode, key, false)) { 243 - while (afs_select_current_fileserver(&fc)) { 244 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 245 - afs_fs_extend_lock(&fc, scb); 246 - } 233 + afs_op_set_vnode(op, 0, vnode); 247 234 248 - afs_check_for_remote_deletion(&fc, vnode); 249 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, NULL, scb); 250 - ret = afs_end_vnode_operation(&fc); 251 - } 252 - 253 - kfree(scb); 254 - _leave(" = %d", ret); 255 - return ret; 235 + op->flags |= AFS_OPERATION_UNINTR; 236 + op->ops = &afs_extend_lock_operation; 237 + return afs_do_sync_operation(op); 256 238 } 239 + 240 + static const struct afs_operation_ops afs_release_lock_operation = { 241 + .issue_afs_rpc = afs_fs_release_lock, 242 + .issue_yfs_rpc = yfs_fs_release_lock, 243 + .success = afs_lock_success, 244 + }; 257 245 258 246 /* 259 247 * Release a lock on a file 260 248 */ 261 249 static int afs_release_lock(struct afs_vnode *vnode, struct key *key) 262 250 { 263 - struct afs_status_cb *scb; 264 - struct afs_fs_cursor fc; 265 - int ret; 251 + struct afs_operation *op; 266 252 267 253 _enter("%s{%llx:%llu.%u},%x", 268 254 vnode->volume->name, ··· 265 263 vnode->fid.unique, 266 264 key_serial(key)); 267 265 268 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 269 - if (!scb) 270 - return -ENOMEM; 266 + op = afs_alloc_operation(key, vnode->volume); 267 + if (IS_ERR(op)) 268 + return PTR_ERR(op); 271 269 272 - ret = -ERESTARTSYS; 273 - if (afs_begin_vnode_operation(&fc, vnode, key, false)) { 274 - while (afs_select_current_fileserver(&fc)) { 275 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 276 - afs_fs_release_lock(&fc, scb); 277 - } 270 + afs_op_set_vnode(op, 0, vnode); 278 271 279 - afs_check_for_remote_deletion(&fc, vnode); 280 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, NULL, scb); 281 - ret = afs_end_vnode_operation(&fc); 282 - } 283 - 284 - kfree(scb); 285 - _leave(" = %d", ret); 286 - return ret; 272 + op->flags |= AFS_OPERATION_UNINTR; 273 + op->ops = &afs_release_lock_operation; 274 + return afs_do_sync_operation(op); 287 275 } 288 276 289 277 /*
+239
fs/afs/fs_operation.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Fileserver-directed operation handling. 3 + * 4 + * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #include <linux/kernel.h> 9 + #include <linux/slab.h> 10 + #include <linux/fs.h> 11 + #include "internal.h" 12 + 13 + static atomic_t afs_operation_debug_counter; 14 + 15 + /* 16 + * Create an operation against a volume. 17 + */ 18 + struct afs_operation *afs_alloc_operation(struct key *key, struct afs_volume *volume) 19 + { 20 + struct afs_operation *op; 21 + 22 + _enter(""); 23 + 24 + op = kzalloc(sizeof(*op), GFP_KERNEL); 25 + if (!op) 26 + return ERR_PTR(-ENOMEM); 27 + 28 + if (!key) { 29 + key = afs_request_key(volume->cell); 30 + if (IS_ERR(key)) { 31 + kfree(op); 32 + return ERR_CAST(key); 33 + } 34 + } else { 35 + key_get(key); 36 + } 37 + 38 + op->key = key; 39 + op->volume = afs_get_volume(volume, afs_volume_trace_get_new_op); 40 + op->net = volume->cell->net; 41 + op->cb_v_break = volume->cb_v_break; 42 + op->debug_id = atomic_inc_return(&afs_operation_debug_counter); 43 + op->error = -EDESTADDRREQ; 44 + op->ac.error = SHRT_MAX; 45 + 46 + _leave(" = [op=%08x]", op->debug_id); 47 + return op; 48 + } 49 + 50 + /* 51 + * Lock the vnode(s) being operated upon. 52 + */ 53 + static bool afs_get_io_locks(struct afs_operation *op) 54 + { 55 + struct afs_vnode *vnode = op->file[0].vnode; 56 + struct afs_vnode *vnode2 = op->file[1].vnode; 57 + 58 + _enter(""); 59 + 60 + if (op->flags & AFS_OPERATION_UNINTR) { 61 + mutex_lock(&vnode->io_lock); 62 + op->flags |= AFS_OPERATION_LOCK_0; 63 + _leave(" = t [1]"); 64 + return true; 65 + } 66 + 67 + if (!vnode2 || !op->file[1].need_io_lock || vnode == vnode2) 68 + vnode2 = NULL; 69 + 70 + if (vnode2 > vnode) 71 + swap(vnode, vnode2); 72 + 73 + if (mutex_lock_interruptible(&vnode->io_lock) < 0) { 74 + op->error = -EINTR; 75 + op->flags |= AFS_OPERATION_STOP; 76 + _leave(" = f [I 0]"); 77 + return false; 78 + } 79 + op->flags |= AFS_OPERATION_LOCK_0; 80 + 81 + if (vnode2) { 82 + if (mutex_lock_interruptible_nested(&vnode2->io_lock, 1) < 0) { 83 + op->error = -EINTR; 84 + op->flags |= AFS_OPERATION_STOP; 85 + mutex_unlock(&vnode->io_lock); 86 + op->flags &= ~AFS_OPERATION_LOCK_0; 87 + _leave(" = f [I 1]"); 88 + return false; 89 + } 90 + op->flags |= AFS_OPERATION_LOCK_1; 91 + } 92 + 93 + _leave(" = t [2]"); 94 + return true; 95 + } 96 + 97 + static void afs_drop_io_locks(struct afs_operation *op) 98 + { 99 + struct afs_vnode *vnode = op->file[0].vnode; 100 + struct afs_vnode *vnode2 = op->file[1].vnode; 101 + 102 + _enter(""); 103 + 104 + if (op->flags & AFS_OPERATION_LOCK_1) 105 + mutex_unlock(&vnode2->io_lock); 106 + if (op->flags & AFS_OPERATION_LOCK_0) 107 + mutex_unlock(&vnode->io_lock); 108 + } 109 + 110 + static void afs_prepare_vnode(struct afs_operation *op, struct afs_vnode_param *vp, 111 + unsigned int index) 112 + { 113 + struct afs_vnode *vnode = vp->vnode; 114 + 115 + if (vnode) { 116 + vp->fid = vnode->fid; 117 + vp->dv_before = vnode->status.data_version; 118 + vp->cb_break_before = afs_calc_vnode_cb_break(vnode); 119 + if (vnode->lock_state != AFS_VNODE_LOCK_NONE) 120 + op->flags |= AFS_OPERATION_CUR_ONLY; 121 + } 122 + 123 + if (vp->fid.vnode) 124 + _debug("PREP[%u] {%llx:%llu.%u}", 125 + index, vp->fid.vid, vp->fid.vnode, vp->fid.unique); 126 + } 127 + 128 + /* 129 + * Begin an operation on the fileserver. 130 + * 131 + * Fileserver operations are serialised on the server by vnode, so we serialise 132 + * them here also using the io_lock. 133 + */ 134 + bool afs_begin_vnode_operation(struct afs_operation *op) 135 + { 136 + struct afs_vnode *vnode = op->file[0].vnode; 137 + 138 + ASSERT(vnode); 139 + 140 + _enter(""); 141 + 142 + if (op->file[0].need_io_lock) 143 + if (!afs_get_io_locks(op)) 144 + return false; 145 + 146 + afs_prepare_vnode(op, &op->file[0], 0); 147 + afs_prepare_vnode(op, &op->file[1], 1); 148 + op->cb_v_break = op->volume->cb_v_break; 149 + _leave(" = true"); 150 + return true; 151 + } 152 + 153 + /* 154 + * Tidy up a filesystem cursor and unlock the vnode. 155 + */ 156 + static void afs_end_vnode_operation(struct afs_operation *op) 157 + { 158 + _enter(""); 159 + 160 + if (op->error == -EDESTADDRREQ || 161 + op->error == -EADDRNOTAVAIL || 162 + op->error == -ENETUNREACH || 163 + op->error == -EHOSTUNREACH) 164 + afs_dump_edestaddrreq(op); 165 + 166 + afs_drop_io_locks(op); 167 + 168 + if (op->error == -ECONNABORTED) 169 + op->error = afs_abort_to_error(op->ac.abort_code); 170 + } 171 + 172 + /* 173 + * Wait for an in-progress operation to complete. 174 + */ 175 + void afs_wait_for_operation(struct afs_operation *op) 176 + { 177 + _enter(""); 178 + 179 + while (afs_select_fileserver(op)) { 180 + op->cb_s_break = op->server->cb_s_break; 181 + if (test_bit(AFS_SERVER_FL_IS_YFS, &op->server->flags) && 182 + op->ops->issue_yfs_rpc) 183 + op->ops->issue_yfs_rpc(op); 184 + else 185 + op->ops->issue_afs_rpc(op); 186 + 187 + op->error = afs_wait_for_call_to_complete(op->call, &op->ac); 188 + } 189 + 190 + if (op->error == 0) { 191 + _debug("success"); 192 + op->ops->success(op); 193 + } 194 + 195 + afs_end_vnode_operation(op); 196 + 197 + if (op->error == 0 && op->ops->edit_dir) { 198 + _debug("edit_dir"); 199 + op->ops->edit_dir(op); 200 + } 201 + _leave(""); 202 + } 203 + 204 + /* 205 + * Dispose of an operation. 206 + */ 207 + int afs_put_operation(struct afs_operation *op) 208 + { 209 + int i, ret = op->error; 210 + 211 + _enter("op=%08x,%d", op->debug_id, ret); 212 + 213 + if (op->ops && op->ops->put) 214 + op->ops->put(op); 215 + if (op->file[0].put_vnode) 216 + iput(&op->file[0].vnode->vfs_inode); 217 + if (op->file[1].put_vnode) 218 + iput(&op->file[1].vnode->vfs_inode); 219 + 220 + if (op->more_files) { 221 + for (i = 0; i < op->nr_files - 2; i++) 222 + if (op->more_files[i].put_vnode) 223 + iput(&op->more_files[i].vnode->vfs_inode); 224 + kfree(op->more_files); 225 + } 226 + 227 + afs_end_cursor(&op->ac); 228 + afs_put_serverlist(op->net, op->server_list); 229 + afs_put_volume(op->net, op->volume, afs_volume_trace_put_put_op); 230 + kfree(op); 231 + return ret; 232 + } 233 + 234 + int afs_do_sync_operation(struct afs_operation *op) 235 + { 236 + afs_begin_vnode_operation(op); 237 + afs_wait_for_operation(op); 238 + return afs_put_operation(op); 239 + }
+267 -74
fs/afs/fs_probe.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* AFS fileserver probing 3 3 * 4 - * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 + * Copyright (C) 2018, 2020 Red Hat, Inc. All Rights Reserved. 5 5 * Written by David Howells (dhowells@redhat.com) 6 6 */ 7 7 ··· 11 11 #include "internal.h" 12 12 #include "protocol_yfs.h" 13 13 14 - static bool afs_fs_probe_done(struct afs_server *server) 15 - { 16 - if (!atomic_dec_and_test(&server->probe_outstanding)) 17 - return false; 14 + static unsigned int afs_fs_probe_fast_poll_interval = 30 * HZ; 15 + static unsigned int afs_fs_probe_slow_poll_interval = 5 * 60 * HZ; 18 16 19 - wake_up_var(&server->probe_outstanding); 20 - clear_bit_unlock(AFS_SERVER_FL_PROBING, &server->flags); 21 - wake_up_bit(&server->flags, AFS_SERVER_FL_PROBING); 22 - return true; 17 + /* 18 + * Start the probe polling timer. We have to supply it with an inc on the 19 + * outstanding server count. 20 + */ 21 + static void afs_schedule_fs_probe(struct afs_net *net, 22 + struct afs_server *server, bool fast) 23 + { 24 + unsigned long atj; 25 + 26 + if (!net->live) 27 + return; 28 + 29 + atj = server->probed_at; 30 + atj += fast ? afs_fs_probe_fast_poll_interval : afs_fs_probe_slow_poll_interval; 31 + 32 + afs_inc_servers_outstanding(net); 33 + if (timer_reduce(&net->fs_probe_timer, atj)) 34 + afs_dec_servers_outstanding(net); 35 + } 36 + 37 + /* 38 + * Handle the completion of a set of probes. 39 + */ 40 + static void afs_finished_fs_probe(struct afs_net *net, struct afs_server *server) 41 + { 42 + bool responded = server->probe.responded; 43 + 44 + write_seqlock(&net->fs_lock); 45 + if (responded) { 46 + list_add_tail(&server->probe_link, &net->fs_probe_slow); 47 + } else { 48 + server->rtt = UINT_MAX; 49 + clear_bit(AFS_SERVER_FL_RESPONDING, &server->flags); 50 + list_add_tail(&server->probe_link, &net->fs_probe_fast); 51 + } 52 + write_sequnlock(&net->fs_lock); 53 + 54 + afs_schedule_fs_probe(net, server, !responded); 55 + } 56 + 57 + /* 58 + * Handle the completion of a probe. 59 + */ 60 + static void afs_done_one_fs_probe(struct afs_net *net, struct afs_server *server) 61 + { 62 + _enter(""); 63 + 64 + if (atomic_dec_and_test(&server->probe_outstanding)) 65 + afs_finished_fs_probe(net, server); 66 + 67 + wake_up_all(&server->probe_wq); 68 + } 69 + 70 + /* 71 + * Handle inability to send a probe due to ENOMEM when trying to allocate a 72 + * call struct. 73 + */ 74 + static void afs_fs_probe_not_done(struct afs_net *net, 75 + struct afs_server *server, 76 + struct afs_addr_cursor *ac) 77 + { 78 + struct afs_addr_list *alist = ac->alist; 79 + unsigned int index = ac->index; 80 + 81 + _enter(""); 82 + 83 + trace_afs_io_error(0, -ENOMEM, afs_io_error_fs_probe_fail); 84 + spin_lock(&server->probe_lock); 85 + 86 + server->probe.local_failure = true; 87 + if (server->probe.error == 0) 88 + server->probe.error = -ENOMEM; 89 + 90 + set_bit(index, &alist->failed); 91 + 92 + spin_unlock(&server->probe_lock); 93 + return afs_done_one_fs_probe(net, server); 23 94 } 24 95 25 96 /* ··· 101 30 { 102 31 struct afs_addr_list *alist = call->alist; 103 32 struct afs_server *server = call->server; 104 - unsigned int server_index = call->server_index; 105 33 unsigned int index = call->addr_ix; 106 34 unsigned int rtt_us = 0; 107 - bool have_result = false; 108 35 int ret = call->error; 109 36 110 37 _enter("%pU,%u", &server->uuid, index); ··· 121 52 goto responded; 122 53 case -ENOMEM: 123 54 case -ENONET: 55 + clear_bit(index, &alist->responded); 124 56 server->probe.local_failure = true; 125 - afs_io_error(call, afs_io_error_fs_probe_fail); 57 + trace_afs_io_error(call->debug_id, ret, afs_io_error_fs_probe_fail); 126 58 goto out; 127 59 case -ECONNRESET: /* Responded, but call expired. */ 128 60 case -ERFKILL: ··· 142 72 server->probe.error == -ETIMEDOUT || 143 73 server->probe.error == -ETIME)) 144 74 server->probe.error = ret; 145 - afs_io_error(call, afs_io_error_fs_probe_fail); 75 + trace_afs_io_error(call->debug_id, ret, afs_io_error_fs_probe_fail); 146 76 goto out; 147 77 } 148 78 149 79 responded: 150 - set_bit(index, &alist->responded); 151 80 clear_bit(index, &alist->failed); 152 81 153 82 if (call->service_id == YFS_FS_SERVICE) { ··· 164 95 rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall); 165 96 if (rtt_us < server->probe.rtt) { 166 97 server->probe.rtt = rtt_us; 98 + server->rtt = rtt_us; 167 99 alist->preferred = index; 168 - have_result = true; 169 100 } 170 101 171 102 smp_wmb(); /* Set rtt before responded. */ 172 103 server->probe.responded = true; 173 - set_bit(AFS_SERVER_FL_PROBED, &server->flags); 104 + set_bit(index, &alist->responded); 105 + set_bit(AFS_SERVER_FL_RESPONDING, &server->flags); 174 106 out: 175 107 spin_unlock(&server->probe_lock); 176 108 177 - _debug("probe [%u][%u] %pISpc rtt=%u ret=%d", 178 - server_index, index, &alist->addrs[index].transport, rtt_us, ret); 109 + _debug("probe %pU [%u] %pISpc rtt=%u ret=%d", 110 + &server->uuid, index, &alist->addrs[index].transport, 111 + rtt_us, ret); 179 112 180 - have_result |= afs_fs_probe_done(server); 181 - if (have_result) 182 - wake_up_all(&server->probe_wq); 113 + return afs_done_one_fs_probe(call->net, server); 183 114 } 184 115 185 116 /* 186 - * Probe all of a fileserver's addresses to find out the best route and to 187 - * query its capabilities. 117 + * Probe one or all of a fileserver's addresses to find out the best route and 118 + * to query its capabilities. 188 119 */ 189 - static int afs_do_probe_fileserver(struct afs_net *net, 190 - struct afs_server *server, 191 - struct key *key, 192 - unsigned int server_index, 193 - struct afs_error *_e) 120 + void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server, 121 + struct key *key, bool all) 194 122 { 195 123 struct afs_addr_cursor ac = { 196 124 .index = 0, 197 125 }; 198 - struct afs_call *call; 199 - bool in_progress = false; 200 126 201 127 _enter("%pU", &server->uuid); 202 128 ··· 201 137 afs_get_addrlist(ac.alist); 202 138 read_unlock(&server->fs_lock); 203 139 204 - atomic_set(&server->probe_outstanding, ac.alist->nr_addrs); 140 + server->probed_at = jiffies; 141 + atomic_set(&server->probe_outstanding, all ? ac.alist->nr_addrs : 1); 205 142 memset(&server->probe, 0, sizeof(server->probe)); 206 143 server->probe.rtt = UINT_MAX; 207 144 208 - for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { 209 - call = afs_fs_get_capabilities(net, server, &ac, key, server_index); 210 - if (!IS_ERR(call)) { 211 - afs_put_call(call); 212 - in_progress = true; 213 - } else { 214 - afs_prioritise_error(_e, PTR_ERR(call), ac.abort_code); 215 - } 145 + ac.index = ac.alist->preferred; 146 + if (ac.index < 0 || ac.index >= ac.alist->nr_addrs) 147 + all = true; 148 + 149 + if (all) { 150 + for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) 151 + if (!afs_fs_get_capabilities(net, server, &ac, key)) 152 + afs_fs_probe_not_done(net, server, &ac); 153 + } else { 154 + if (!afs_fs_get_capabilities(net, server, &ac, key)) 155 + afs_fs_probe_not_done(net, server, &ac); 216 156 } 217 157 218 - if (!in_progress) 219 - afs_fs_probe_done(server); 220 158 afs_put_addrlist(ac.alist); 221 - return in_progress; 222 - } 223 - 224 - /* 225 - * Send off probes to all unprobed servers. 226 - */ 227 - int afs_probe_fileservers(struct afs_net *net, struct key *key, 228 - struct afs_server_list *list) 229 - { 230 - struct afs_server *server; 231 - struct afs_error e; 232 - bool in_progress = false; 233 - int i; 234 - 235 - e.error = 0; 236 - e.responded = false; 237 - for (i = 0; i < list->nr_servers; i++) { 238 - server = list->servers[i].server; 239 - if (test_bit(AFS_SERVER_FL_PROBED, &server->flags)) 240 - continue; 241 - 242 - if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags) && 243 - afs_do_probe_fileserver(net, server, key, i, &e)) 244 - in_progress = true; 245 - } 246 - 247 - return in_progress ? 0 : e.error; 248 159 } 249 160 250 161 /* ··· 229 190 { 230 191 struct wait_queue_entry *waits; 231 192 struct afs_server *server; 232 - unsigned int rtt = UINT_MAX; 193 + unsigned int rtt = UINT_MAX, rtt_s; 233 194 bool have_responders = false; 234 195 int pref = -1, i; 235 196 ··· 239 200 for (i = 0; i < slist->nr_servers; i++) { 240 201 if (test_bit(i, &untried)) { 241 202 server = slist->servers[i].server; 242 - if (!test_bit(AFS_SERVER_FL_PROBING, &server->flags)) 203 + if (!atomic_read(&server->probe_outstanding)) 243 204 __clear_bit(i, &untried); 244 205 if (server->probe.responded) 245 206 have_responders = true; ··· 269 230 server = slist->servers[i].server; 270 231 if (server->probe.responded) 271 232 goto stop; 272 - if (test_bit(AFS_SERVER_FL_PROBING, &server->flags)) 233 + if (atomic_read(&server->probe_outstanding)) 273 234 still_probing = true; 274 235 } 275 236 } ··· 285 246 for (i = 0; i < slist->nr_servers; i++) { 286 247 if (test_bit(i, &untried)) { 287 248 server = slist->servers[i].server; 288 - if (server->probe.responded && 289 - server->probe.rtt < rtt) { 249 + rtt_s = READ_ONCE(server->rtt); 250 + if (test_bit(AFS_SERVER_FL_RESPONDING, &server->flags) && 251 + rtt_s < rtt) { 290 252 pref = i; 291 - rtt = server->probe.rtt; 253 + rtt = rtt_s; 292 254 } 293 255 294 256 remove_wait_queue(&server->probe_wq, &waits[i]); ··· 304 264 if (pref >= 0) 305 265 slist->preferred = pref; 306 266 return 0; 267 + } 268 + 269 + /* 270 + * Probe timer. We have an increment on fs_outstanding that we need to pass 271 + * along to the work item. 272 + */ 273 + void afs_fs_probe_timer(struct timer_list *timer) 274 + { 275 + struct afs_net *net = container_of(timer, struct afs_net, fs_probe_timer); 276 + 277 + if (!queue_work(afs_wq, &net->fs_prober)) 278 + afs_dec_servers_outstanding(net); 279 + } 280 + 281 + /* 282 + * Dispatch a probe to a server. 283 + */ 284 + static void afs_dispatch_fs_probe(struct afs_net *net, struct afs_server *server, bool all) 285 + __releases(&net->fs_lock) 286 + { 287 + struct key *key = NULL; 288 + 289 + /* We remove it from the queues here - it will be added back to 290 + * one of the queues on the completion of the probe. 291 + */ 292 + list_del_init(&server->probe_link); 293 + 294 + afs_get_server(server, afs_server_trace_get_probe); 295 + write_sequnlock(&net->fs_lock); 296 + 297 + afs_fs_probe_fileserver(net, server, key, all); 298 + afs_put_server(net, server, afs_server_trace_put_probe); 299 + } 300 + 301 + /* 302 + * Probe a server immediately without waiting for its due time to come 303 + * round. This is used when all of the addresses have been tried. 304 + */ 305 + void afs_probe_fileserver(struct afs_net *net, struct afs_server *server) 306 + { 307 + write_seqlock(&net->fs_lock); 308 + if (!list_empty(&server->probe_link)) 309 + return afs_dispatch_fs_probe(net, server, true); 310 + write_sequnlock(&net->fs_lock); 311 + } 312 + 313 + /* 314 + * Probe dispatcher to regularly dispatch probes to keep NAT alive. 315 + */ 316 + void afs_fs_probe_dispatcher(struct work_struct *work) 317 + { 318 + struct afs_net *net = container_of(work, struct afs_net, fs_prober); 319 + struct afs_server *fast, *slow, *server; 320 + unsigned long nowj, timer_at, poll_at; 321 + bool first_pass = true, set_timer = false; 322 + 323 + if (!net->live) 324 + return; 325 + 326 + _enter(""); 327 + 328 + if (list_empty(&net->fs_probe_fast) && list_empty(&net->fs_probe_slow)) { 329 + _leave(" [none]"); 330 + return; 331 + } 332 + 333 + again: 334 + write_seqlock(&net->fs_lock); 335 + 336 + fast = slow = server = NULL; 337 + nowj = jiffies; 338 + timer_at = nowj + MAX_JIFFY_OFFSET; 339 + 340 + if (!list_empty(&net->fs_probe_fast)) { 341 + fast = list_first_entry(&net->fs_probe_fast, struct afs_server, probe_link); 342 + poll_at = fast->probed_at + afs_fs_probe_fast_poll_interval; 343 + if (time_before(nowj, poll_at)) { 344 + timer_at = poll_at; 345 + set_timer = true; 346 + fast = NULL; 347 + } 348 + } 349 + 350 + if (!list_empty(&net->fs_probe_slow)) { 351 + slow = list_first_entry(&net->fs_probe_slow, struct afs_server, probe_link); 352 + poll_at = slow->probed_at + afs_fs_probe_slow_poll_interval; 353 + if (time_before(nowj, poll_at)) { 354 + if (time_before(poll_at, timer_at)) 355 + timer_at = poll_at; 356 + set_timer = true; 357 + slow = NULL; 358 + } 359 + } 360 + 361 + server = fast ?: slow; 362 + if (server) 363 + _debug("probe %pU", &server->uuid); 364 + 365 + if (server && (first_pass || !need_resched())) { 366 + afs_dispatch_fs_probe(net, server, server == fast); 367 + first_pass = false; 368 + goto again; 369 + } 370 + 371 + write_sequnlock(&net->fs_lock); 372 + 373 + if (server) { 374 + if (!queue_work(afs_wq, &net->fs_prober)) 375 + afs_dec_servers_outstanding(net); 376 + _leave(" [requeue]"); 377 + } else if (set_timer) { 378 + if (timer_reduce(&net->fs_probe_timer, timer_at)) 379 + afs_dec_servers_outstanding(net); 380 + _leave(" [timer]"); 381 + } else { 382 + afs_dec_servers_outstanding(net); 383 + _leave(" [quiesce]"); 384 + } 385 + } 386 + 387 + /* 388 + * Wait for a probe on a particular fileserver to complete for 2s. 389 + */ 390 + int afs_wait_for_one_fs_probe(struct afs_server *server, bool is_intr) 391 + { 392 + struct wait_queue_entry wait; 393 + unsigned long timo = 2 * HZ; 394 + 395 + if (atomic_read(&server->probe_outstanding) == 0) 396 + goto dont_wait; 397 + 398 + init_wait_entry(&wait, 0); 399 + for (;;) { 400 + prepare_to_wait_event(&server->probe_wq, &wait, 401 + is_intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 402 + if (timo == 0 || 403 + server->probe.responded || 404 + atomic_read(&server->probe_outstanding) == 0 || 405 + (is_intr && signal_pending(current))) 406 + break; 407 + timo = schedule_timeout(timo); 408 + } 409 + 410 + finish_wait(&server->probe_wq, &wait); 411 + 412 + dont_wait: 413 + if (server->probe.responded) 414 + return 0; 415 + if (is_intr && signal_pending(current)) 416 + return -ERESTARTSYS; 417 + if (timo == 0) 418 + return -ETIME; 419 + return -EDESTADDRREQ; 307 420 }
+513 -796
fs/afs/fsclient.c
··· 13 13 #include "internal.h" 14 14 #include "afs_fs.h" 15 15 #include "xdr_fs.h" 16 - #include "protocol_yfs.h" 17 - 18 - static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi) 19 - { 20 - call->cbi = afs_get_cb_interest(cbi); 21 - } 22 16 23 17 /* 24 18 * decode an AFSFid block ··· 50 56 /* 51 57 * decode an AFSFetchStatus block 52 58 */ 53 - static int xdr_decode_AFSFetchStatus(const __be32 **_bp, 54 - struct afs_call *call, 55 - struct afs_status_cb *scb) 59 + static void xdr_decode_AFSFetchStatus(const __be32 **_bp, 60 + struct afs_call *call, 61 + struct afs_status_cb *scb) 56 62 { 57 63 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; 58 64 struct afs_file_status *status = &scb->status; 59 65 bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus); 60 66 u64 data_version, size; 61 67 u32 type, abort_code; 62 - int ret; 63 68 64 69 abort_code = ntohl(xdr->abort_code); 65 70 ··· 72 79 */ 73 80 status->abort_code = abort_code; 74 81 scb->have_error = true; 75 - goto good; 82 + goto advance; 76 83 } 77 84 78 85 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); ··· 82 89 if (abort_code != 0 && inline_error) { 83 90 status->abort_code = abort_code; 84 91 scb->have_error = true; 85 - goto good; 92 + goto advance; 86 93 } 87 94 88 95 type = ntohl(xdr->type); ··· 118 125 data_version |= (u64)ntohl(xdr->data_version_hi) << 32; 119 126 status->data_version = data_version; 120 127 scb->have_status = true; 121 - good: 122 - ret = 0; 123 128 advance: 124 129 *_bp = (const void *)*_bp + sizeof(*xdr); 125 - return ret; 130 + return; 126 131 127 132 bad: 128 133 xdr_dump_bad(*_bp); 129 - ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); 134 + afs_protocol_error(call, afs_eproto_bad_status); 130 135 goto advance; 131 136 } 132 137 ··· 234 243 /* 235 244 * deliver reply data to an FS.FetchStatus 236 245 */ 237 - static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call) 246 + static int afs_deliver_fs_fetch_status(struct afs_call *call) 238 247 { 248 + struct afs_operation *op = call->op; 249 + struct afs_vnode_param *vp = &op->file[op->fetch_status.which]; 239 250 const __be32 *bp; 240 251 int ret; 241 252 ··· 247 254 248 255 /* unmarshall the reply once we've received all of it */ 249 256 bp = call->buffer; 250 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 251 - if (ret < 0) 252 - return ret; 253 - xdr_decode_AFSCallBack(&bp, call, call->out_scb); 254 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 257 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 258 + xdr_decode_AFSCallBack(&bp, call, &vp->scb); 259 + xdr_decode_AFSVolSync(&bp, &op->volsync); 255 260 256 261 _leave(" = 0 [done]"); 257 262 return 0; ··· 258 267 /* 259 268 * FS.FetchStatus operation type 260 269 */ 261 - static const struct afs_call_type afs_RXFSFetchStatus_vnode = { 262 - .name = "FS.FetchStatus(vnode)", 270 + static const struct afs_call_type afs_RXFSFetchStatus = { 271 + .name = "FS.FetchStatus", 263 272 .op = afs_FS_FetchStatus, 264 - .deliver = afs_deliver_fs_fetch_status_vnode, 273 + .deliver = afs_deliver_fs_fetch_status, 265 274 .destructor = afs_flat_call_destructor, 266 275 }; 267 276 268 277 /* 269 278 * fetch the status information for a file 270 279 */ 271 - int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb, 272 - struct afs_volsync *volsync) 280 + void afs_fs_fetch_status(struct afs_operation *op) 273 281 { 274 - struct afs_vnode *vnode = fc->vnode; 282 + struct afs_vnode_param *vp = &op->file[op->fetch_status.which]; 275 283 struct afs_call *call; 276 - struct afs_net *net = afs_v2net(vnode); 277 284 __be32 *bp; 278 285 279 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 280 - return yfs_fs_fetch_file_status(fc, scb, volsync); 281 - 282 286 _enter(",%x,{%llx:%llu},,", 283 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 287 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 284 288 285 - call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode, 289 + call = afs_alloc_flat_call(op->net, &afs_RXFSFetchStatus, 286 290 16, (21 + 3 + 6) * 4); 287 - if (!call) { 288 - fc->ac.error = -ENOMEM; 289 - return -ENOMEM; 290 - } 291 - 292 - call->key = fc->key; 293 - call->out_scb = scb; 294 - call->out_volsync = volsync; 291 + if (!call) 292 + return afs_op_nomem(op); 295 293 296 294 /* marshall the parameters */ 297 295 bp = call->request; 298 296 bp[0] = htonl(FSFETCHSTATUS); 299 - bp[1] = htonl(vnode->fid.vid); 300 - bp[2] = htonl(vnode->fid.vnode); 301 - bp[3] = htonl(vnode->fid.unique); 297 + bp[1] = htonl(vp->fid.vid); 298 + bp[2] = htonl(vp->fid.vnode); 299 + bp[3] = htonl(vp->fid.unique); 302 300 303 - afs_use_fs_server(call, fc->cbi); 304 - trace_afs_make_fs_call(call, &vnode->fid); 305 - 306 - afs_set_fc_call(call, fc); 307 - afs_make_call(&fc->ac, call, GFP_NOFS); 308 - return afs_wait_for_call_to_complete(call, &fc->ac); 301 + trace_afs_make_fs_call(call, &vp->fid); 302 + afs_make_op_call(op, call, GFP_NOFS); 309 303 } 310 304 311 305 /* ··· 298 322 */ 299 323 static int afs_deliver_fs_fetch_data(struct afs_call *call) 300 324 { 301 - struct afs_read *req = call->read_request; 325 + struct afs_operation *op = call->op; 326 + struct afs_vnode_param *vp = &op->file[0]; 327 + struct afs_read *req = op->fetch.req; 302 328 const __be32 *bp; 303 329 unsigned int size; 304 330 int ret; ··· 397 419 return ret; 398 420 399 421 bp = call->buffer; 400 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 401 - if (ret < 0) 402 - return ret; 403 - xdr_decode_AFSCallBack(&bp, call, call->out_scb); 404 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 422 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 423 + xdr_decode_AFSCallBack(&bp, call, &vp->scb); 424 + xdr_decode_AFSVolSync(&bp, &op->volsync); 405 425 406 - req->data_version = call->out_scb->status.data_version; 407 - req->file_size = call->out_scb->status.size; 426 + req->data_version = vp->scb.status.data_version; 427 + req->file_size = vp->scb.status.size; 408 428 409 429 call->unmarshall++; 410 430 ··· 425 449 return 0; 426 450 } 427 451 428 - static void afs_fetch_data_destructor(struct afs_call *call) 429 - { 430 - struct afs_read *req = call->read_request; 431 - 432 - afs_put_read(req); 433 - afs_flat_call_destructor(call); 434 - } 435 - 436 452 /* 437 453 * FS.FetchData operation type 438 454 */ ··· 432 464 .name = "FS.FetchData", 433 465 .op = afs_FS_FetchData, 434 466 .deliver = afs_deliver_fs_fetch_data, 435 - .destructor = afs_fetch_data_destructor, 467 + .destructor = afs_flat_call_destructor, 436 468 }; 437 469 438 470 static const struct afs_call_type afs_RXFSFetchData64 = { 439 471 .name = "FS.FetchData64", 440 472 .op = afs_FS_FetchData64, 441 473 .deliver = afs_deliver_fs_fetch_data, 442 - .destructor = afs_fetch_data_destructor, 474 + .destructor = afs_flat_call_destructor, 443 475 }; 444 476 445 477 /* 446 478 * fetch data from a very large file 447 479 */ 448 - static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, 449 - struct afs_status_cb *scb, 450 - struct afs_read *req) 480 + static void afs_fs_fetch_data64(struct afs_operation *op) 451 481 { 452 - struct afs_vnode *vnode = fc->vnode; 482 + struct afs_vnode_param *vp = &op->file[0]; 483 + struct afs_read *req = op->fetch.req; 453 484 struct afs_call *call; 454 - struct afs_net *net = afs_v2net(vnode); 455 485 __be32 *bp; 456 486 457 487 _enter(""); 458 488 459 - call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4); 489 + call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4); 460 490 if (!call) 461 - return -ENOMEM; 462 - 463 - call->key = fc->key; 464 - call->out_scb = scb; 465 - call->out_volsync = NULL; 466 - call->read_request = afs_get_read(req); 491 + return afs_op_nomem(op); 467 492 468 493 /* marshall the parameters */ 469 494 bp = call->request; 470 495 bp[0] = htonl(FSFETCHDATA64); 471 - bp[1] = htonl(vnode->fid.vid); 472 - bp[2] = htonl(vnode->fid.vnode); 473 - bp[3] = htonl(vnode->fid.unique); 496 + bp[1] = htonl(vp->fid.vid); 497 + bp[2] = htonl(vp->fid.vnode); 498 + bp[3] = htonl(vp->fid.unique); 474 499 bp[4] = htonl(upper_32_bits(req->pos)); 475 500 bp[5] = htonl(lower_32_bits(req->pos)); 476 501 bp[6] = 0; 477 502 bp[7] = htonl(lower_32_bits(req->len)); 478 503 479 - afs_use_fs_server(call, fc->cbi); 480 - trace_afs_make_fs_call(call, &vnode->fid); 481 - afs_set_fc_call(call, fc); 482 - afs_make_call(&fc->ac, call, GFP_NOFS); 483 - return afs_wait_for_call_to_complete(call, &fc->ac); 504 + trace_afs_make_fs_call(call, &vp->fid); 505 + afs_make_op_call(op, call, GFP_NOFS); 484 506 } 485 507 486 508 /* 487 509 * fetch data from a file 488 510 */ 489 - int afs_fs_fetch_data(struct afs_fs_cursor *fc, 490 - struct afs_status_cb *scb, 491 - struct afs_read *req) 511 + void afs_fs_fetch_data(struct afs_operation *op) 492 512 { 493 - struct afs_vnode *vnode = fc->vnode; 513 + struct afs_vnode_param *vp = &op->file[0]; 494 514 struct afs_call *call; 495 - struct afs_net *net = afs_v2net(vnode); 515 + struct afs_read *req = op->fetch.req; 496 516 __be32 *bp; 497 - 498 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 499 - return yfs_fs_fetch_data(fc, scb, req); 500 517 501 518 if (upper_32_bits(req->pos) || 502 519 upper_32_bits(req->len) || 503 520 upper_32_bits(req->pos + req->len)) 504 - return afs_fs_fetch_data64(fc, scb, req); 521 + return afs_fs_fetch_data64(op); 505 522 506 523 _enter(""); 507 524 508 - call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4); 525 + call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4); 509 526 if (!call) 510 - return -ENOMEM; 511 - 512 - call->key = fc->key; 513 - call->out_scb = scb; 514 - call->out_volsync = NULL; 515 - call->read_request = afs_get_read(req); 527 + return afs_op_nomem(op); 516 528 517 529 /* marshall the parameters */ 518 530 bp = call->request; 519 531 bp[0] = htonl(FSFETCHDATA); 520 - bp[1] = htonl(vnode->fid.vid); 521 - bp[2] = htonl(vnode->fid.vnode); 522 - bp[3] = htonl(vnode->fid.unique); 532 + bp[1] = htonl(vp->fid.vid); 533 + bp[2] = htonl(vp->fid.vnode); 534 + bp[3] = htonl(vp->fid.unique); 523 535 bp[4] = htonl(lower_32_bits(req->pos)); 524 536 bp[5] = htonl(lower_32_bits(req->len)); 525 537 526 - afs_use_fs_server(call, fc->cbi); 527 - trace_afs_make_fs_call(call, &vnode->fid); 528 - afs_set_fc_call(call, fc); 529 - afs_make_call(&fc->ac, call, GFP_NOFS); 530 - return afs_wait_for_call_to_complete(call, &fc->ac); 538 + trace_afs_make_fs_call(call, &vp->fid); 539 + afs_make_op_call(op, call, GFP_NOFS); 531 540 } 532 541 533 542 /* ··· 512 567 */ 513 568 static int afs_deliver_fs_create_vnode(struct afs_call *call) 514 569 { 570 + struct afs_operation *op = call->op; 571 + struct afs_vnode_param *dvp = &op->file[0]; 572 + struct afs_vnode_param *vp = &op->file[1]; 515 573 const __be32 *bp; 516 574 int ret; 517 575 ··· 524 576 525 577 /* unmarshall the reply once we've received all of it */ 526 578 bp = call->buffer; 527 - xdr_decode_AFSFid(&bp, call->out_fid); 528 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 529 - if (ret < 0) 530 - return ret; 531 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb); 532 - if (ret < 0) 533 - return ret; 534 - xdr_decode_AFSCallBack(&bp, call, call->out_scb); 535 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 579 + xdr_decode_AFSFid(&bp, &op->file[1].fid); 580 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 581 + xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb); 582 + xdr_decode_AFSCallBack(&bp, call, &vp->scb); 583 + xdr_decode_AFSVolSync(&bp, &op->volsync); 536 584 537 585 _leave(" = 0 [done]"); 538 586 return 0; ··· 544 600 .destructor = afs_flat_call_destructor, 545 601 }; 546 602 603 + /* 604 + * Create a file. 605 + */ 606 + void afs_fs_create_file(struct afs_operation *op) 607 + { 608 + const struct qstr *name = &op->dentry->d_name; 609 + struct afs_vnode_param *dvp = &op->file[0]; 610 + struct afs_call *call; 611 + size_t namesz, reqsz, padsz; 612 + __be32 *bp; 613 + 614 + _enter(""); 615 + 616 + namesz = name->len; 617 + padsz = (4 - (namesz & 3)) & 3; 618 + reqsz = (5 * 4) + namesz + padsz + (6 * 4); 619 + 620 + call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, 621 + reqsz, (3 + 21 + 21 + 3 + 6) * 4); 622 + if (!call) 623 + return afs_op_nomem(op); 624 + 625 + /* marshall the parameters */ 626 + bp = call->request; 627 + *bp++ = htonl(FSCREATEFILE); 628 + *bp++ = htonl(dvp->fid.vid); 629 + *bp++ = htonl(dvp->fid.vnode); 630 + *bp++ = htonl(dvp->fid.unique); 631 + *bp++ = htonl(namesz); 632 + memcpy(bp, name->name, namesz); 633 + bp = (void *) bp + namesz; 634 + if (padsz > 0) { 635 + memset(bp, 0, padsz); 636 + bp = (void *) bp + padsz; 637 + } 638 + *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); 639 + *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 640 + *bp++ = 0; /* owner */ 641 + *bp++ = 0; /* group */ 642 + *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */ 643 + *bp++ = 0; /* segment size */ 644 + 645 + trace_afs_make_fs_call1(call, &dvp->fid, name); 646 + afs_make_op_call(op, call, GFP_NOFS); 647 + } 648 + 547 649 static const struct afs_call_type afs_RXFSMakeDir = { 548 650 .name = "FS.MakeDir", 549 651 .op = afs_FS_MakeDir, ··· 598 608 }; 599 609 600 610 /* 601 - * create a file or make a directory 611 + * Create a new directory 602 612 */ 603 - int afs_fs_create(struct afs_fs_cursor *fc, 604 - const char *name, 605 - umode_t mode, 606 - struct afs_status_cb *dvnode_scb, 607 - struct afs_fid *newfid, 608 - struct afs_status_cb *new_scb) 613 + void afs_fs_make_dir(struct afs_operation *op) 609 614 { 610 - struct afs_vnode *dvnode = fc->vnode; 615 + const struct qstr *name = &op->dentry->d_name; 616 + struct afs_vnode_param *dvp = &op->file[0]; 611 617 struct afs_call *call; 612 - struct afs_net *net = afs_v2net(dvnode); 613 618 size_t namesz, reqsz, padsz; 614 619 __be32 *bp; 615 620 616 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)){ 617 - if (S_ISDIR(mode)) 618 - return yfs_fs_make_dir(fc, name, mode, dvnode_scb, 619 - newfid, new_scb); 620 - else 621 - return yfs_fs_create_file(fc, name, mode, dvnode_scb, 622 - newfid, new_scb); 623 - } 624 - 625 621 _enter(""); 626 622 627 - namesz = strlen(name); 623 + namesz = name->len; 628 624 padsz = (4 - (namesz & 3)) & 3; 629 625 reqsz = (5 * 4) + namesz + padsz + (6 * 4); 630 626 631 - call = afs_alloc_flat_call( 632 - net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile, 633 - reqsz, (3 + 21 + 21 + 3 + 6) * 4); 627 + call = afs_alloc_flat_call(op->net, &afs_RXFSMakeDir, 628 + reqsz, (3 + 21 + 21 + 3 + 6) * 4); 634 629 if (!call) 635 - return -ENOMEM; 636 - 637 - call->key = fc->key; 638 - call->out_dir_scb = dvnode_scb; 639 - call->out_fid = newfid; 640 - call->out_scb = new_scb; 630 + return afs_op_nomem(op); 641 631 642 632 /* marshall the parameters */ 643 633 bp = call->request; 644 - *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE); 645 - *bp++ = htonl(dvnode->fid.vid); 646 - *bp++ = htonl(dvnode->fid.vnode); 647 - *bp++ = htonl(dvnode->fid.unique); 634 + *bp++ = htonl(FSMAKEDIR); 635 + *bp++ = htonl(dvp->fid.vid); 636 + *bp++ = htonl(dvp->fid.vnode); 637 + *bp++ = htonl(dvp->fid.unique); 648 638 *bp++ = htonl(namesz); 649 - memcpy(bp, name, namesz); 639 + memcpy(bp, name->name, namesz); 650 640 bp = (void *) bp + namesz; 651 641 if (padsz > 0) { 652 642 memset(bp, 0, padsz); 653 643 bp = (void *) bp + padsz; 654 644 } 655 645 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); 656 - *bp++ = htonl(dvnode->vfs_inode.i_mtime.tv_sec); /* mtime */ 646 + *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 657 647 *bp++ = 0; /* owner */ 658 648 *bp++ = 0; /* group */ 659 - *bp++ = htonl(mode & S_IALLUGO); /* unix mode */ 649 + *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */ 660 650 *bp++ = 0; /* segment size */ 661 651 662 - afs_use_fs_server(call, fc->cbi); 663 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 664 - afs_set_fc_call(call, fc); 665 - afs_make_call(&fc->ac, call, GFP_NOFS); 666 - return afs_wait_for_call_to_complete(call, &fc->ac); 652 + trace_afs_make_fs_call1(call, &dvp->fid, name); 653 + afs_make_op_call(op, call, GFP_NOFS); 667 654 } 668 655 669 656 /* 670 - * Deliver reply data to any operation that returns directory status and volume 671 - * sync. 657 + * Deliver reply data to any operation that returns status and volume sync. 672 658 */ 673 - static int afs_deliver_fs_dir_status_and_vol(struct afs_call *call) 659 + static int afs_deliver_fs_file_status_and_vol(struct afs_call *call) 674 660 { 661 + struct afs_operation *op = call->op; 662 + struct afs_vnode_param *vp = &op->file[0]; 675 663 const __be32 *bp; 676 664 int ret; 677 665 ··· 659 691 660 692 /* unmarshall the reply once we've received all of it */ 661 693 bp = call->buffer; 662 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb); 663 - if (ret < 0) 664 - return ret; 665 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 694 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 695 + xdr_decode_AFSVolSync(&bp, &op->volsync); 666 696 667 697 _leave(" = 0 [done]"); 668 698 return 0; 669 699 } 670 700 671 701 /* 672 - * FS.RemoveDir/FS.RemoveFile operation type 702 + * FS.RemoveFile operation type 673 703 */ 674 704 static const struct afs_call_type afs_RXFSRemoveFile = { 675 705 .name = "FS.RemoveFile", 676 706 .op = afs_FS_RemoveFile, 677 - .deliver = afs_deliver_fs_dir_status_and_vol, 678 - .destructor = afs_flat_call_destructor, 679 - }; 680 - 681 - static const struct afs_call_type afs_RXFSRemoveDir = { 682 - .name = "FS.RemoveDir", 683 - .op = afs_FS_RemoveDir, 684 - .deliver = afs_deliver_fs_dir_status_and_vol, 707 + .deliver = afs_deliver_fs_file_status_and_vol, 685 708 .destructor = afs_flat_call_destructor, 686 709 }; 687 710 688 711 /* 689 - * remove a file or directory 712 + * Remove a file. 690 713 */ 691 - int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 692 - const char *name, bool isdir, struct afs_status_cb *dvnode_scb) 714 + void afs_fs_remove_file(struct afs_operation *op) 693 715 { 694 - struct afs_vnode *dvnode = fc->vnode; 716 + const struct qstr *name = &op->dentry->d_name; 717 + struct afs_vnode_param *dvp = &op->file[0]; 695 718 struct afs_call *call; 696 - struct afs_net *net = afs_v2net(dvnode); 697 719 size_t namesz, reqsz, padsz; 698 720 __be32 *bp; 699 721 700 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 701 - return yfs_fs_remove(fc, vnode, name, isdir, dvnode_scb); 702 - 703 722 _enter(""); 704 723 705 - namesz = strlen(name); 724 + namesz = name->len; 706 725 padsz = (4 - (namesz & 3)) & 3; 707 726 reqsz = (5 * 4) + namesz + padsz; 708 727 709 - call = afs_alloc_flat_call( 710 - net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile, 711 - reqsz, (21 + 6) * 4); 728 + call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveFile, 729 + reqsz, (21 + 6) * 4); 712 730 if (!call) 713 - return -ENOMEM; 714 - 715 - call->key = fc->key; 716 - call->out_dir_scb = dvnode_scb; 731 + return afs_op_nomem(op); 717 732 718 733 /* marshall the parameters */ 719 734 bp = call->request; 720 - *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE); 721 - *bp++ = htonl(dvnode->fid.vid); 722 - *bp++ = htonl(dvnode->fid.vnode); 723 - *bp++ = htonl(dvnode->fid.unique); 735 + *bp++ = htonl(FSREMOVEFILE); 736 + *bp++ = htonl(dvp->fid.vid); 737 + *bp++ = htonl(dvp->fid.vnode); 738 + *bp++ = htonl(dvp->fid.unique); 724 739 *bp++ = htonl(namesz); 725 - memcpy(bp, name, namesz); 740 + memcpy(bp, name->name, namesz); 726 741 bp = (void *) bp + namesz; 727 742 if (padsz > 0) { 728 743 memset(bp, 0, padsz); 729 744 bp = (void *) bp + padsz; 730 745 } 731 746 732 - afs_use_fs_server(call, fc->cbi); 733 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 734 - afs_set_fc_call(call, fc); 735 - afs_make_call(&fc->ac, call, GFP_NOFS); 736 - return afs_wait_for_call_to_complete(call, &fc->ac); 747 + trace_afs_make_fs_call1(call, &dvp->fid, name); 748 + afs_make_op_call(op, call, GFP_NOFS); 749 + } 750 + 751 + static const struct afs_call_type afs_RXFSRemoveDir = { 752 + .name = "FS.RemoveDir", 753 + .op = afs_FS_RemoveDir, 754 + .deliver = afs_deliver_fs_file_status_and_vol, 755 + .destructor = afs_flat_call_destructor, 756 + }; 757 + 758 + /* 759 + * Remove a directory. 760 + */ 761 + void afs_fs_remove_dir(struct afs_operation *op) 762 + { 763 + const struct qstr *name = &op->dentry->d_name; 764 + struct afs_vnode_param *dvp = &op->file[0]; 765 + struct afs_call *call; 766 + size_t namesz, reqsz, padsz; 767 + __be32 *bp; 768 + 769 + _enter(""); 770 + 771 + namesz = name->len; 772 + padsz = (4 - (namesz & 3)) & 3; 773 + reqsz = (5 * 4) + namesz + padsz; 774 + 775 + call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveDir, 776 + reqsz, (21 + 6) * 4); 777 + if (!call) 778 + return afs_op_nomem(op); 779 + 780 + /* marshall the parameters */ 781 + bp = call->request; 782 + *bp++ = htonl(FSREMOVEDIR); 783 + *bp++ = htonl(dvp->fid.vid); 784 + *bp++ = htonl(dvp->fid.vnode); 785 + *bp++ = htonl(dvp->fid.unique); 786 + *bp++ = htonl(namesz); 787 + memcpy(bp, name->name, namesz); 788 + bp = (void *) bp + namesz; 789 + if (padsz > 0) { 790 + memset(bp, 0, padsz); 791 + bp = (void *) bp + padsz; 792 + } 793 + 794 + trace_afs_make_fs_call1(call, &dvp->fid, name); 795 + afs_make_op_call(op, call, GFP_NOFS); 737 796 } 738 797 739 798 /* ··· 768 773 */ 769 774 static int afs_deliver_fs_link(struct afs_call *call) 770 775 { 776 + struct afs_operation *op = call->op; 777 + struct afs_vnode_param *dvp = &op->file[0]; 778 + struct afs_vnode_param *vp = &op->file[1]; 771 779 const __be32 *bp; 772 780 int ret; 773 781 ··· 782 784 783 785 /* unmarshall the reply once we've received all of it */ 784 786 bp = call->buffer; 785 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 786 - if (ret < 0) 787 - return ret; 788 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb); 789 - if (ret < 0) 790 - return ret; 791 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 787 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 788 + xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb); 789 + xdr_decode_AFSVolSync(&bp, &op->volsync); 792 790 793 791 _leave(" = 0 [done]"); 794 792 return 0; ··· 803 809 /* 804 810 * make a hard link 805 811 */ 806 - int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 807 - const char *name, 808 - struct afs_status_cb *dvnode_scb, 809 - struct afs_status_cb *vnode_scb) 812 + void afs_fs_link(struct afs_operation *op) 810 813 { 811 - struct afs_vnode *dvnode = fc->vnode; 814 + const struct qstr *name = &op->dentry->d_name; 815 + struct afs_vnode_param *dvp = &op->file[0]; 816 + struct afs_vnode_param *vp = &op->file[1]; 812 817 struct afs_call *call; 813 - struct afs_net *net = afs_v2net(vnode); 814 818 size_t namesz, reqsz, padsz; 815 819 __be32 *bp; 816 820 817 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 818 - return yfs_fs_link(fc, vnode, name, dvnode_scb, vnode_scb); 819 - 820 821 _enter(""); 821 822 822 - namesz = strlen(name); 823 + namesz = name->len; 823 824 padsz = (4 - (namesz & 3)) & 3; 824 825 reqsz = (5 * 4) + namesz + padsz + (3 * 4); 825 826 826 - call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4); 827 + call = afs_alloc_flat_call(op->net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4); 827 828 if (!call) 828 - return -ENOMEM; 829 - 830 - call->key = fc->key; 831 - call->out_dir_scb = dvnode_scb; 832 - call->out_scb = vnode_scb; 829 + return afs_op_nomem(op); 833 830 834 831 /* marshall the parameters */ 835 832 bp = call->request; 836 833 *bp++ = htonl(FSLINK); 837 - *bp++ = htonl(dvnode->fid.vid); 838 - *bp++ = htonl(dvnode->fid.vnode); 839 - *bp++ = htonl(dvnode->fid.unique); 834 + *bp++ = htonl(dvp->fid.vid); 835 + *bp++ = htonl(dvp->fid.vnode); 836 + *bp++ = htonl(dvp->fid.unique); 840 837 *bp++ = htonl(namesz); 841 - memcpy(bp, name, namesz); 838 + memcpy(bp, name->name, namesz); 842 839 bp = (void *) bp + namesz; 843 840 if (padsz > 0) { 844 841 memset(bp, 0, padsz); 845 842 bp = (void *) bp + padsz; 846 843 } 847 - *bp++ = htonl(vnode->fid.vid); 848 - *bp++ = htonl(vnode->fid.vnode); 849 - *bp++ = htonl(vnode->fid.unique); 844 + *bp++ = htonl(vp->fid.vid); 845 + *bp++ = htonl(vp->fid.vnode); 846 + *bp++ = htonl(vp->fid.unique); 850 847 851 - afs_use_fs_server(call, fc->cbi); 852 - trace_afs_make_fs_call1(call, &vnode->fid, name); 853 - afs_set_fc_call(call, fc); 854 - afs_make_call(&fc->ac, call, GFP_NOFS); 855 - return afs_wait_for_call_to_complete(call, &fc->ac); 848 + trace_afs_make_fs_call1(call, &vp->fid, name); 849 + afs_make_op_call(op, call, GFP_NOFS); 856 850 } 857 851 858 852 /* ··· 848 866 */ 849 867 static int afs_deliver_fs_symlink(struct afs_call *call) 850 868 { 869 + struct afs_operation *op = call->op; 870 + struct afs_vnode_param *dvp = &op->file[0]; 871 + struct afs_vnode_param *vp = &op->file[1]; 851 872 const __be32 *bp; 852 873 int ret; 853 874 ··· 862 877 863 878 /* unmarshall the reply once we've received all of it */ 864 879 bp = call->buffer; 865 - xdr_decode_AFSFid(&bp, call->out_fid); 866 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 867 - if (ret < 0) 868 - return ret; 869 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb); 870 - if (ret < 0) 871 - return ret; 872 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 880 + xdr_decode_AFSFid(&bp, &vp->fid); 881 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 882 + xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb); 883 + xdr_decode_AFSVolSync(&bp, &op->volsync); 873 884 874 885 _leave(" = 0 [done]"); 875 886 return 0; ··· 884 903 /* 885 904 * create a symbolic link 886 905 */ 887 - int afs_fs_symlink(struct afs_fs_cursor *fc, 888 - const char *name, 889 - const char *contents, 890 - struct afs_status_cb *dvnode_scb, 891 - struct afs_fid *newfid, 892 - struct afs_status_cb *new_scb) 906 + void afs_fs_symlink(struct afs_operation *op) 893 907 { 894 - struct afs_vnode *dvnode = fc->vnode; 908 + const struct qstr *name = &op->dentry->d_name; 909 + struct afs_vnode_param *dvp = &op->file[0]; 895 910 struct afs_call *call; 896 - struct afs_net *net = afs_v2net(dvnode); 897 911 size_t namesz, reqsz, padsz, c_namesz, c_padsz; 898 912 __be32 *bp; 899 913 900 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 901 - return yfs_fs_symlink(fc, name, contents, dvnode_scb, 902 - newfid, new_scb); 903 - 904 914 _enter(""); 905 915 906 - namesz = strlen(name); 916 + namesz = name->len; 907 917 padsz = (4 - (namesz & 3)) & 3; 908 918 909 - c_namesz = strlen(contents); 919 + c_namesz = strlen(op->create.symlink); 910 920 c_padsz = (4 - (c_namesz & 3)) & 3; 911 921 912 922 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4); 913 923 914 - call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz, 924 + call = afs_alloc_flat_call(op->net, &afs_RXFSSymlink, reqsz, 915 925 (3 + 21 + 21 + 6) * 4); 916 926 if (!call) 917 - return -ENOMEM; 918 - 919 - call->key = fc->key; 920 - call->out_dir_scb = dvnode_scb; 921 - call->out_fid = newfid; 922 - call->out_scb = new_scb; 927 + return afs_op_nomem(op); 923 928 924 929 /* marshall the parameters */ 925 930 bp = call->request; 926 931 *bp++ = htonl(FSSYMLINK); 927 - *bp++ = htonl(dvnode->fid.vid); 928 - *bp++ = htonl(dvnode->fid.vnode); 929 - *bp++ = htonl(dvnode->fid.unique); 932 + *bp++ = htonl(dvp->fid.vid); 933 + *bp++ = htonl(dvp->fid.vnode); 934 + *bp++ = htonl(dvp->fid.unique); 930 935 *bp++ = htonl(namesz); 931 - memcpy(bp, name, namesz); 936 + memcpy(bp, name->name, namesz); 932 937 bp = (void *) bp + namesz; 933 938 if (padsz > 0) { 934 939 memset(bp, 0, padsz); 935 940 bp = (void *) bp + padsz; 936 941 } 937 942 *bp++ = htonl(c_namesz); 938 - memcpy(bp, contents, c_namesz); 943 + memcpy(bp, op->create.symlink, c_namesz); 939 944 bp = (void *) bp + c_namesz; 940 945 if (c_padsz > 0) { 941 946 memset(bp, 0, c_padsz); 942 947 bp = (void *) bp + c_padsz; 943 948 } 944 949 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); 945 - *bp++ = htonl(dvnode->vfs_inode.i_mtime.tv_sec); /* mtime */ 950 + *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 946 951 *bp++ = 0; /* owner */ 947 952 *bp++ = 0; /* group */ 948 953 *bp++ = htonl(S_IRWXUGO); /* unix mode */ 949 954 *bp++ = 0; /* segment size */ 950 955 951 - afs_use_fs_server(call, fc->cbi); 952 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 953 - afs_set_fc_call(call, fc); 954 - afs_make_call(&fc->ac, call, GFP_NOFS); 955 - return afs_wait_for_call_to_complete(call, &fc->ac); 956 + trace_afs_make_fs_call1(call, &dvp->fid, name); 957 + afs_make_op_call(op, call, GFP_NOFS); 956 958 } 957 959 958 960 /* ··· 943 979 */ 944 980 static int afs_deliver_fs_rename(struct afs_call *call) 945 981 { 982 + struct afs_operation *op = call->op; 983 + struct afs_vnode_param *orig_dvp = &op->file[0]; 984 + struct afs_vnode_param *new_dvp = &op->file[1]; 946 985 const __be32 *bp; 947 986 int ret; 948 987 ··· 953 986 if (ret < 0) 954 987 return ret; 955 988 989 + bp = call->buffer; 956 990 /* If the two dirs are the same, we have two copies of the same status 957 991 * report, so we just decode it twice. 958 992 */ 959 - bp = call->buffer; 960 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb); 961 - if (ret < 0) 962 - return ret; 963 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 964 - if (ret < 0) 965 - return ret; 966 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 993 + xdr_decode_AFSFetchStatus(&bp, call, &orig_dvp->scb); 994 + xdr_decode_AFSFetchStatus(&bp, call, &new_dvp->scb); 995 + xdr_decode_AFSVolSync(&bp, &op->volsync); 967 996 968 997 _leave(" = 0 [done]"); 969 998 return 0; ··· 978 1015 /* 979 1016 * Rename/move a file or directory. 980 1017 */ 981 - int afs_fs_rename(struct afs_fs_cursor *fc, 982 - const char *orig_name, 983 - struct afs_vnode *new_dvnode, 984 - const char *new_name, 985 - struct afs_status_cb *orig_dvnode_scb, 986 - struct afs_status_cb *new_dvnode_scb) 1018 + void afs_fs_rename(struct afs_operation *op) 987 1019 { 988 - struct afs_vnode *orig_dvnode = fc->vnode; 1020 + struct afs_vnode_param *orig_dvp = &op->file[0]; 1021 + struct afs_vnode_param *new_dvp = &op->file[1]; 1022 + const struct qstr *orig_name = &op->dentry->d_name; 1023 + const struct qstr *new_name = &op->dentry_2->d_name; 989 1024 struct afs_call *call; 990 - struct afs_net *net = afs_v2net(orig_dvnode); 991 1025 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz; 992 1026 __be32 *bp; 993 1027 994 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 995 - return yfs_fs_rename(fc, orig_name, 996 - new_dvnode, new_name, 997 - orig_dvnode_scb, 998 - new_dvnode_scb); 999 - 1000 1028 _enter(""); 1001 1029 1002 - o_namesz = strlen(orig_name); 1030 + o_namesz = orig_name->len; 1003 1031 o_padsz = (4 - (o_namesz & 3)) & 3; 1004 1032 1005 - n_namesz = strlen(new_name); 1033 + n_namesz = new_name->len; 1006 1034 n_padsz = (4 - (n_namesz & 3)) & 3; 1007 1035 1008 1036 reqsz = (4 * 4) + ··· 1001 1047 (3 * 4) + 1002 1048 4 + n_namesz + n_padsz; 1003 1049 1004 - call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4); 1050 + call = afs_alloc_flat_call(op->net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4); 1005 1051 if (!call) 1006 - return -ENOMEM; 1007 - 1008 - call->key = fc->key; 1009 - call->out_dir_scb = orig_dvnode_scb; 1010 - call->out_scb = new_dvnode_scb; 1052 + return afs_op_nomem(op); 1011 1053 1012 1054 /* marshall the parameters */ 1013 1055 bp = call->request; 1014 1056 *bp++ = htonl(FSRENAME); 1015 - *bp++ = htonl(orig_dvnode->fid.vid); 1016 - *bp++ = htonl(orig_dvnode->fid.vnode); 1017 - *bp++ = htonl(orig_dvnode->fid.unique); 1057 + *bp++ = htonl(orig_dvp->fid.vid); 1058 + *bp++ = htonl(orig_dvp->fid.vnode); 1059 + *bp++ = htonl(orig_dvp->fid.unique); 1018 1060 *bp++ = htonl(o_namesz); 1019 - memcpy(bp, orig_name, o_namesz); 1061 + memcpy(bp, orig_name->name, o_namesz); 1020 1062 bp = (void *) bp + o_namesz; 1021 1063 if (o_padsz > 0) { 1022 1064 memset(bp, 0, o_padsz); 1023 1065 bp = (void *) bp + o_padsz; 1024 1066 } 1025 1067 1026 - *bp++ = htonl(new_dvnode->fid.vid); 1027 - *bp++ = htonl(new_dvnode->fid.vnode); 1028 - *bp++ = htonl(new_dvnode->fid.unique); 1068 + *bp++ = htonl(new_dvp->fid.vid); 1069 + *bp++ = htonl(new_dvp->fid.vnode); 1070 + *bp++ = htonl(new_dvp->fid.unique); 1029 1071 *bp++ = htonl(n_namesz); 1030 - memcpy(bp, new_name, n_namesz); 1072 + memcpy(bp, new_name->name, n_namesz); 1031 1073 bp = (void *) bp + n_namesz; 1032 1074 if (n_padsz > 0) { 1033 1075 memset(bp, 0, n_padsz); 1034 1076 bp = (void *) bp + n_padsz; 1035 1077 } 1036 1078 1037 - afs_use_fs_server(call, fc->cbi); 1038 - trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name); 1039 - afs_set_fc_call(call, fc); 1040 - afs_make_call(&fc->ac, call, GFP_NOFS); 1041 - return afs_wait_for_call_to_complete(call, &fc->ac); 1079 + trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name); 1080 + afs_make_op_call(op, call, GFP_NOFS); 1042 1081 } 1043 1082 1044 1083 /* 1045 - * deliver reply data to an FS.StoreData 1084 + * Deliver reply data to FS.StoreData or FS.StoreStatus 1046 1085 */ 1047 1086 static int afs_deliver_fs_store_data(struct afs_call *call) 1048 1087 { 1088 + struct afs_operation *op = call->op; 1089 + struct afs_vnode_param *vp = &op->file[0]; 1049 1090 const __be32 *bp; 1050 1091 int ret; 1051 1092 ··· 1052 1103 1053 1104 /* unmarshall the reply once we've received all of it */ 1054 1105 bp = call->buffer; 1055 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 1056 - if (ret < 0) 1057 - return ret; 1058 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 1106 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 1107 + xdr_decode_AFSVolSync(&bp, &op->volsync); 1059 1108 1060 1109 _leave(" = 0 [done]"); 1061 1110 return 0; ··· 1079 1132 /* 1080 1133 * store a set of pages to a very large file 1081 1134 */ 1082 - static int afs_fs_store_data64(struct afs_fs_cursor *fc, 1083 - struct address_space *mapping, 1084 - pgoff_t first, pgoff_t last, 1085 - unsigned offset, unsigned to, 1086 - loff_t size, loff_t pos, loff_t i_size, 1087 - struct afs_status_cb *scb) 1135 + static void afs_fs_store_data64(struct afs_operation *op, 1136 + loff_t pos, loff_t size, loff_t i_size) 1088 1137 { 1089 - struct afs_vnode *vnode = fc->vnode; 1138 + struct afs_vnode_param *vp = &op->file[0]; 1090 1139 struct afs_call *call; 1091 - struct afs_net *net = afs_v2net(vnode); 1092 1140 __be32 *bp; 1093 1141 1094 1142 _enter(",%x,{%llx:%llu},,", 1095 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1143 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1096 1144 1097 - call = afs_alloc_flat_call(net, &afs_RXFSStoreData64, 1145 + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64, 1098 1146 (4 + 6 + 3 * 2) * 4, 1099 1147 (21 + 6) * 4); 1100 1148 if (!call) 1101 - return -ENOMEM; 1149 + return afs_op_nomem(op); 1102 1150 1103 - call->key = fc->key; 1104 - call->mapping = mapping; 1105 - call->first = first; 1106 - call->last = last; 1107 - call->first_offset = offset; 1108 - call->last_to = to; 1109 1151 call->send_pages = true; 1110 - call->out_scb = scb; 1111 1152 1112 1153 /* marshall the parameters */ 1113 1154 bp = call->request; 1114 1155 *bp++ = htonl(FSSTOREDATA64); 1115 - *bp++ = htonl(vnode->fid.vid); 1116 - *bp++ = htonl(vnode->fid.vnode); 1117 - *bp++ = htonl(vnode->fid.unique); 1156 + *bp++ = htonl(vp->fid.vid); 1157 + *bp++ = htonl(vp->fid.vnode); 1158 + *bp++ = htonl(vp->fid.unique); 1118 1159 1119 1160 *bp++ = htonl(AFS_SET_MTIME); /* mask */ 1120 - *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ 1161 + *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 1121 1162 *bp++ = 0; /* owner */ 1122 1163 *bp++ = 0; /* group */ 1123 1164 *bp++ = 0; /* unix mode */ 1124 1165 *bp++ = 0; /* segment size */ 1125 1166 1126 - *bp++ = htonl(pos >> 32); 1127 - *bp++ = htonl((u32) pos); 1128 - *bp++ = htonl(size >> 32); 1129 - *bp++ = htonl((u32) size); 1130 - *bp++ = htonl(i_size >> 32); 1131 - *bp++ = htonl((u32) i_size); 1167 + *bp++ = htonl(upper_32_bits(pos)); 1168 + *bp++ = htonl(lower_32_bits(pos)); 1169 + *bp++ = htonl(upper_32_bits(size)); 1170 + *bp++ = htonl(lower_32_bits(size)); 1171 + *bp++ = htonl(upper_32_bits(i_size)); 1172 + *bp++ = htonl(lower_32_bits(i_size)); 1132 1173 1133 - trace_afs_make_fs_call(call, &vnode->fid); 1134 - afs_set_fc_call(call, fc); 1135 - afs_make_call(&fc->ac, call, GFP_NOFS); 1136 - return afs_wait_for_call_to_complete(call, &fc->ac); 1174 + trace_afs_make_fs_call(call, &vp->fid); 1175 + afs_make_op_call(op, call, GFP_NOFS); 1137 1176 } 1138 1177 1139 1178 /* 1140 1179 * store a set of pages 1141 1180 */ 1142 - int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, 1143 - pgoff_t first, pgoff_t last, 1144 - unsigned offset, unsigned to, 1145 - struct afs_status_cb *scb) 1181 + void afs_fs_store_data(struct afs_operation *op) 1146 1182 { 1147 - struct afs_vnode *vnode = fc->vnode; 1183 + struct afs_vnode_param *vp = &op->file[0]; 1148 1184 struct afs_call *call; 1149 - struct afs_net *net = afs_v2net(vnode); 1150 1185 loff_t size, pos, i_size; 1151 1186 __be32 *bp; 1152 1187 1153 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1154 - return yfs_fs_store_data(fc, mapping, first, last, offset, to, scb); 1155 - 1156 1188 _enter(",%x,{%llx:%llu},,", 1157 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1189 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1158 1190 1159 - size = (loff_t)to - (loff_t)offset; 1160 - if (first != last) 1161 - size += (loff_t)(last - first) << PAGE_SHIFT; 1162 - pos = (loff_t)first << PAGE_SHIFT; 1163 - pos += offset; 1191 + size = (loff_t)op->store.last_to - (loff_t)op->store.first_offset; 1192 + if (op->store.first != op->store.last) 1193 + size += (loff_t)(op->store.last - op->store.first) << PAGE_SHIFT; 1194 + pos = (loff_t)op->store.first << PAGE_SHIFT; 1195 + pos += op->store.first_offset; 1164 1196 1165 - i_size = i_size_read(&vnode->vfs_inode); 1197 + i_size = i_size_read(&vp->vnode->vfs_inode); 1166 1198 if (pos + size > i_size) 1167 1199 i_size = size + pos; 1168 1200 ··· 1149 1223 (unsigned long long) size, (unsigned long long) pos, 1150 1224 (unsigned long long) i_size); 1151 1225 1152 - if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32) 1153 - return afs_fs_store_data64(fc, mapping, first, last, offset, to, 1154 - size, pos, i_size, scb); 1226 + if (upper_32_bits(pos) || upper_32_bits(i_size) || upper_32_bits(size) || 1227 + upper_32_bits(pos + size)) 1228 + return afs_fs_store_data64(op, pos, size, i_size); 1155 1229 1156 - call = afs_alloc_flat_call(net, &afs_RXFSStoreData, 1230 + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData, 1157 1231 (4 + 6 + 3) * 4, 1158 1232 (21 + 6) * 4); 1159 1233 if (!call) 1160 - return -ENOMEM; 1234 + return afs_op_nomem(op); 1161 1235 1162 - call->key = fc->key; 1163 - call->mapping = mapping; 1164 - call->first = first; 1165 - call->last = last; 1166 - call->first_offset = offset; 1167 - call->last_to = to; 1168 1236 call->send_pages = true; 1169 - call->out_scb = scb; 1170 1237 1171 1238 /* marshall the parameters */ 1172 1239 bp = call->request; 1173 1240 *bp++ = htonl(FSSTOREDATA); 1174 - *bp++ = htonl(vnode->fid.vid); 1175 - *bp++ = htonl(vnode->fid.vnode); 1176 - *bp++ = htonl(vnode->fid.unique); 1241 + *bp++ = htonl(vp->fid.vid); 1242 + *bp++ = htonl(vp->fid.vnode); 1243 + *bp++ = htonl(vp->fid.unique); 1177 1244 1178 1245 *bp++ = htonl(AFS_SET_MTIME); /* mask */ 1179 - *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ 1246 + *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 1180 1247 *bp++ = 0; /* owner */ 1181 1248 *bp++ = 0; /* group */ 1182 1249 *bp++ = 0; /* unix mode */ 1183 1250 *bp++ = 0; /* segment size */ 1184 1251 1185 - *bp++ = htonl(pos); 1186 - *bp++ = htonl(size); 1187 - *bp++ = htonl(i_size); 1252 + *bp++ = htonl(lower_32_bits(pos)); 1253 + *bp++ = htonl(lower_32_bits(size)); 1254 + *bp++ = htonl(lower_32_bits(i_size)); 1188 1255 1189 - afs_use_fs_server(call, fc->cbi); 1190 - trace_afs_make_fs_call(call, &vnode->fid); 1191 - afs_set_fc_call(call, fc); 1192 - afs_make_call(&fc->ac, call, GFP_NOFS); 1193 - return afs_wait_for_call_to_complete(call, &fc->ac); 1194 - } 1195 - 1196 - /* 1197 - * deliver reply data to an FS.StoreStatus 1198 - */ 1199 - static int afs_deliver_fs_store_status(struct afs_call *call) 1200 - { 1201 - const __be32 *bp; 1202 - int ret; 1203 - 1204 - _enter(""); 1205 - 1206 - ret = afs_transfer_reply(call); 1207 - if (ret < 0) 1208 - return ret; 1209 - 1210 - /* unmarshall the reply once we've received all of it */ 1211 - bp = call->buffer; 1212 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 1213 - if (ret < 0) 1214 - return ret; 1215 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 1216 - 1217 - _leave(" = 0 [done]"); 1218 - return 0; 1256 + trace_afs_make_fs_call(call, &vp->fid); 1257 + afs_make_op_call(op, call, GFP_NOFS); 1219 1258 } 1220 1259 1221 1260 /* ··· 1189 1298 static const struct afs_call_type afs_RXFSStoreStatus = { 1190 1299 .name = "FS.StoreStatus", 1191 1300 .op = afs_FS_StoreStatus, 1192 - .deliver = afs_deliver_fs_store_status, 1301 + .deliver = afs_deliver_fs_store_data, 1193 1302 .destructor = afs_flat_call_destructor, 1194 1303 }; 1195 1304 1196 1305 static const struct afs_call_type afs_RXFSStoreData_as_Status = { 1197 1306 .name = "FS.StoreData", 1198 1307 .op = afs_FS_StoreData, 1199 - .deliver = afs_deliver_fs_store_status, 1308 + .deliver = afs_deliver_fs_store_data, 1200 1309 .destructor = afs_flat_call_destructor, 1201 1310 }; 1202 1311 1203 1312 static const struct afs_call_type afs_RXFSStoreData64_as_Status = { 1204 1313 .name = "FS.StoreData64", 1205 1314 .op = afs_FS_StoreData64, 1206 - .deliver = afs_deliver_fs_store_status, 1315 + .deliver = afs_deliver_fs_store_data, 1207 1316 .destructor = afs_flat_call_destructor, 1208 1317 }; 1209 1318 ··· 1211 1320 * set the attributes on a very large file, using FS.StoreData rather than 1212 1321 * FS.StoreStatus so as to alter the file size also 1213 1322 */ 1214 - static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr, 1215 - struct afs_status_cb *scb) 1323 + static void afs_fs_setattr_size64(struct afs_operation *op) 1216 1324 { 1217 - struct afs_vnode *vnode = fc->vnode; 1325 + struct afs_vnode_param *vp = &op->file[0]; 1218 1326 struct afs_call *call; 1219 - struct afs_net *net = afs_v2net(vnode); 1327 + struct iattr *attr = op->setattr.attr; 1220 1328 __be32 *bp; 1221 1329 1222 1330 _enter(",%x,{%llx:%llu},,", 1223 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1331 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1224 1332 1225 1333 ASSERT(attr->ia_valid & ATTR_SIZE); 1226 1334 1227 - call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status, 1335 + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64_as_Status, 1228 1336 (4 + 6 + 3 * 2) * 4, 1229 1337 (21 + 6) * 4); 1230 1338 if (!call) 1231 - return -ENOMEM; 1232 - 1233 - call->key = fc->key; 1234 - call->out_scb = scb; 1339 + return afs_op_nomem(op); 1235 1340 1236 1341 /* marshall the parameters */ 1237 1342 bp = call->request; 1238 1343 *bp++ = htonl(FSSTOREDATA64); 1239 - *bp++ = htonl(vnode->fid.vid); 1240 - *bp++ = htonl(vnode->fid.vnode); 1241 - *bp++ = htonl(vnode->fid.unique); 1344 + *bp++ = htonl(vp->fid.vid); 1345 + *bp++ = htonl(vp->fid.vnode); 1346 + *bp++ = htonl(vp->fid.unique); 1242 1347 1243 1348 xdr_encode_AFS_StoreStatus(&bp, attr); 1244 1349 1245 - *bp++ = htonl(attr->ia_size >> 32); /* position of start of write */ 1246 - *bp++ = htonl((u32) attr->ia_size); 1247 - *bp++ = 0; /* size of write */ 1350 + *bp++ = htonl(upper_32_bits(attr->ia_size)); /* position of start of write */ 1351 + *bp++ = htonl(lower_32_bits(attr->ia_size)); 1352 + *bp++ = 0; /* size of write */ 1248 1353 *bp++ = 0; 1249 - *bp++ = htonl(attr->ia_size >> 32); /* new file length */ 1250 - *bp++ = htonl((u32) attr->ia_size); 1354 + *bp++ = htonl(upper_32_bits(attr->ia_size)); /* new file length */ 1355 + *bp++ = htonl(lower_32_bits(attr->ia_size)); 1251 1356 1252 - afs_use_fs_server(call, fc->cbi); 1253 - trace_afs_make_fs_call(call, &vnode->fid); 1254 - afs_set_fc_call(call, fc); 1255 - afs_make_call(&fc->ac, call, GFP_NOFS); 1256 - return afs_wait_for_call_to_complete(call, &fc->ac); 1357 + trace_afs_make_fs_call(call, &vp->fid); 1358 + afs_make_op_call(op, call, GFP_NOFS); 1257 1359 } 1258 1360 1259 1361 /* 1260 1362 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus 1261 1363 * so as to alter the file size also 1262 1364 */ 1263 - static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr, 1264 - struct afs_status_cb *scb) 1365 + static void afs_fs_setattr_size(struct afs_operation *op) 1265 1366 { 1266 - struct afs_vnode *vnode = fc->vnode; 1367 + struct afs_vnode_param *vp = &op->file[0]; 1267 1368 struct afs_call *call; 1268 - struct afs_net *net = afs_v2net(vnode); 1369 + struct iattr *attr = op->setattr.attr; 1269 1370 __be32 *bp; 1270 1371 1271 1372 _enter(",%x,{%llx:%llu},,", 1272 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1373 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1273 1374 1274 1375 ASSERT(attr->ia_valid & ATTR_SIZE); 1275 - if (attr->ia_size >> 32) 1276 - return afs_fs_setattr_size64(fc, attr, scb); 1376 + if (upper_32_bits(attr->ia_size)) 1377 + return afs_fs_setattr_size64(op); 1277 1378 1278 - call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status, 1379 + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status, 1279 1380 (4 + 6 + 3) * 4, 1280 1381 (21 + 6) * 4); 1281 1382 if (!call) 1282 - return -ENOMEM; 1283 - 1284 - call->key = fc->key; 1285 - call->out_scb = scb; 1383 + return afs_op_nomem(op); 1286 1384 1287 1385 /* marshall the parameters */ 1288 1386 bp = call->request; 1289 1387 *bp++ = htonl(FSSTOREDATA); 1290 - *bp++ = htonl(vnode->fid.vid); 1291 - *bp++ = htonl(vnode->fid.vnode); 1292 - *bp++ = htonl(vnode->fid.unique); 1388 + *bp++ = htonl(vp->fid.vid); 1389 + *bp++ = htonl(vp->fid.vnode); 1390 + *bp++ = htonl(vp->fid.unique); 1293 1391 1294 1392 xdr_encode_AFS_StoreStatus(&bp, attr); 1295 1393 ··· 1286 1406 *bp++ = 0; /* size of write */ 1287 1407 *bp++ = htonl(attr->ia_size); /* new file length */ 1288 1408 1289 - afs_use_fs_server(call, fc->cbi); 1290 - trace_afs_make_fs_call(call, &vnode->fid); 1291 - afs_set_fc_call(call, fc); 1292 - afs_make_call(&fc->ac, call, GFP_NOFS); 1293 - return afs_wait_for_call_to_complete(call, &fc->ac); 1409 + trace_afs_make_fs_call(call, &vp->fid); 1410 + afs_make_op_call(op, call, GFP_NOFS); 1294 1411 } 1295 1412 1296 1413 /* 1297 1414 * set the attributes on a file, using FS.StoreData if there's a change in file 1298 1415 * size, and FS.StoreStatus otherwise 1299 1416 */ 1300 - int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr, 1301 - struct afs_status_cb *scb) 1417 + void afs_fs_setattr(struct afs_operation *op) 1302 1418 { 1303 - struct afs_vnode *vnode = fc->vnode; 1419 + struct afs_vnode_param *vp = &op->file[0]; 1304 1420 struct afs_call *call; 1305 - struct afs_net *net = afs_v2net(vnode); 1421 + struct iattr *attr = op->setattr.attr; 1306 1422 __be32 *bp; 1307 1423 1308 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1309 - return yfs_fs_setattr(fc, attr, scb); 1310 - 1311 1424 if (attr->ia_valid & ATTR_SIZE) 1312 - return afs_fs_setattr_size(fc, attr, scb); 1425 + return afs_fs_setattr_size(op); 1313 1426 1314 1427 _enter(",%x,{%llx:%llu},,", 1315 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1428 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1316 1429 1317 - call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus, 1430 + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreStatus, 1318 1431 (4 + 6) * 4, 1319 1432 (21 + 6) * 4); 1320 1433 if (!call) 1321 - return -ENOMEM; 1322 - 1323 - call->key = fc->key; 1324 - call->out_scb = scb; 1434 + return afs_op_nomem(op); 1325 1435 1326 1436 /* marshall the parameters */ 1327 1437 bp = call->request; 1328 1438 *bp++ = htonl(FSSTORESTATUS); 1329 - *bp++ = htonl(vnode->fid.vid); 1330 - *bp++ = htonl(vnode->fid.vnode); 1331 - *bp++ = htonl(vnode->fid.unique); 1439 + *bp++ = htonl(vp->fid.vid); 1440 + *bp++ = htonl(vp->fid.vnode); 1441 + *bp++ = htonl(vp->fid.unique); 1332 1442 1333 - xdr_encode_AFS_StoreStatus(&bp, attr); 1443 + xdr_encode_AFS_StoreStatus(&bp, op->setattr.attr); 1334 1444 1335 - afs_use_fs_server(call, fc->cbi); 1336 - trace_afs_make_fs_call(call, &vnode->fid); 1337 - afs_set_fc_call(call, fc); 1338 - afs_make_call(&fc->ac, call, GFP_NOFS); 1339 - return afs_wait_for_call_to_complete(call, &fc->ac); 1445 + trace_afs_make_fs_call(call, &vp->fid); 1446 + afs_make_op_call(op, call, GFP_NOFS); 1340 1447 } 1341 1448 1342 1449 /* ··· 1331 1464 */ 1332 1465 static int afs_deliver_fs_get_volume_status(struct afs_call *call) 1333 1466 { 1467 + struct afs_operation *op = call->op; 1334 1468 const __be32 *bp; 1335 1469 char *p; 1336 1470 u32 size; ··· 1353 1485 return ret; 1354 1486 1355 1487 bp = call->buffer; 1356 - xdr_decode_AFSFetchVolumeStatus(&bp, call->out_volstatus); 1488 + xdr_decode_AFSFetchVolumeStatus(&bp, &op->volstatus.vs); 1357 1489 call->unmarshall++; 1358 1490 afs_extract_to_tmp(call); 1359 1491 /* Fall through */ ··· 1367 1499 call->count = ntohl(call->tmp); 1368 1500 _debug("volname length: %u", call->count); 1369 1501 if (call->count >= AFSNAMEMAX) 1370 - return afs_protocol_error(call, -EBADMSG, 1371 - afs_eproto_volname_len); 1502 + return afs_protocol_error(call, afs_eproto_volname_len); 1372 1503 size = (call->count + 3) & ~3; /* It's padded */ 1373 1504 afs_extract_to_buf(call, size); 1374 1505 call->unmarshall++; ··· 1396 1529 call->count = ntohl(call->tmp); 1397 1530 _debug("offline msg length: %u", call->count); 1398 1531 if (call->count >= AFSNAMEMAX) 1399 - return afs_protocol_error(call, -EBADMSG, 1400 - afs_eproto_offline_msg_len); 1532 + return afs_protocol_error(call, afs_eproto_offline_msg_len); 1401 1533 size = (call->count + 3) & ~3; /* It's padded */ 1402 1534 afs_extract_to_buf(call, size); 1403 1535 call->unmarshall++; ··· 1426 1560 call->count = ntohl(call->tmp); 1427 1561 _debug("motd length: %u", call->count); 1428 1562 if (call->count >= AFSNAMEMAX) 1429 - return afs_protocol_error(call, -EBADMSG, 1430 - afs_eproto_motd_len); 1563 + return afs_protocol_error(call, afs_eproto_motd_len); 1431 1564 size = (call->count + 3) & ~3; /* It's padded */ 1432 1565 afs_extract_to_buf(call, size); 1433 1566 call->unmarshall++; ··· 1466 1601 /* 1467 1602 * fetch the status of a volume 1468 1603 */ 1469 - int afs_fs_get_volume_status(struct afs_fs_cursor *fc, 1470 - struct afs_volume_status *vs) 1604 + void afs_fs_get_volume_status(struct afs_operation *op) 1471 1605 { 1472 - struct afs_vnode *vnode = fc->vnode; 1606 + struct afs_vnode_param *vp = &op->file[0]; 1473 1607 struct afs_call *call; 1474 - struct afs_net *net = afs_v2net(vnode); 1475 1608 __be32 *bp; 1476 - 1477 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1478 - return yfs_fs_get_volume_status(fc, vs); 1479 1609 1480 1610 _enter(""); 1481 1611 1482 - call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 1612 + call = afs_alloc_flat_call(op->net, &afs_RXFSGetVolumeStatus, 2 * 4, 1483 1613 max(12 * 4, AFSOPAQUEMAX + 1)); 1484 1614 if (!call) 1485 - return -ENOMEM; 1486 - 1487 - call->key = fc->key; 1488 - call->out_volstatus = vs; 1615 + return afs_op_nomem(op); 1489 1616 1490 1617 /* marshall the parameters */ 1491 1618 bp = call->request; 1492 1619 bp[0] = htonl(FSGETVOLUMESTATUS); 1493 - bp[1] = htonl(vnode->fid.vid); 1620 + bp[1] = htonl(vp->fid.vid); 1494 1621 1495 - afs_use_fs_server(call, fc->cbi); 1496 - trace_afs_make_fs_call(call, &vnode->fid); 1497 - afs_set_fc_call(call, fc); 1498 - afs_make_call(&fc->ac, call, GFP_NOFS); 1499 - return afs_wait_for_call_to_complete(call, &fc->ac); 1622 + trace_afs_make_fs_call(call, &vp->fid); 1623 + afs_make_op_call(op, call, GFP_NOFS); 1500 1624 } 1501 1625 1502 1626 /* ··· 1493 1639 */ 1494 1640 static int afs_deliver_fs_xxxx_lock(struct afs_call *call) 1495 1641 { 1642 + struct afs_operation *op = call->op; 1496 1643 const __be32 *bp; 1497 1644 int ret; 1498 1645 ··· 1505 1650 1506 1651 /* unmarshall the reply once we've received all of it */ 1507 1652 bp = call->buffer; 1508 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 1653 + xdr_decode_AFSVolSync(&bp, &op->volsync); 1509 1654 1510 1655 _leave(" = 0 [done]"); 1511 1656 return 0; ··· 1546 1691 /* 1547 1692 * Set a lock on a file 1548 1693 */ 1549 - int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type, 1550 - struct afs_status_cb *scb) 1694 + void afs_fs_set_lock(struct afs_operation *op) 1551 1695 { 1552 - struct afs_vnode *vnode = fc->vnode; 1696 + struct afs_vnode_param *vp = &op->file[0]; 1553 1697 struct afs_call *call; 1554 - struct afs_net *net = afs_v2net(vnode); 1555 1698 __be32 *bp; 1556 - 1557 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1558 - return yfs_fs_set_lock(fc, type, scb); 1559 1699 1560 1700 _enter(""); 1561 1701 1562 - call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4); 1702 + call = afs_alloc_flat_call(op->net, &afs_RXFSSetLock, 5 * 4, 6 * 4); 1563 1703 if (!call) 1564 - return -ENOMEM; 1565 - 1566 - call->key = fc->key; 1567 - call->lvnode = vnode; 1568 - call->out_scb = scb; 1704 + return afs_op_nomem(op); 1569 1705 1570 1706 /* marshall the parameters */ 1571 1707 bp = call->request; 1572 1708 *bp++ = htonl(FSSETLOCK); 1573 - *bp++ = htonl(vnode->fid.vid); 1574 - *bp++ = htonl(vnode->fid.vnode); 1575 - *bp++ = htonl(vnode->fid.unique); 1576 - *bp++ = htonl(type); 1709 + *bp++ = htonl(vp->fid.vid); 1710 + *bp++ = htonl(vp->fid.vnode); 1711 + *bp++ = htonl(vp->fid.unique); 1712 + *bp++ = htonl(op->lock.type); 1577 1713 1578 - afs_use_fs_server(call, fc->cbi); 1579 - trace_afs_make_fs_calli(call, &vnode->fid, type); 1580 - afs_set_fc_call(call, fc); 1581 - afs_make_call(&fc->ac, call, GFP_NOFS); 1582 - return afs_wait_for_call_to_complete(call, &fc->ac); 1714 + trace_afs_make_fs_calli(call, &vp->fid, op->lock.type); 1715 + afs_make_op_call(op, call, GFP_NOFS); 1583 1716 } 1584 1717 1585 1718 /* 1586 1719 * extend a lock on a file 1587 1720 */ 1588 - int afs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb) 1721 + void afs_fs_extend_lock(struct afs_operation *op) 1589 1722 { 1590 - struct afs_vnode *vnode = fc->vnode; 1723 + struct afs_vnode_param *vp = &op->file[0]; 1591 1724 struct afs_call *call; 1592 - struct afs_net *net = afs_v2net(vnode); 1593 1725 __be32 *bp; 1594 - 1595 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1596 - return yfs_fs_extend_lock(fc, scb); 1597 1726 1598 1727 _enter(""); 1599 1728 1600 - call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4); 1729 + call = afs_alloc_flat_call(op->net, &afs_RXFSExtendLock, 4 * 4, 6 * 4); 1601 1730 if (!call) 1602 - return -ENOMEM; 1603 - 1604 - call->key = fc->key; 1605 - call->lvnode = vnode; 1606 - call->out_scb = scb; 1731 + return afs_op_nomem(op); 1607 1732 1608 1733 /* marshall the parameters */ 1609 1734 bp = call->request; 1610 1735 *bp++ = htonl(FSEXTENDLOCK); 1611 - *bp++ = htonl(vnode->fid.vid); 1612 - *bp++ = htonl(vnode->fid.vnode); 1613 - *bp++ = htonl(vnode->fid.unique); 1736 + *bp++ = htonl(vp->fid.vid); 1737 + *bp++ = htonl(vp->fid.vnode); 1738 + *bp++ = htonl(vp->fid.unique); 1614 1739 1615 - afs_use_fs_server(call, fc->cbi); 1616 - trace_afs_make_fs_call(call, &vnode->fid); 1617 - afs_set_fc_call(call, fc); 1618 - afs_make_call(&fc->ac, call, GFP_NOFS); 1619 - return afs_wait_for_call_to_complete(call, &fc->ac); 1740 + trace_afs_make_fs_call(call, &vp->fid); 1741 + afs_make_op_call(op, call, GFP_NOFS); 1620 1742 } 1621 1743 1622 1744 /* 1623 1745 * release a lock on a file 1624 1746 */ 1625 - int afs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb) 1747 + void afs_fs_release_lock(struct afs_operation *op) 1626 1748 { 1627 - struct afs_vnode *vnode = fc->vnode; 1749 + struct afs_vnode_param *vp = &op->file[0]; 1628 1750 struct afs_call *call; 1629 - struct afs_net *net = afs_v2net(vnode); 1630 1751 __be32 *bp; 1631 - 1632 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1633 - return yfs_fs_release_lock(fc, scb); 1634 1752 1635 1753 _enter(""); 1636 1754 1637 - call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4); 1755 + call = afs_alloc_flat_call(op->net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4); 1638 1756 if (!call) 1639 - return -ENOMEM; 1640 - 1641 - call->key = fc->key; 1642 - call->lvnode = vnode; 1643 - call->out_scb = scb; 1757 + return afs_op_nomem(op); 1644 1758 1645 1759 /* marshall the parameters */ 1646 1760 bp = call->request; 1647 1761 *bp++ = htonl(FSRELEASELOCK); 1648 - *bp++ = htonl(vnode->fid.vid); 1649 - *bp++ = htonl(vnode->fid.vnode); 1650 - *bp++ = htonl(vnode->fid.unique); 1762 + *bp++ = htonl(vp->fid.vid); 1763 + *bp++ = htonl(vp->fid.vnode); 1764 + *bp++ = htonl(vp->fid.unique); 1651 1765 1652 - afs_use_fs_server(call, fc->cbi); 1653 - trace_afs_make_fs_call(call, &vnode->fid); 1654 - afs_set_fc_call(call, fc); 1655 - afs_make_call(&fc->ac, call, GFP_NOFS); 1656 - return afs_wait_for_call_to_complete(call, &fc->ac); 1766 + trace_afs_make_fs_call(call, &vp->fid); 1767 + afs_make_op_call(op, call, GFP_NOFS); 1657 1768 } 1658 1769 1659 1770 /* ··· 1663 1842 bp = call->request; 1664 1843 *bp++ = htonl(FSGIVEUPALLCALLBACKS); 1665 1844 1666 - /* Can't take a ref on server */ 1845 + call->server = afs_use_server(server, afs_server_trace_give_up_cb); 1667 1846 afs_make_call(ac, call, GFP_NOFS); 1668 1847 return afs_wait_for_call_to_complete(call, ac); 1669 1848 } ··· 1726 1905 }; 1727 1906 1728 1907 /* 1729 - * Probe a fileserver for the capabilities that it supports. This can 1730 - * return up to 196 words. 1908 + * Probe a fileserver for the capabilities that it supports. This RPC can 1909 + * reply with up to 196 words. The operation is asynchronous and if we managed 1910 + * to allocate a call, true is returned the result is delivered through the 1911 + * ->done() - otherwise we return false to indicate we didn't even try. 1731 1912 */ 1732 - struct afs_call *afs_fs_get_capabilities(struct afs_net *net, 1733 - struct afs_server *server, 1734 - struct afs_addr_cursor *ac, 1735 - struct key *key, 1736 - unsigned int server_index) 1913 + bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server, 1914 + struct afs_addr_cursor *ac, struct key *key) 1737 1915 { 1738 1916 struct afs_call *call; 1739 1917 __be32 *bp; ··· 1741 1921 1742 1922 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4); 1743 1923 if (!call) 1744 - return ERR_PTR(-ENOMEM); 1924 + return false; 1745 1925 1746 1926 call->key = key; 1747 - call->server = afs_get_server(server, afs_server_trace_get_caps); 1748 - call->server_index = server_index; 1927 + call->server = afs_use_server(server, afs_server_trace_get_caps); 1749 1928 call->upgrade = true; 1750 1929 call->async = true; 1751 1930 call->max_lifespan = AFS_PROBE_MAX_LIFESPAN; ··· 1753 1934 bp = call->request; 1754 1935 *bp++ = htonl(FSGETCAPABILITIES); 1755 1936 1756 - /* Can't take a ref on server */ 1757 1937 trace_afs_make_fs_call(call, NULL); 1758 1938 afs_make_call(ac, call, GFP_NOFS); 1759 - return call; 1760 - } 1761 - 1762 - /* 1763 - * Deliver reply data to an FS.FetchStatus with no vnode. 1764 - */ 1765 - static int afs_deliver_fs_fetch_status(struct afs_call *call) 1766 - { 1767 - const __be32 *bp; 1768 - int ret; 1769 - 1770 - ret = afs_transfer_reply(call); 1771 - if (ret < 0) 1772 - return ret; 1773 - 1774 - /* unmarshall the reply once we've received all of it */ 1775 - bp = call->buffer; 1776 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 1777 - if (ret < 0) 1778 - return ret; 1779 - xdr_decode_AFSCallBack(&bp, call, call->out_scb); 1780 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 1781 - 1782 - _leave(" = 0 [done]"); 1783 - return 0; 1784 - } 1785 - 1786 - /* 1787 - * FS.FetchStatus operation type 1788 - */ 1789 - static const struct afs_call_type afs_RXFSFetchStatus = { 1790 - .name = "FS.FetchStatus", 1791 - .op = afs_FS_FetchStatus, 1792 - .deliver = afs_deliver_fs_fetch_status, 1793 - .destructor = afs_flat_call_destructor, 1794 - }; 1795 - 1796 - /* 1797 - * Fetch the status information for a fid without needing a vnode handle. 1798 - */ 1799 - int afs_fs_fetch_status(struct afs_fs_cursor *fc, 1800 - struct afs_net *net, 1801 - struct afs_fid *fid, 1802 - struct afs_status_cb *scb, 1803 - struct afs_volsync *volsync) 1804 - { 1805 - struct afs_call *call; 1806 - __be32 *bp; 1807 - 1808 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1809 - return yfs_fs_fetch_status(fc, net, fid, scb, volsync); 1810 - 1811 - _enter(",%x,{%llx:%llu},,", 1812 - key_serial(fc->key), fid->vid, fid->vnode); 1813 - 1814 - call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4); 1815 - if (!call) { 1816 - fc->ac.error = -ENOMEM; 1817 - return -ENOMEM; 1818 - } 1819 - 1820 - call->key = fc->key; 1821 - call->out_fid = fid; 1822 - call->out_scb = scb; 1823 - call->out_volsync = volsync; 1824 - 1825 - /* marshall the parameters */ 1826 - bp = call->request; 1827 - bp[0] = htonl(FSFETCHSTATUS); 1828 - bp[1] = htonl(fid->vid); 1829 - bp[2] = htonl(fid->vnode); 1830 - bp[3] = htonl(fid->unique); 1831 - 1832 - afs_use_fs_server(call, fc->cbi); 1833 - trace_afs_make_fs_call(call, fid); 1834 - afs_set_fc_call(call, fc); 1835 - afs_make_call(&fc->ac, call, GFP_NOFS); 1836 - return afs_wait_for_call_to_complete(call, &fc->ac); 1939 + afs_put_call(call); 1940 + return true; 1837 1941 } 1838 1942 1839 1943 /* ··· 1764 2022 */ 1765 2023 static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) 1766 2024 { 2025 + struct afs_operation *op = call->op; 1767 2026 struct afs_status_cb *scb; 1768 2027 const __be32 *bp; 1769 2028 u32 tmp; ··· 1786 2043 return ret; 1787 2044 1788 2045 tmp = ntohl(call->tmp); 1789 - _debug("status count: %u/%u", tmp, call->count2); 1790 - if (tmp != call->count2) 1791 - return afs_protocol_error(call, -EBADMSG, 1792 - afs_eproto_ibulkst_count); 2046 + _debug("status count: %u/%u", tmp, op->nr_files); 2047 + if (tmp != op->nr_files) 2048 + return afs_protocol_error(call, afs_eproto_ibulkst_count); 1793 2049 1794 2050 call->count = 0; 1795 2051 call->unmarshall++; ··· 1802 2060 if (ret < 0) 1803 2061 return ret; 1804 2062 2063 + switch (call->count) { 2064 + case 0: 2065 + scb = &op->file[0].scb; 2066 + break; 2067 + case 1: 2068 + scb = &op->file[1].scb; 2069 + break; 2070 + default: 2071 + scb = &op->more_files[call->count - 2].scb; 2072 + break; 2073 + } 2074 + 1805 2075 bp = call->buffer; 1806 - scb = &call->out_scb[call->count]; 1807 - ret = xdr_decode_AFSFetchStatus(&bp, call, scb); 1808 - if (ret < 0) 1809 - return ret; 2076 + xdr_decode_AFSFetchStatus(&bp, call, scb); 1810 2077 1811 2078 call->count++; 1812 - if (call->count < call->count2) 2079 + if (call->count < op->nr_files) 1813 2080 goto more_counts; 1814 2081 1815 2082 call->count = 0; ··· 1835 2084 1836 2085 tmp = ntohl(call->tmp); 1837 2086 _debug("CB count: %u", tmp); 1838 - if (tmp != call->count2) 1839 - return afs_protocol_error(call, -EBADMSG, 1840 - afs_eproto_ibulkst_cb_count); 2087 + if (tmp != op->nr_files) 2088 + return afs_protocol_error(call, afs_eproto_ibulkst_cb_count); 1841 2089 call->count = 0; 1842 2090 call->unmarshall++; 1843 2091 more_cbs: ··· 1850 2100 return ret; 1851 2101 1852 2102 _debug("unmarshall CB array"); 2103 + switch (call->count) { 2104 + case 0: 2105 + scb = &op->file[0].scb; 2106 + break; 2107 + case 1: 2108 + scb = &op->file[1].scb; 2109 + break; 2110 + default: 2111 + scb = &op->more_files[call->count - 2].scb; 2112 + break; 2113 + } 2114 + 1853 2115 bp = call->buffer; 1854 - scb = &call->out_scb[call->count]; 1855 2116 xdr_decode_AFSCallBack(&bp, call, scb); 1856 2117 call->count++; 1857 - if (call->count < call->count2) 2118 + if (call->count < op->nr_files) 1858 2119 goto more_cbs; 1859 2120 1860 2121 afs_extract_to_buf(call, 6 * sizeof(__be32)); ··· 1878 2117 return ret; 1879 2118 1880 2119 bp = call->buffer; 1881 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 2120 + xdr_decode_AFSVolSync(&bp, &op->volsync); 1882 2121 1883 2122 call->unmarshall++; 1884 2123 ··· 1890 2129 return 0; 1891 2130 } 1892 2131 2132 + static void afs_done_fs_inline_bulk_status(struct afs_call *call) 2133 + { 2134 + if (call->error == -ECONNABORTED && 2135 + call->abort_code == RX_INVALID_OPERATION) { 2136 + set_bit(AFS_SERVER_FL_NO_IBULK, &call->server->flags); 2137 + if (call->op) 2138 + set_bit(AFS_VOLUME_MAYBE_NO_IBULK, &call->op->volume->flags); 2139 + } 2140 + } 2141 + 1893 2142 /* 1894 2143 * FS.InlineBulkStatus operation type 1895 2144 */ ··· 1907 2136 .name = "FS.InlineBulkStatus", 1908 2137 .op = afs_FS_InlineBulkStatus, 1909 2138 .deliver = afs_deliver_fs_inline_bulk_status, 2139 + .done = afs_done_fs_inline_bulk_status, 1910 2140 .destructor = afs_flat_call_destructor, 1911 2141 }; 1912 2142 1913 2143 /* 1914 2144 * Fetch the status information for up to 50 files 1915 2145 */ 1916 - int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc, 1917 - struct afs_net *net, 1918 - struct afs_fid *fids, 1919 - struct afs_status_cb *statuses, 1920 - unsigned int nr_fids, 1921 - struct afs_volsync *volsync) 2146 + void afs_fs_inline_bulk_status(struct afs_operation *op) 1922 2147 { 2148 + struct afs_vnode_param *dvp = &op->file[0]; 2149 + struct afs_vnode_param *vp = &op->file[1]; 1923 2150 struct afs_call *call; 1924 2151 __be32 *bp; 1925 2152 int i; 1926 2153 1927 - if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1928 - return yfs_fs_inline_bulk_status(fc, net, fids, statuses, 1929 - nr_fids, volsync); 1930 - 1931 - _enter(",%x,{%llx:%llu},%u", 1932 - key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids); 1933 - 1934 - call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus, 1935 - (2 + nr_fids * 3) * 4, 1936 - 21 * 4); 1937 - if (!call) { 1938 - fc->ac.error = -ENOMEM; 1939 - return -ENOMEM; 2154 + if (test_bit(AFS_SERVER_FL_NO_IBULK, &op->server->flags)) { 2155 + op->error = -ENOTSUPP; 2156 + return; 1940 2157 } 1941 2158 1942 - call->key = fc->key; 1943 - call->out_scb = statuses; 1944 - call->out_volsync = volsync; 1945 - call->count2 = nr_fids; 2159 + _enter(",%x,{%llx:%llu},%u", 2160 + key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files); 2161 + 2162 + call = afs_alloc_flat_call(op->net, &afs_RXFSInlineBulkStatus, 2163 + (2 + op->nr_files * 3) * 4, 2164 + 21 * 4); 2165 + if (!call) 2166 + return afs_op_nomem(op); 1946 2167 1947 2168 /* marshall the parameters */ 1948 2169 bp = call->request; 1949 2170 *bp++ = htonl(FSINLINEBULKSTATUS); 1950 - *bp++ = htonl(nr_fids); 1951 - for (i = 0; i < nr_fids; i++) { 1952 - *bp++ = htonl(fids[i].vid); 1953 - *bp++ = htonl(fids[i].vnode); 1954 - *bp++ = htonl(fids[i].unique); 2171 + *bp++ = htonl(op->nr_files); 2172 + *bp++ = htonl(dvp->fid.vid); 2173 + *bp++ = htonl(dvp->fid.vnode); 2174 + *bp++ = htonl(dvp->fid.unique); 2175 + *bp++ = htonl(vp->fid.vid); 2176 + *bp++ = htonl(vp->fid.vnode); 2177 + *bp++ = htonl(vp->fid.unique); 2178 + for (i = 0; i < op->nr_files - 2; i++) { 2179 + *bp++ = htonl(op->more_files[i].fid.vid); 2180 + *bp++ = htonl(op->more_files[i].fid.vnode); 2181 + *bp++ = htonl(op->more_files[i].fid.unique); 1955 2182 } 1956 2183 1957 - afs_use_fs_server(call, fc->cbi); 1958 - trace_afs_make_fs_call(call, &fids[0]); 1959 - afs_set_fc_call(call, fc); 1960 - afs_make_call(&fc->ac, call, GFP_NOFS); 1961 - return afs_wait_for_call_to_complete(call, &fc->ac); 2184 + trace_afs_make_fs_call(call, &vp->fid); 2185 + afs_make_op_call(op, call, GFP_NOFS); 1962 2186 } 1963 2187 1964 2188 /* ··· 1961 2195 */ 1962 2196 static int afs_deliver_fs_fetch_acl(struct afs_call *call) 1963 2197 { 2198 + struct afs_operation *op = call->op; 2199 + struct afs_vnode_param *vp = &op->file[0]; 1964 2200 struct afs_acl *acl; 1965 2201 const __be32 *bp; 1966 2202 unsigned int size; ··· 1988 2220 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); 1989 2221 if (!acl) 1990 2222 return -ENOMEM; 1991 - call->ret_acl = acl; 2223 + op->acl = acl; 1992 2224 acl->size = call->count2; 1993 2225 afs_extract_begin(call, acl->data, size); 1994 2226 call->unmarshall++; ··· 2011 2243 return ret; 2012 2244 2013 2245 bp = call->buffer; 2014 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 2015 - if (ret < 0) 2016 - return ret; 2017 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 2246 + xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 2247 + xdr_decode_AFSVolSync(&bp, &op->volsync); 2018 2248 2019 2249 call->unmarshall++; 2020 2250 ··· 2024 2258 return 0; 2025 2259 } 2026 2260 2027 - static void afs_destroy_fs_fetch_acl(struct afs_call *call) 2028 - { 2029 - kfree(call->ret_acl); 2030 - afs_flat_call_destructor(call); 2031 - } 2032 - 2033 2261 /* 2034 2262 * FS.FetchACL operation type 2035 2263 */ ··· 2031 2271 .name = "FS.FetchACL", 2032 2272 .op = afs_FS_FetchACL, 2033 2273 .deliver = afs_deliver_fs_fetch_acl, 2034 - .destructor = afs_destroy_fs_fetch_acl, 2035 2274 }; 2036 2275 2037 2276 /* 2038 2277 * Fetch the ACL for a file. 2039 2278 */ 2040 - struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *fc, 2041 - struct afs_status_cb *scb) 2279 + void afs_fs_fetch_acl(struct afs_operation *op) 2042 2280 { 2043 - struct afs_vnode *vnode = fc->vnode; 2281 + struct afs_vnode_param *vp = &op->file[0]; 2044 2282 struct afs_call *call; 2045 - struct afs_net *net = afs_v2net(vnode); 2046 2283 __be32 *bp; 2047 2284 2048 2285 _enter(",%x,{%llx:%llu},,", 2049 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 2286 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 2050 2287 2051 - call = afs_alloc_flat_call(net, &afs_RXFSFetchACL, 16, (21 + 6) * 4); 2052 - if (!call) { 2053 - fc->ac.error = -ENOMEM; 2054 - return ERR_PTR(-ENOMEM); 2055 - } 2056 - 2057 - call->key = fc->key; 2058 - call->ret_acl = NULL; 2059 - call->out_scb = scb; 2060 - call->out_volsync = NULL; 2288 + call = afs_alloc_flat_call(op->net, &afs_RXFSFetchACL, 16, (21 + 6) * 4); 2289 + if (!call) 2290 + return afs_op_nomem(op); 2061 2291 2062 2292 /* marshall the parameters */ 2063 2293 bp = call->request; 2064 2294 bp[0] = htonl(FSFETCHACL); 2065 - bp[1] = htonl(vnode->fid.vid); 2066 - bp[2] = htonl(vnode->fid.vnode); 2067 - bp[3] = htonl(vnode->fid.unique); 2295 + bp[1] = htonl(vp->fid.vid); 2296 + bp[2] = htonl(vp->fid.vnode); 2297 + bp[3] = htonl(vp->fid.unique); 2068 2298 2069 - afs_use_fs_server(call, fc->cbi); 2070 - trace_afs_make_fs_call(call, &vnode->fid); 2071 - afs_make_call(&fc->ac, call, GFP_KERNEL); 2072 - return (struct afs_acl *)afs_wait_for_call_to_complete(call, &fc->ac); 2073 - } 2074 - 2075 - /* 2076 - * Deliver reply data to any operation that returns file status and volume 2077 - * sync. 2078 - */ 2079 - static int afs_deliver_fs_file_status_and_vol(struct afs_call *call) 2080 - { 2081 - const __be32 *bp; 2082 - int ret; 2083 - 2084 - ret = afs_transfer_reply(call); 2085 - if (ret < 0) 2086 - return ret; 2087 - 2088 - bp = call->buffer; 2089 - ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); 2090 - if (ret < 0) 2091 - return ret; 2092 - xdr_decode_AFSVolSync(&bp, call->out_volsync); 2093 - 2094 - _leave(" = 0 [done]"); 2095 - return 0; 2299 + trace_afs_make_fs_call(call, &vp->fid); 2300 + afs_make_op_call(op, call, GFP_KERNEL); 2096 2301 } 2097 2302 2098 2303 /* ··· 2073 2348 /* 2074 2349 * Fetch the ACL for a file. 2075 2350 */ 2076 - int afs_fs_store_acl(struct afs_fs_cursor *fc, const struct afs_acl *acl, 2077 - struct afs_status_cb *scb) 2351 + void afs_fs_store_acl(struct afs_operation *op) 2078 2352 { 2079 - struct afs_vnode *vnode = fc->vnode; 2353 + struct afs_vnode_param *vp = &op->file[0]; 2080 2354 struct afs_call *call; 2081 - struct afs_net *net = afs_v2net(vnode); 2355 + const struct afs_acl *acl = op->acl; 2082 2356 size_t size; 2083 2357 __be32 *bp; 2084 2358 2085 2359 _enter(",%x,{%llx:%llu},,", 2086 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 2360 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 2087 2361 2088 2362 size = round_up(acl->size, 4); 2089 - call = afs_alloc_flat_call(net, &afs_RXFSStoreACL, 2363 + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreACL, 2090 2364 5 * 4 + size, (21 + 6) * 4); 2091 - if (!call) { 2092 - fc->ac.error = -ENOMEM; 2093 - return -ENOMEM; 2094 - } 2095 - 2096 - call->key = fc->key; 2097 - call->out_scb = scb; 2098 - call->out_volsync = NULL; 2365 + if (!call) 2366 + return afs_op_nomem(op); 2099 2367 2100 2368 /* marshall the parameters */ 2101 2369 bp = call->request; 2102 2370 bp[0] = htonl(FSSTOREACL); 2103 - bp[1] = htonl(vnode->fid.vid); 2104 - bp[2] = htonl(vnode->fid.vnode); 2105 - bp[3] = htonl(vnode->fid.unique); 2371 + bp[1] = htonl(vp->fid.vid); 2372 + bp[2] = htonl(vp->fid.vnode); 2373 + bp[3] = htonl(vp->fid.unique); 2106 2374 bp[4] = htonl(acl->size); 2107 2375 memcpy(&bp[5], acl->data, acl->size); 2108 2376 if (acl->size != size) 2109 2377 memset((void *)&bp[5] + acl->size, 0, size - acl->size); 2110 2378 2111 - trace_afs_make_fs_call(call, &vnode->fid); 2112 - afs_make_call(&fc->ac, call, GFP_KERNEL); 2113 - return afs_wait_for_call_to_complete(call, &fc->ac); 2379 + trace_afs_make_fs_call(call, &vp->fid); 2380 + afs_make_op_call(op, call, GFP_KERNEL); 2114 2381 }
+228 -271
fs/afs/inode.c
··· 67 67 /* 68 68 * Initialise an inode from the vnode status. 69 69 */ 70 - static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key, 71 - struct afs_cb_interest *cbi, 72 - struct afs_vnode *parent_vnode, 73 - struct afs_status_cb *scb) 70 + static int afs_inode_init_from_status(struct afs_operation *op, 71 + struct afs_vnode_param *vp, 72 + struct afs_vnode *vnode) 74 73 { 75 - struct afs_cb_interest *old_cbi = NULL; 76 - struct afs_file_status *status = &scb->status; 74 + struct afs_file_status *status = &vp->scb.status; 77 75 struct inode *inode = AFS_VNODE_TO_I(vnode); 78 76 struct timespec64 t; 77 + 78 + _enter("{%llx:%llu.%u} %s", 79 + vp->fid.vid, vp->fid.vnode, vp->fid.unique, 80 + op->type ? op->type->name : "???"); 79 81 80 82 _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu", 81 83 status->type, ··· 88 86 89 87 write_seqlock(&vnode->cb_lock); 90 88 89 + vnode->cb_v_break = op->cb_v_break; 90 + vnode->cb_s_break = op->cb_s_break; 91 91 vnode->status = *status; 92 92 93 93 t = status->mtime_client; 94 94 inode->i_ctime = t; 95 95 inode->i_mtime = t; 96 96 inode->i_atime = t; 97 + inode->i_flags |= S_NOATIME; 97 98 inode->i_uid = make_kuid(&init_user_ns, status->owner); 98 99 inode->i_gid = make_kgid(&init_user_ns, status->group); 99 100 set_nlink(&vnode->vfs_inode, status->nlink); ··· 133 128 inode_nohighmem(inode); 134 129 break; 135 130 default: 136 - dump_vnode(vnode, parent_vnode); 131 + dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL); 137 132 write_sequnlock(&vnode->cb_lock); 138 - return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type); 133 + return afs_protocol_error(NULL, afs_eproto_file_type); 139 134 } 140 135 141 136 afs_set_i_size(vnode, status->size); ··· 143 138 vnode->invalid_before = status->data_version; 144 139 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version); 145 140 146 - if (!scb->have_cb) { 141 + if (!vp->scb.have_cb) { 147 142 /* it's a symlink we just created (the fileserver 148 143 * didn't give us a callback) */ 149 144 vnode->cb_expires_at = ktime_get_real_seconds(); 150 145 } else { 151 - vnode->cb_expires_at = scb->callback.expires_at; 152 - old_cbi = rcu_dereference_protected(vnode->cb_interest, 153 - lockdep_is_held(&vnode->cb_lock.lock)); 154 - if (cbi != old_cbi) 155 - rcu_assign_pointer(vnode->cb_interest, afs_get_cb_interest(cbi)); 156 - else 157 - old_cbi = NULL; 146 + vnode->cb_expires_at = vp->scb.callback.expires_at; 147 + vnode->cb_server = op->server; 158 148 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 159 149 } 160 150 161 151 write_sequnlock(&vnode->cb_lock); 162 - afs_put_cb_interest(afs_v2net(vnode), old_cbi); 163 152 return 0; 164 153 } 165 154 166 155 /* 167 156 * Update the core inode struct from a returned status record. 168 157 */ 169 - static void afs_apply_status(struct afs_fs_cursor *fc, 170 - struct afs_vnode *vnode, 171 - struct afs_status_cb *scb, 172 - const afs_dataversion_t *expected_version) 158 + static void afs_apply_status(struct afs_operation *op, 159 + struct afs_vnode_param *vp) 173 160 { 174 - struct afs_file_status *status = &scb->status; 161 + struct afs_file_status *status = &vp->scb.status; 162 + struct afs_vnode *vnode = vp->vnode; 175 163 struct timespec64 t; 176 164 umode_t mode; 177 165 bool data_changed = false; 166 + 167 + _enter("{%llx:%llu.%u} %s", 168 + vp->fid.vid, vp->fid.vnode, vp->fid.unique, 169 + op->type ? op->type->name : "???"); 178 170 179 171 BUG_ON(test_bit(AFS_VNODE_UNSET, &vnode->flags)); 180 172 ··· 181 179 vnode->fid.vnode, 182 180 vnode->fid.unique, 183 181 status->type, vnode->status.type); 184 - afs_protocol_error(NULL, -EBADMSG, afs_eproto_bad_status); 182 + afs_protocol_error(NULL, afs_eproto_bad_status); 185 183 return; 186 184 } 187 185 ··· 211 209 212 210 vnode->status = *status; 213 211 214 - if (expected_version && 215 - *expected_version != status->data_version) { 212 + if (vp->dv_before + vp->dv_delta != status->data_version) { 216 213 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) 217 214 pr_warn("kAFS: vnode modified {%llx:%llu} %llx->%llx %s\n", 218 215 vnode->fid.vid, vnode->fid.vnode, 219 - (unsigned long long)*expected_version, 216 + (unsigned long long)vp->dv_before + vp->dv_delta, 220 217 (unsigned long long)status->data_version, 221 - fc->type ? fc->type->name : "???"); 218 + op->type ? op->type->name : "???"); 222 219 223 220 vnode->invalid_before = status->data_version; 224 221 if (vnode->status.type == AFS_FTYPE_DIR) { ··· 244 243 /* 245 244 * Apply a callback to a vnode. 246 245 */ 247 - static void afs_apply_callback(struct afs_fs_cursor *fc, 248 - struct afs_vnode *vnode, 249 - struct afs_status_cb *scb, 250 - unsigned int cb_break) 246 + static void afs_apply_callback(struct afs_operation *op, 247 + struct afs_vnode_param *vp) 251 248 { 252 - struct afs_cb_interest *old; 253 - struct afs_callback *cb = &scb->callback; 249 + struct afs_callback *cb = &vp->scb.callback; 250 + struct afs_vnode *vnode = vp->vnode; 254 251 255 - if (!afs_cb_is_broken(cb_break, vnode, fc->cbi)) { 252 + if (!afs_cb_is_broken(vp->cb_break_before, vnode)) { 256 253 vnode->cb_expires_at = cb->expires_at; 257 - old = rcu_dereference_protected(vnode->cb_interest, 258 - lockdep_is_held(&vnode->cb_lock.lock)); 259 - if (old != fc->cbi) { 260 - rcu_assign_pointer(vnode->cb_interest, afs_get_cb_interest(fc->cbi)); 261 - afs_put_cb_interest(afs_v2net(vnode), old); 262 - } 254 + vnode->cb_server = op->server; 263 255 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 264 256 } 265 257 } ··· 261 267 * Apply the received status and callback to an inode all in the same critical 262 268 * section to avoid races with afs_validate(). 263 269 */ 264 - void afs_vnode_commit_status(struct afs_fs_cursor *fc, 265 - struct afs_vnode *vnode, 266 - unsigned int cb_break, 267 - const afs_dataversion_t *expected_version, 268 - struct afs_status_cb *scb) 270 + void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *vp) 269 271 { 270 - if (fc->ac.error != 0) 271 - return; 272 + struct afs_vnode *vnode = vp->vnode; 273 + 274 + _enter(""); 275 + 276 + ASSERTCMP(op->error, ==, 0); 272 277 273 278 write_seqlock(&vnode->cb_lock); 274 279 275 - if (scb->have_error) { 276 - if (scb->status.abort_code == VNOVNODE) { 280 + if (vp->scb.have_error) { 281 + if (vp->scb.status.abort_code == VNOVNODE) { 277 282 set_bit(AFS_VNODE_DELETED, &vnode->flags); 278 283 clear_nlink(&vnode->vfs_inode); 279 284 __afs_break_callback(vnode, afs_cb_break_for_deleted); 280 285 } 281 286 } else { 282 - if (scb->have_status) 283 - afs_apply_status(fc, vnode, scb, expected_version); 284 - if (scb->have_cb) 285 - afs_apply_callback(fc, vnode, scb, cb_break); 287 + if (vp->scb.have_status) 288 + afs_apply_status(op, vp); 289 + if (vp->scb.have_cb) 290 + afs_apply_callback(op, vp); 286 291 } 287 292 288 293 write_sequnlock(&vnode->cb_lock); 289 294 290 - if (fc->ac.error == 0 && scb->have_status) 291 - afs_cache_permit(vnode, fc->key, cb_break, scb); 295 + if (op->error == 0 && vp->scb.have_status) 296 + afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb); 292 297 } 298 + 299 + static void afs_fetch_status_success(struct afs_operation *op) 300 + { 301 + struct afs_vnode_param *vp = &op->file[0]; 302 + struct afs_vnode *vnode = vp->vnode; 303 + int ret; 304 + 305 + if (vnode->vfs_inode.i_state & I_NEW) { 306 + ret = afs_inode_init_from_status(op, vp, vnode); 307 + op->error = ret; 308 + if (ret == 0) 309 + afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb); 310 + } else { 311 + afs_vnode_commit_status(op, vp); 312 + } 313 + } 314 + 315 + static const struct afs_operation_ops afs_fetch_status_operation = { 316 + .issue_afs_rpc = afs_fs_fetch_status, 317 + .issue_yfs_rpc = yfs_fs_fetch_status, 318 + .success = afs_fetch_status_success, 319 + }; 293 320 294 321 /* 295 322 * Fetch file status from the volume. ··· 318 303 int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new, 319 304 afs_access_t *_caller_access) 320 305 { 321 - struct afs_status_cb *scb; 322 - struct afs_fs_cursor fc; 323 - int ret; 306 + struct afs_operation *op; 324 307 325 308 _enter("%s,{%llx:%llu.%u,S=%lx}", 326 309 vnode->volume->name, 327 310 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique, 328 311 vnode->flags); 329 312 330 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 331 - if (!scb) 332 - return -ENOMEM; 313 + op = afs_alloc_operation(key, vnode->volume); 314 + if (IS_ERR(op)) 315 + return PTR_ERR(op); 333 316 334 - ret = -ERESTARTSYS; 335 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 336 - afs_dataversion_t data_version = vnode->status.data_version; 317 + afs_op_set_vnode(op, 0, vnode); 337 318 338 - while (afs_select_fileserver(&fc)) { 339 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 340 - afs_fs_fetch_file_status(&fc, scb, NULL); 341 - } 319 + op->nr_files = 1; 320 + op->ops = &afs_fetch_status_operation; 321 + afs_begin_vnode_operation(op); 322 + afs_wait_for_operation(op); 342 323 343 - if (fc.error) { 344 - /* Do nothing. */ 345 - } else if (is_new) { 346 - ret = afs_inode_init_from_status(vnode, key, fc.cbi, 347 - NULL, scb); 348 - fc.error = ret; 349 - if (ret == 0) 350 - afs_cache_permit(vnode, key, fc.cb_break, scb); 351 - } else { 352 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 353 - &data_version, scb); 354 - } 355 - afs_check_for_remote_deletion(&fc, vnode); 356 - ret = afs_end_vnode_operation(&fc); 357 - } 324 + if (_caller_access) 325 + *_caller_access = op->file[0].scb.status.caller_access; 326 + return afs_put_operation(op); 327 + } 358 328 359 - if (ret == 0 && _caller_access) 360 - *_caller_access = scb->status.caller_access; 361 - kfree(scb); 362 - _leave(" = %d", ret); 363 - return ret; 329 + /* 330 + * ilookup() comparator 331 + */ 332 + int afs_ilookup5_test_by_fid(struct inode *inode, void *opaque) 333 + { 334 + struct afs_vnode *vnode = AFS_FS_I(inode); 335 + struct afs_fid *fid = opaque; 336 + 337 + return (fid->vnode == vnode->fid.vnode && 338 + fid->vnode_hi == vnode->fid.vnode_hi && 339 + fid->unique == vnode->fid.unique); 364 340 } 365 341 366 342 /* 367 343 * iget5() comparator 368 344 */ 369 - int afs_iget5_test(struct inode *inode, void *opaque) 345 + static int afs_iget5_test(struct inode *inode, void *opaque) 370 346 { 371 - struct afs_iget_data *iget_data = opaque; 372 - struct afs_vnode *vnode = AFS_FS_I(inode); 347 + struct afs_vnode_param *vp = opaque; 348 + //struct afs_vnode *vnode = AFS_FS_I(inode); 373 349 374 - return memcmp(&vnode->fid, &iget_data->fid, sizeof(iget_data->fid)) == 0; 375 - } 376 - 377 - /* 378 - * iget5() comparator for inode created by autocell operations 379 - * 380 - * These pseudo inodes don't match anything. 381 - */ 382 - static int afs_iget5_pseudo_dir_test(struct inode *inode, void *opaque) 383 - { 384 - return 0; 350 + return afs_ilookup5_test_by_fid(inode, &vp->fid); 385 351 } 386 352 387 353 /* ··· 370 374 */ 371 375 static int afs_iget5_set(struct inode *inode, void *opaque) 372 376 { 373 - struct afs_iget_data *iget_data = opaque; 377 + struct afs_vnode_param *vp = opaque; 378 + struct afs_super_info *as = AFS_FS_S(inode->i_sb); 374 379 struct afs_vnode *vnode = AFS_FS_I(inode); 375 380 376 - vnode->fid = iget_data->fid; 377 - vnode->volume = iget_data->volume; 378 - vnode->cb_v_break = iget_data->cb_v_break; 379 - vnode->cb_s_break = iget_data->cb_s_break; 381 + vnode->volume = as->volume; 382 + vnode->fid = vp->fid; 380 383 381 384 /* YFS supports 96-bit vnode IDs, but Linux only supports 382 385 * 64-bit inode numbers. 383 386 */ 384 - inode->i_ino = iget_data->fid.vnode; 385 - inode->i_generation = iget_data->fid.unique; 387 + inode->i_ino = vnode->fid.vnode; 388 + inode->i_generation = vnode->fid.unique; 386 389 return 0; 387 - } 388 - 389 - /* 390 - * Create an inode for a dynamic root directory or an autocell dynamic 391 - * automount dir. 392 - */ 393 - struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) 394 - { 395 - struct afs_super_info *as; 396 - struct afs_vnode *vnode; 397 - struct inode *inode; 398 - static atomic_t afs_autocell_ino; 399 - 400 - struct afs_iget_data iget_data = { 401 - .cb_v_break = 0, 402 - .cb_s_break = 0, 403 - }; 404 - 405 - _enter(""); 406 - 407 - as = sb->s_fs_info; 408 - if (as->volume) { 409 - iget_data.volume = as->volume; 410 - iget_data.fid.vid = as->volume->vid; 411 - } 412 - if (root) { 413 - iget_data.fid.vnode = 1; 414 - iget_data.fid.unique = 1; 415 - } else { 416 - iget_data.fid.vnode = atomic_inc_return(&afs_autocell_ino); 417 - iget_data.fid.unique = 0; 418 - } 419 - 420 - inode = iget5_locked(sb, iget_data.fid.vnode, 421 - afs_iget5_pseudo_dir_test, afs_iget5_set, 422 - &iget_data); 423 - if (!inode) { 424 - _leave(" = -ENOMEM"); 425 - return ERR_PTR(-ENOMEM); 426 - } 427 - 428 - _debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }", 429 - inode, inode->i_ino, iget_data.fid.vid, iget_data.fid.vnode, 430 - iget_data.fid.unique); 431 - 432 - vnode = AFS_FS_I(inode); 433 - 434 - /* there shouldn't be an existing inode */ 435 - BUG_ON(!(inode->i_state & I_NEW)); 436 - 437 - inode->i_size = 0; 438 - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; 439 - if (root) { 440 - inode->i_op = &afs_dynroot_inode_operations; 441 - inode->i_fop = &simple_dir_operations; 442 - } else { 443 - inode->i_op = &afs_autocell_inode_operations; 444 - } 445 - set_nlink(inode, 2); 446 - inode->i_uid = GLOBAL_ROOT_UID; 447 - inode->i_gid = GLOBAL_ROOT_GID; 448 - inode->i_ctime = inode->i_atime = inode->i_mtime = current_time(inode); 449 - inode->i_blocks = 0; 450 - inode_set_iversion_raw(inode, 0); 451 - inode->i_generation = 0; 452 - 453 - set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags); 454 - if (!root) { 455 - set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags); 456 - inode->i_flags |= S_AUTOMOUNT; 457 - } 458 - 459 - inode->i_flags |= S_NOATIME; 460 - unlock_new_inode(inode); 461 - _leave(" = %p", inode); 462 - return inode; 463 390 } 464 391 465 392 /* ··· 420 501 /* 421 502 * inode retrieval 422 503 */ 423 - struct inode *afs_iget(struct super_block *sb, struct key *key, 424 - struct afs_iget_data *iget_data, 425 - struct afs_status_cb *scb, 426 - struct afs_cb_interest *cbi, 427 - struct afs_vnode *parent_vnode) 504 + struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp) 428 505 { 429 - struct afs_super_info *as; 506 + struct afs_vnode_param *dvp = &op->file[0]; 507 + struct super_block *sb = dvp->vnode->vfs_inode.i_sb; 430 508 struct afs_vnode *vnode; 431 - struct afs_fid *fid = &iget_data->fid; 432 509 struct inode *inode; 433 510 int ret; 434 511 435 - _enter(",{%llx:%llu.%u},,", fid->vid, fid->vnode, fid->unique); 512 + _enter(",{%llx:%llu.%u},,", vp->fid.vid, vp->fid.vnode, vp->fid.unique); 436 513 437 - as = sb->s_fs_info; 438 - iget_data->volume = as->volume; 439 - 440 - inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set, 441 - iget_data); 514 + inode = iget5_locked(sb, vp->fid.vnode, afs_iget5_test, afs_iget5_set, vp); 442 515 if (!inode) { 443 516 _leave(" = -ENOMEM"); 444 517 return ERR_PTR(-ENOMEM); 445 518 } 446 519 447 - _debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }", 448 - inode, fid->vid, fid->vnode, fid->unique); 449 - 450 520 vnode = AFS_FS_I(inode); 521 + 522 + _debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }", 523 + inode, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); 451 524 452 525 /* deal with an existing inode */ 453 526 if (!(inode->i_state & I_NEW)) { ··· 447 536 return inode; 448 537 } 449 538 450 - if (!scb) { 451 - /* it's a remotely extant inode */ 452 - ret = afs_fetch_status(vnode, key, true, NULL); 453 - if (ret < 0) 454 - goto bad_inode; 455 - } else { 456 - ret = afs_inode_init_from_status(vnode, key, cbi, parent_vnode, 457 - scb); 458 - if (ret < 0) 459 - goto bad_inode; 460 - } 539 + ret = afs_inode_init_from_status(op, vp, vnode); 540 + if (ret < 0) 541 + goto bad_inode; 461 542 462 543 afs_get_inode_cache(vnode); 463 544 464 545 /* success */ 465 546 clear_bit(AFS_VNODE_UNSET, &vnode->flags); 466 - inode->i_flags |= S_NOATIME; 467 547 unlock_new_inode(inode); 468 548 _leave(" = %p", inode); 469 549 return inode; 470 550 471 551 /* failure */ 472 552 bad_inode: 553 + iget_failed(inode); 554 + _leave(" = %d [bad]", ret); 555 + return ERR_PTR(ret); 556 + } 557 + 558 + static int afs_iget5_set_root(struct inode *inode, void *opaque) 559 + { 560 + struct afs_super_info *as = AFS_FS_S(inode->i_sb); 561 + struct afs_vnode *vnode = AFS_FS_I(inode); 562 + 563 + vnode->volume = as->volume; 564 + vnode->fid.vid = as->volume->vid, 565 + vnode->fid.vnode = 1; 566 + vnode->fid.unique = 1; 567 + inode->i_ino = 1; 568 + inode->i_generation = 1; 569 + return 0; 570 + } 571 + 572 + /* 573 + * Set up the root inode for a volume. This is always vnode 1, unique 1 within 574 + * the volume. 575 + */ 576 + struct inode *afs_root_iget(struct super_block *sb, struct key *key) 577 + { 578 + struct afs_super_info *as = AFS_FS_S(sb); 579 + struct afs_operation *op; 580 + struct afs_vnode *vnode; 581 + struct inode *inode; 582 + int ret; 583 + 584 + _enter(",{%llx},,", as->volume->vid); 585 + 586 + inode = iget5_locked(sb, 1, NULL, afs_iget5_set_root, NULL); 587 + if (!inode) { 588 + _leave(" = -ENOMEM"); 589 + return ERR_PTR(-ENOMEM); 590 + } 591 + 592 + _debug("GOT ROOT INODE %p { vl=%llx }", inode, as->volume->vid); 593 + 594 + BUG_ON(!(inode->i_state & I_NEW)); 595 + 596 + vnode = AFS_FS_I(inode); 597 + vnode->cb_v_break = as->volume->cb_v_break, 598 + 599 + op = afs_alloc_operation(key, as->volume); 600 + if (IS_ERR(op)) { 601 + ret = PTR_ERR(op); 602 + goto error; 603 + } 604 + 605 + afs_op_set_vnode(op, 0, vnode); 606 + 607 + op->nr_files = 1; 608 + op->ops = &afs_fetch_status_operation; 609 + ret = afs_do_sync_operation(op); 610 + if (ret < 0) 611 + goto error; 612 + 613 + afs_get_inode_cache(vnode); 614 + 615 + clear_bit(AFS_VNODE_UNSET, &vnode->flags); 616 + unlock_new_inode(inode); 617 + _leave(" = %p", inode); 618 + return inode; 619 + 620 + error: 473 621 iget_failed(inode); 474 622 _leave(" = %d [bad]", ret); 475 623 return ERR_PTR(ret); ··· 556 586 } 557 587 558 588 /* 589 + * Get the server reinit counter for a vnode's current server. 590 + */ 591 + static bool afs_get_s_break_rcu(struct afs_vnode *vnode, unsigned int *_s_break) 592 + { 593 + struct afs_server_list *slist = rcu_dereference(vnode->volume->servers); 594 + struct afs_server *server; 595 + int i; 596 + 597 + for (i = 0; i < slist->nr_servers; i++) { 598 + server = slist->servers[i].server; 599 + if (server == vnode->cb_server) { 600 + *_s_break = READ_ONCE(server->cb_s_break); 601 + return true; 602 + } 603 + } 604 + 605 + return false; 606 + } 607 + 608 + /* 559 609 * Check the validity of a vnode/inode. 560 610 */ 561 611 bool afs_check_validity(struct afs_vnode *vnode) 562 612 { 563 - struct afs_cb_interest *cbi; 564 - struct afs_server *server; 565 613 struct afs_volume *volume = vnode->volume; 566 614 enum afs_cb_break_reason need_clear = afs_cb_break_no_break; 567 615 time64_t now = ktime_get_real_seconds(); ··· 592 604 cb_v_break = READ_ONCE(volume->cb_v_break); 593 605 cb_break = vnode->cb_break; 594 606 595 - if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 596 - cbi = rcu_dereference(vnode->cb_interest); 597 - server = rcu_dereference(cbi->server); 598 - cb_s_break = READ_ONCE(server->cb_s_break); 599 - 607 + if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) && 608 + afs_get_s_break_rcu(vnode, &cb_s_break)) { 600 609 if (vnode->cb_s_break != cb_s_break || 601 610 vnode->cb_v_break != cb_v_break) { 602 611 vnode->cb_s_break = cb_s_break; ··· 740 755 */ 741 756 void afs_evict_inode(struct inode *inode) 742 757 { 743 - struct afs_cb_interest *cbi; 744 758 struct afs_vnode *vnode; 745 759 746 760 vnode = AFS_FS_I(inode); ··· 755 771 756 772 truncate_inode_pages_final(&inode->i_data); 757 773 clear_inode(inode); 758 - 759 - write_seqlock(&vnode->cb_lock); 760 - cbi = rcu_dereference_protected(vnode->cb_interest, 761 - lockdep_is_held(&vnode->cb_lock.lock)); 762 - if (cbi) { 763 - afs_put_cb_interest(afs_i2net(inode), cbi); 764 - rcu_assign_pointer(vnode->cb_interest, NULL); 765 - } 766 - write_sequnlock(&vnode->cb_lock); 767 774 768 775 while (!list_empty(&vnode->wb_keys)) { 769 776 struct afs_wb_key *wbk = list_entry(vnode->wb_keys.next, ··· 783 808 _leave(""); 784 809 } 785 810 811 + static void afs_setattr_success(struct afs_operation *op) 812 + { 813 + afs_vnode_commit_status(op, &op->file[0]); 814 + } 815 + 816 + static const struct afs_operation_ops afs_setattr_operation = { 817 + .issue_afs_rpc = afs_fs_setattr, 818 + .issue_yfs_rpc = yfs_fs_setattr, 819 + .success = afs_setattr_success, 820 + }; 821 + 786 822 /* 787 823 * set the attributes of an inode 788 824 */ 789 825 int afs_setattr(struct dentry *dentry, struct iattr *attr) 790 826 { 791 - struct afs_fs_cursor fc; 792 - struct afs_status_cb *scb; 827 + struct afs_operation *op; 793 828 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); 794 - struct key *key; 795 - int ret = -ENOMEM; 796 829 797 830 _enter("{%llx:%llu},{n=%pd},%x", 798 831 vnode->fid.vid, vnode->fid.vnode, dentry, ··· 812 829 return 0; 813 830 } 814 831 815 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); 816 - if (!scb) 817 - goto error; 818 - 819 832 /* flush any dirty data outstanding on a regular file */ 820 833 if (S_ISREG(vnode->vfs_inode.i_mode)) 821 834 filemap_write_and_wait(vnode->vfs_inode.i_mapping); 822 835 823 - if (attr->ia_valid & ATTR_FILE) { 824 - key = afs_file_key(attr->ia_file); 825 - } else { 826 - key = afs_request_key(vnode->volume->cell); 827 - if (IS_ERR(key)) { 828 - ret = PTR_ERR(key); 829 - goto error_scb; 830 - } 831 - } 836 + op = afs_alloc_operation(((attr->ia_valid & ATTR_FILE) ? 837 + afs_file_key(attr->ia_file) : NULL), 838 + vnode->volume); 839 + if (IS_ERR(op)) 840 + return PTR_ERR(op); 832 841 833 - ret = -ERESTARTSYS; 834 - if (afs_begin_vnode_operation(&fc, vnode, key, false)) { 835 - afs_dataversion_t data_version = vnode->status.data_version; 842 + afs_op_set_vnode(op, 0, vnode); 843 + op->setattr.attr = attr; 836 844 837 - if (attr->ia_valid & ATTR_SIZE) 838 - data_version++; 845 + if (attr->ia_valid & ATTR_SIZE) 846 + op->file[0].dv_delta = 1; 839 847 840 - while (afs_select_fileserver(&fc)) { 841 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 842 - afs_fs_setattr(&fc, attr, scb); 843 - } 844 - 845 - afs_check_for_remote_deletion(&fc, vnode); 846 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 847 - &data_version, scb); 848 - ret = afs_end_vnode_operation(&fc); 849 - } 850 - 851 - if (!(attr->ia_valid & ATTR_FILE)) 852 - key_put(key); 853 - 854 - error_scb: 855 - kfree(scb); 856 - error: 857 - _leave(" = %d", ret); 858 - return ret; 848 + op->ops = &afs_setattr_operation; 849 + return afs_do_sync_operation(op); 859 850 }
+302 -227
fs/afs/internal.h
··· 59 59 struct key *key; /* key to use for secure mounting */ 60 60 }; 61 61 62 - struct afs_iget_data { 63 - struct afs_fid fid; 64 - struct afs_volume *volume; /* volume on which resides */ 65 - unsigned int cb_v_break; /* Pre-fetch volume break count */ 66 - unsigned int cb_s_break; /* Pre-fetch server break count */ 67 - }; 68 - 69 62 enum afs_call_state { 70 63 AFS_CALL_CL_REQUESTING, /* Client: Request is being sent */ 71 64 AFS_CALL_CL_AWAIT_REPLY, /* Client: Awaiting reply */ ··· 83 90 unsigned char nr_ipv4; /* Number of IPv4 addresses */ 84 91 enum dns_record_source source:8; 85 92 enum dns_lookup_status status:8; 86 - unsigned long probed; /* Mask of servers that have been probed */ 87 93 unsigned long failed; /* Mask of addrs that failed locally/ICMP */ 88 94 unsigned long responded; /* Mask of addrs that responded */ 89 95 struct sockaddr_rxrpc addrs[]; ··· 103 111 struct afs_net *net; /* The network namespace */ 104 112 struct afs_server *server; /* The fileserver record if fs op (pins ref) */ 105 113 struct afs_vlserver *vlserver; /* The vlserver record if vl op */ 106 - struct afs_cb_interest *cbi; /* Callback interest for server used */ 107 - struct afs_vnode *lvnode; /* vnode being locked */ 108 114 void *request; /* request data (first part) */ 109 - struct address_space *mapping; /* Pages being written from */ 110 115 struct iov_iter def_iter; /* Default buffer/data iterator */ 111 116 struct iov_iter *iter; /* Iterator currently in use */ 112 117 union { /* Convenience for ->def_iter */ ··· 115 126 long ret0; /* Value to reply with instead of 0 */ 116 127 struct afs_addr_list *ret_alist; 117 128 struct afs_vldb_entry *ret_vldb; 118 - struct afs_acl *ret_acl; 129 + char *ret_str; 119 130 }; 120 - struct afs_fid *out_fid; 121 - struct afs_status_cb *out_dir_scb; 122 - struct afs_status_cb *out_scb; 123 - struct yfs_acl *out_yacl; 124 - struct afs_volsync *out_volsync; 125 - struct afs_volume_status *out_volstatus; 126 - struct afs_read *read_request; 131 + struct afs_operation *op; 127 132 unsigned int server_index; 128 - pgoff_t first; /* first page in mapping to deal with */ 129 - pgoff_t last; /* last page in mapping to deal with */ 130 133 atomic_t usage; 131 134 enum afs_call_state state; 132 135 spinlock_t state_lock; 133 136 int error; /* error code */ 134 137 u32 abort_code; /* Remote abort ID or 0 */ 135 - u32 epoch; 136 138 unsigned int max_lifespan; /* Maximum lifespan to set if not 0 */ 137 139 unsigned request_size; /* size of request data */ 138 140 unsigned reply_max; /* maximum size of reply */ 139 - unsigned first_offset; /* offset into mapping[first] */ 140 - union { 141 - unsigned last_to; /* amount of mapping[last] */ 142 - unsigned count2; /* count used in unmarshalling */ 143 - }; 141 + unsigned count2; /* count used in unmarshalling */ 144 142 unsigned char unmarshall; /* unmarshalling phase */ 145 143 unsigned char addr_ix; /* Address in ->alist */ 146 144 bool drop_ref; /* T if need to drop ref for incoming call */ ··· 137 161 bool upgrade; /* T to request service upgrade */ 138 162 bool have_reply_time; /* T if have got reply_time */ 139 163 bool intr; /* T if interruptible */ 164 + bool unmarshalling_error; /* T if an unmarshalling error occurred */ 140 165 u16 service_id; /* Actual service ID (after upgrade) */ 141 166 unsigned int debug_id; /* Trace ID */ 142 167 u32 operation_ID; /* operation ID for an incoming call */ ··· 268 291 struct timer_list cells_timer; 269 292 atomic_t cells_outstanding; 270 293 seqlock_t cells_lock; 294 + struct mutex cells_alias_lock; 271 295 272 296 struct mutex proc_cells_lock; 273 297 struct hlist_head proc_cells; ··· 277 299 * cell, but in practice, people create aliases and subsets and there's 278 300 * no easy way to distinguish them. 279 301 */ 280 - seqlock_t fs_lock; /* For fs_servers */ 302 + seqlock_t fs_lock; /* For fs_servers, fs_probe_*, fs_proc */ 281 303 struct rb_root fs_servers; /* afs_server (by server UUID or address) */ 282 - struct list_head fs_updates; /* afs_server (by update_at) */ 304 + struct list_head fs_probe_fast; /* List of afs_server to probe at 30s intervals */ 305 + struct list_head fs_probe_slow; /* List of afs_server to probe at 5m intervals */ 283 306 struct hlist_head fs_proc; /* procfs servers list */ 284 307 285 308 struct hlist_head fs_addresses4; /* afs_server (by lowest IPv4 addr) */ ··· 289 310 290 311 struct work_struct fs_manager; 291 312 struct timer_list fs_timer; 313 + 314 + struct work_struct fs_prober; 315 + struct timer_list fs_probe_timer; 292 316 atomic_t servers_outstanding; 293 317 294 318 /* File locking renewal management */ ··· 342 360 * for authentication and encryption. The cell name is not typically used in 343 361 * the protocol. 344 362 * 345 - * There is no easy way to determine if two cells are aliases or one is a 346 - * subset of another. 363 + * Two cells are determined to be aliases if they have an explicit alias (YFS 364 + * only), share any VL servers in common or have at least one volume in common. 365 + * "In common" means that the address list of the VL servers or the fileservers 366 + * share at least one endpoint. 347 367 */ 348 368 struct afs_cell { 349 369 union { ··· 353 369 struct rb_node net_node; /* Node in net->cells */ 354 370 }; 355 371 struct afs_net *net; 372 + struct afs_cell *alias_of; /* The cell this is an alias of */ 373 + struct afs_volume *root_volume; /* The root.cell volume if there is one */ 356 374 struct key *anonymous_key; /* anonymous user key for this cell */ 357 375 struct work_struct manager; /* Manager for init/deinit/dns */ 358 376 struct hlist_node proc_link; /* /proc cell list link */ ··· 367 381 unsigned long flags; 368 382 #define AFS_CELL_FL_NO_GC 0 /* The cell was added manually, don't auto-gc */ 369 383 #define AFS_CELL_FL_DO_LOOKUP 1 /* DNS lookup requested */ 384 + #define AFS_CELL_FL_CHECK_ALIAS 2 /* Need to check for aliases */ 370 385 enum afs_cell_state state; 371 386 short error; 372 387 enum dns_record_source dns_source:8; /* Latest source of data from lookup */ 373 388 enum dns_lookup_status dns_status:8; /* Latest status of data from lookup */ 374 389 unsigned int dns_lookup_count; /* Counter of DNS lookups */ 375 390 391 + /* The volumes belonging to this cell */ 392 + struct rb_root volumes; /* Tree of volumes on this server */ 393 + struct hlist_head proc_volumes; /* procfs volume list */ 394 + seqlock_t volume_lock; /* For volumes */ 395 + 376 396 /* Active fileserver interaction state. */ 377 - struct list_head proc_volumes; /* procfs volume list */ 378 - rwlock_t proc_lock; 397 + struct rb_root fs_servers; /* afs_server (by server UUID) */ 398 + seqlock_t fs_lock; /* For fs_servers */ 379 399 380 400 /* VL server list. */ 381 401 rwlock_t vl_servers_lock; /* Lock on vl_servers */ ··· 463 471 #define AFS_VLDB_QUERY_ERROR 4 /* - VL server returned error */ 464 472 465 473 uuid_t fs_server[AFS_NMAXNSERVERS]; 474 + u32 addr_version[AFS_NMAXNSERVERS]; /* Registration change counters */ 466 475 u8 fs_mask[AFS_NMAXNSERVERS]; 467 476 #define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */ 468 477 #define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */ ··· 485 492 }; 486 493 487 494 struct afs_addr_list __rcu *addresses; 488 - struct rb_node uuid_rb; /* Link in net->servers */ 495 + struct afs_cell *cell; /* Cell to which belongs (pins ref) */ 496 + struct rb_node uuid_rb; /* Link in net->fs_servers */ 497 + struct afs_server __rcu *uuid_next; /* Next server with same UUID */ 498 + struct afs_server *uuid_prev; /* Previous server with same UUID */ 499 + struct list_head probe_link; /* Link in net->fs_probe_list */ 489 500 struct hlist_node addr4_link; /* Link in net->fs_addresses4 */ 490 501 struct hlist_node addr6_link; /* Link in net->fs_addresses6 */ 491 502 struct hlist_node proc_link; /* Link in net->fs_proc */ 492 503 struct afs_server *gc_next; /* Next server in manager's list */ 493 - time64_t put_time; /* Time at which last put */ 494 - time64_t update_at; /* Time at which to next update the record */ 504 + time64_t unuse_time; /* Time at which last unused */ 495 505 unsigned long flags; 496 - #define AFS_SERVER_FL_NOT_READY 1 /* The record is not ready for use */ 497 - #define AFS_SERVER_FL_NOT_FOUND 2 /* VL server says no such server */ 498 - #define AFS_SERVER_FL_VL_FAIL 3 /* Failed to access VL server */ 499 - #define AFS_SERVER_FL_UPDATING 4 500 - #define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */ 501 - #define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ 502 - #define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */ 506 + #define AFS_SERVER_FL_RESPONDING 0 /* The server is responding */ 507 + #define AFS_SERVER_FL_UPDATING 1 508 + #define AFS_SERVER_FL_NEEDS_UPDATE 2 /* Fileserver address list is out of date */ 509 + #define AFS_SERVER_FL_NOT_READY 4 /* The record is not ready for use */ 510 + #define AFS_SERVER_FL_NOT_FOUND 5 /* VL server says no such server */ 511 + #define AFS_SERVER_FL_VL_FAIL 6 /* Failed to access VL server */ 503 512 #define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */ 504 - #define AFS_SERVER_FL_IS_YFS 9 /* Server is YFS not AFS */ 505 - #define AFS_SERVER_FL_NO_RM2 10 /* Fileserver doesn't support YFS.RemoveFile2 */ 506 - #define AFS_SERVER_FL_HAVE_EPOCH 11 /* ->epoch is valid */ 507 - atomic_t usage; 513 + #define AFS_SERVER_FL_IS_YFS 16 /* Server is YFS not AFS */ 514 + #define AFS_SERVER_FL_NO_IBULK 17 /* Fileserver doesn't support FS.InlineBulkStatus */ 515 + #define AFS_SERVER_FL_NO_RM2 18 /* Fileserver doesn't support YFS.RemoveFile2 */ 516 + atomic_t ref; /* Object refcount */ 517 + atomic_t active; /* Active user count */ 508 518 u32 addr_version; /* Address list version */ 509 - u32 cm_epoch; /* Server RxRPC epoch */ 519 + unsigned int rtt; /* Server's current RTT in uS */ 510 520 unsigned int debug_id; /* Debugging ID for traces */ 511 521 512 522 /* file service access */ 513 523 rwlock_t fs_lock; /* access lock */ 514 524 515 525 /* callback promise management */ 516 - struct hlist_head cb_volumes; /* List of volume interests on this server */ 517 526 unsigned cb_s_break; /* Break-everything counter. */ 518 - rwlock_t cb_break_lock; /* Volume finding lock */ 519 527 520 528 /* Probe state */ 529 + unsigned long probed_at; /* Time last probe was dispatched (jiffies) */ 521 530 wait_queue_head_t probe_wq; 522 531 atomic_t probe_outstanding; 523 532 spinlock_t probe_lock; 524 533 struct { 525 - unsigned int rtt; /* RTT as ktime/64 */ 534 + unsigned int rtt; /* RTT in uS */ 526 535 u32 abort_code; 527 - u32 cm_epoch; 528 536 short error; 529 537 bool responded:1; 530 538 bool is_yfs:1; 531 539 bool not_yfs:1; 532 540 bool local_failure:1; 533 - bool cm_probed:1; 534 - bool said_rebooted:1; 535 - bool said_inconsistent:1; 536 541 } probe; 537 542 }; 538 543 539 544 /* 540 - * Volume collation in the server's callback interest list. 541 - */ 542 - struct afs_vol_interest { 543 - struct hlist_node srv_link; /* Link in server->cb_volumes */ 544 - struct hlist_head cb_interests; /* List of callback interests on the server */ 545 - union { 546 - struct rcu_head rcu; 547 - afs_volid_t vid; /* Volume ID to match */ 548 - }; 549 - unsigned int usage; 550 - }; 551 - 552 - /* 553 - * Interest by a superblock on a server. 554 - */ 555 - struct afs_cb_interest { 556 - struct hlist_node cb_vlink; /* Link in vol_interest->cb_interests */ 557 - struct afs_vol_interest *vol_interest; 558 - struct afs_server *server; /* Server on which this interest resides */ 559 - struct super_block *sb; /* Superblock on which inodes reside */ 560 - union { 561 - struct rcu_head rcu; 562 - afs_volid_t vid; /* Volume ID to match */ 563 - }; 564 - refcount_t usage; 565 - }; 566 - 567 - /* 568 - * Replaceable server list. 545 + * Replaceable volume server list. 569 546 */ 570 547 struct afs_server_entry { 571 548 struct afs_server *server; 572 - struct afs_cb_interest *cb_interest; 573 549 }; 574 550 575 551 struct afs_server_list { 552 + afs_volid_t vids[AFS_MAXTYPES]; /* Volume IDs */ 576 553 refcount_t usage; 577 554 unsigned char nr_servers; 578 555 unsigned char preferred; /* Preferred server */ ··· 556 593 * Live AFS volume management. 557 594 */ 558 595 struct afs_volume { 559 - afs_volid_t vid; /* volume ID */ 596 + union { 597 + struct rcu_head rcu; 598 + afs_volid_t vid; /* volume ID */ 599 + }; 560 600 atomic_t usage; 561 601 time64_t update_at; /* Time at which to next update */ 562 602 struct afs_cell *cell; /* Cell to which belongs (pins ref) */ 563 - struct list_head proc_link; /* Link in cell->vl_proc */ 603 + struct rb_node cell_node; /* Link in cell->volumes */ 604 + struct hlist_node proc_link; /* Link in cell->proc_volumes */ 605 + struct super_block __rcu *sb; /* Superblock on which inodes reside */ 564 606 unsigned long flags; 565 607 #define AFS_VOLUME_NEEDS_UPDATE 0 /* - T if an update needs performing */ 566 608 #define AFS_VOLUME_UPDATING 1 /* - T if an update is in progress */ ··· 573 605 #define AFS_VOLUME_DELETED 3 /* - T if volume appears deleted */ 574 606 #define AFS_VOLUME_OFFLINE 4 /* - T if volume offline notice given */ 575 607 #define AFS_VOLUME_BUSY 5 /* - T if volume busy notice given */ 608 + #define AFS_VOLUME_MAYBE_NO_IBULK 6 /* - T if some servers don't have InlineBulkStatus */ 576 609 #ifdef CONFIG_AFS_FSCACHE 577 610 struct fscache_cookie *cache; /* caching cookie */ 578 611 #endif 579 - struct afs_server_list *servers; /* List of servers on which volume resides */ 612 + struct afs_server_list __rcu *servers; /* List of servers on which volume resides */ 580 613 rwlock_t servers_lock; /* Lock for ->servers */ 581 614 unsigned int servers_seq; /* Incremented each time ->servers changes */ 582 615 ··· 585 616 rwlock_t cb_v_break_lock; 586 617 587 618 afs_voltype_t type; /* type of volume */ 588 - short error; 589 619 char type_force; /* force volume type (suppress R/O -> R/W) */ 590 620 u8 name_len; 591 621 u8 name[AFS_MAXVOLNAME + 1]; /* NUL-padded volume name */ ··· 645 677 afs_lock_type_t lock_type : 8; 646 678 647 679 /* outstanding callback notification on this file */ 648 - struct afs_cb_interest __rcu *cb_interest; /* Server on which this resides */ 680 + void *cb_server; /* Server with callback/filelock */ 649 681 unsigned int cb_s_break; /* Mass break counter on ->server */ 650 682 unsigned int cb_v_break; /* Mass break counter on ->volume */ 651 683 unsigned int cb_break; /* Break counter on vnode */ 652 - seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */ 684 + seqlock_t cb_lock; /* Lock for ->cb_server, ->status, ->cb_*break */ 653 685 654 686 time64_t cb_expires_at; /* time at which callback expires */ 655 687 }; ··· 726 758 }; 727 759 728 760 /* 729 - * Cursor for iterating over a set of fileservers. 761 + * Fileserver operation methods. 730 762 */ 731 - struct afs_fs_cursor { 732 - const struct afs_call_type *type; /* Type of call done */ 733 - struct afs_addr_cursor ac; 763 + struct afs_operation_ops { 764 + void (*issue_afs_rpc)(struct afs_operation *op); 765 + void (*issue_yfs_rpc)(struct afs_operation *op); 766 + void (*success)(struct afs_operation *op); 767 + void (*aborted)(struct afs_operation *op); 768 + void (*edit_dir)(struct afs_operation *op); 769 + void (*put)(struct afs_operation *op); 770 + }; 771 + 772 + struct afs_vnode_param { 734 773 struct afs_vnode *vnode; 735 - struct afs_server_list *server_list; /* Current server list (pins ref) */ 736 - struct afs_cb_interest *cbi; /* Server on which this resides (pins ref) */ 737 - struct key *key; /* Key for the server */ 738 - unsigned long untried; /* Bitmask of untried servers */ 739 - unsigned int cb_break; /* cb_break + cb_s_break before the call */ 740 - unsigned int cb_break_2; /* cb_break + cb_s_break (2nd vnode) */ 741 - short index; /* Current server */ 774 + struct afs_fid fid; /* Fid to access */ 775 + struct afs_status_cb scb; /* Returned status and callback promise */ 776 + afs_dataversion_t dv_before; /* Data version before the call */ 777 + unsigned int cb_break_before; /* cb_break + cb_s_break before the call */ 778 + u8 dv_delta; /* Expected change in data version */ 779 + bool put_vnode; /* T if we have a ref on the vnode */ 780 + bool need_io_lock; /* T if we need the I/O lock on this */ 781 + }; 782 + 783 + /* 784 + * Fileserver operation wrapper, handling server and address rotation 785 + * asynchronously. May make simultaneous calls to multiple servers. 786 + */ 787 + struct afs_operation { 788 + struct afs_net *net; /* Network namespace */ 789 + struct key *key; /* Key for the cell */ 790 + const struct afs_call_type *type; /* Type of call done */ 791 + const struct afs_operation_ops *ops; 792 + 793 + /* Parameters/results for the operation */ 794 + struct afs_volume *volume; /* Volume being accessed */ 795 + struct afs_vnode_param file[2]; 796 + struct afs_vnode_param *more_files; 797 + struct afs_volsync volsync; 798 + struct dentry *dentry; /* Dentry to be altered */ 799 + struct dentry *dentry_2; /* Second dentry to be altered */ 800 + struct timespec64 mtime; /* Modification time to record */ 801 + short nr_files; /* Number of entries in file[], more_files */ 742 802 short error; 743 - unsigned short flags; 744 - #define AFS_FS_CURSOR_STOP 0x0001 /* Set to cease iteration */ 745 - #define AFS_FS_CURSOR_VBUSY 0x0002 /* Set if seen VBUSY */ 746 - #define AFS_FS_CURSOR_VMOVED 0x0004 /* Set if seen VMOVED */ 747 - #define AFS_FS_CURSOR_VNOVOL 0x0008 /* Set if seen VNOVOL */ 748 - #define AFS_FS_CURSOR_CUR_ONLY 0x0010 /* Set if current server only (file lock held) */ 749 - #define AFS_FS_CURSOR_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */ 750 - #define AFS_FS_CURSOR_INTR 0x0040 /* Set if op is interruptible */ 803 + unsigned int abort_code; 804 + unsigned int debug_id; 805 + 806 + unsigned int cb_v_break; /* Volume break counter before op */ 807 + unsigned int cb_s_break; /* Server break counter before op */ 808 + 809 + union { 810 + struct { 811 + int which; /* Which ->file[] to fetch for */ 812 + } fetch_status; 813 + struct { 814 + int reason; /* enum afs_edit_dir_reason */ 815 + mode_t mode; 816 + const char *symlink; 817 + } create; 818 + struct { 819 + bool need_rehash; 820 + } unlink; 821 + struct { 822 + struct dentry *rehash; 823 + struct dentry *tmp; 824 + bool new_negative; 825 + } rename; 826 + struct { 827 + struct afs_read *req; 828 + } fetch; 829 + struct { 830 + struct afs_vnode *lvnode; /* vnode being locked */ 831 + afs_lock_type_t type; 832 + } lock; 833 + struct { 834 + struct address_space *mapping; /* Pages being written from */ 835 + pgoff_t first; /* first page in mapping to deal with */ 836 + pgoff_t last; /* last page in mapping to deal with */ 837 + unsigned first_offset; /* offset into mapping[first] */ 838 + unsigned last_to; /* amount of mapping[last] */ 839 + } store; 840 + struct { 841 + struct iattr *attr; 842 + } setattr; 843 + struct afs_acl *acl; 844 + struct yfs_acl *yacl; 845 + struct { 846 + struct afs_volume_status vs; 847 + struct kstatfs *buf; 848 + } volstatus; 849 + }; 850 + 851 + /* Fileserver iteration state */ 852 + struct afs_addr_cursor ac; 853 + struct afs_server_list *server_list; /* Current server list (pins ref) */ 854 + struct afs_server *server; /* Server we're using (ref pinned by server_list) */ 855 + struct afs_call *call; 856 + unsigned long untried; /* Bitmask of untried servers */ 857 + short index; /* Current server */ 751 858 unsigned short nr_iterations; /* Number of server iterations */ 859 + 860 + unsigned int flags; 861 + #define AFS_OPERATION_STOP 0x0001 /* Set to cease iteration */ 862 + #define AFS_OPERATION_VBUSY 0x0002 /* Set if seen VBUSY */ 863 + #define AFS_OPERATION_VMOVED 0x0004 /* Set if seen VMOVED */ 864 + #define AFS_OPERATION_VNOVOL 0x0008 /* Set if seen VNOVOL */ 865 + #define AFS_OPERATION_CUR_ONLY 0x0010 /* Set if current server only (file lock held) */ 866 + #define AFS_OPERATION_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */ 867 + #define AFS_OPERATION_UNINTR 0x0040 /* Set if op is uninterruptible */ 868 + #define AFS_OPERATION_DOWNGRADE 0x0080 /* Set to retry with downgraded opcode */ 869 + #define AFS_OPERATION_LOCK_0 0x0100 /* Set if have io_lock on file[0] */ 870 + #define AFS_OPERATION_LOCK_1 0x0200 /* Set if have io_lock on file[1] */ 871 + #define AFS_OPERATION_TRIED_ALL 0x0400 /* Set if we've tried all the fileservers */ 872 + #define AFS_OPERATION_RETRY_SERVER 0x0800 /* Set if we should retry the current server */ 752 873 }; 753 874 754 875 /* ··· 895 838 extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason); 896 839 extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break *); 897 840 898 - extern int afs_register_server_cb_interest(struct afs_vnode *, 899 - struct afs_server_list *, unsigned int); 900 - extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *); 901 - extern void afs_clear_callback_interests(struct afs_net *, struct afs_server_list *); 902 - 903 - static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi) 904 - { 905 - if (cbi) 906 - refcount_inc(&cbi->usage); 907 - return cbi; 908 - } 909 - 910 841 static inline unsigned int afs_calc_vnode_cb_break(struct afs_vnode *vnode) 911 842 { 912 843 return vnode->cb_break + vnode->cb_v_break; 913 844 } 914 845 915 846 static inline bool afs_cb_is_broken(unsigned int cb_break, 916 - const struct afs_vnode *vnode, 917 - const struct afs_cb_interest *cbi) 847 + const struct afs_vnode *vnode) 918 848 { 919 - return !cbi || cb_break != (vnode->cb_break + 920 - vnode->volume->cb_v_break); 849 + return cb_break != (vnode->cb_break + vnode->volume->cb_v_break); 921 850 } 922 851 923 852 /* ··· 995 952 /* 996 953 * fsclient.c 997 954 */ 998 - extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_status_cb *, 999 - struct afs_volsync *); 1000 - extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *); 1001 - extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_status_cb *, struct afs_read *); 1002 - extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, 1003 - struct afs_status_cb *, struct afs_fid *, struct afs_status_cb *); 1004 - extern int afs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool, 1005 - struct afs_status_cb *); 1006 - extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, 1007 - struct afs_status_cb *, struct afs_status_cb *); 1008 - extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, 1009 - struct afs_status_cb *, struct afs_fid *, struct afs_status_cb *); 1010 - extern int afs_fs_rename(struct afs_fs_cursor *, const char *, 1011 - struct afs_vnode *, const char *, 1012 - struct afs_status_cb *, struct afs_status_cb *); 1013 - extern int afs_fs_store_data(struct afs_fs_cursor *, struct address_space *, 1014 - pgoff_t, pgoff_t, unsigned, unsigned, struct afs_status_cb *); 1015 - extern int afs_fs_setattr(struct afs_fs_cursor *, struct iattr *, struct afs_status_cb *); 1016 - extern int afs_fs_get_volume_status(struct afs_fs_cursor *, struct afs_volume_status *); 1017 - extern int afs_fs_set_lock(struct afs_fs_cursor *, afs_lock_type_t, struct afs_status_cb *); 1018 - extern int afs_fs_extend_lock(struct afs_fs_cursor *, struct afs_status_cb *); 1019 - extern int afs_fs_release_lock(struct afs_fs_cursor *, struct afs_status_cb *); 955 + extern void afs_fs_fetch_status(struct afs_operation *); 956 + extern void afs_fs_fetch_data(struct afs_operation *); 957 + extern void afs_fs_create_file(struct afs_operation *); 958 + extern void afs_fs_make_dir(struct afs_operation *); 959 + extern void afs_fs_remove_file(struct afs_operation *); 960 + extern void afs_fs_remove_dir(struct afs_operation *); 961 + extern void afs_fs_link(struct afs_operation *); 962 + extern void afs_fs_symlink(struct afs_operation *); 963 + extern void afs_fs_rename(struct afs_operation *); 964 + extern void afs_fs_store_data(struct afs_operation *); 965 + extern void afs_fs_setattr(struct afs_operation *); 966 + extern void afs_fs_get_volume_status(struct afs_operation *); 967 + extern void afs_fs_set_lock(struct afs_operation *); 968 + extern void afs_fs_extend_lock(struct afs_operation *); 969 + extern void afs_fs_release_lock(struct afs_operation *); 1020 970 extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *, 1021 971 struct afs_addr_cursor *, struct key *); 1022 - extern struct afs_call *afs_fs_get_capabilities(struct afs_net *, struct afs_server *, 1023 - struct afs_addr_cursor *, struct key *, 1024 - unsigned int); 1025 - extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, 1026 - struct afs_fid *, struct afs_status_cb *, 1027 - unsigned int, struct afs_volsync *); 1028 - extern int afs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *, 1029 - struct afs_fid *, struct afs_status_cb *, 1030 - struct afs_volsync *); 972 + extern bool afs_fs_get_capabilities(struct afs_net *, struct afs_server *, 973 + struct afs_addr_cursor *, struct key *); 974 + extern void afs_fs_inline_bulk_status(struct afs_operation *); 1031 975 1032 976 struct afs_acl { 1033 977 u32 size; 1034 978 u8 data[]; 1035 979 }; 1036 980 1037 - extern struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *, struct afs_status_cb *); 1038 - extern int afs_fs_store_acl(struct afs_fs_cursor *, const struct afs_acl *, 1039 - struct afs_status_cb *); 981 + extern void afs_fs_fetch_acl(struct afs_operation *); 982 + extern void afs_fs_store_acl(struct afs_operation *); 983 + 984 + /* 985 + * fs_operation.c 986 + */ 987 + extern struct afs_operation *afs_alloc_operation(struct key *, struct afs_volume *); 988 + extern int afs_put_operation(struct afs_operation *); 989 + extern bool afs_begin_vnode_operation(struct afs_operation *); 990 + extern void afs_wait_for_operation(struct afs_operation *); 991 + extern int afs_do_sync_operation(struct afs_operation *); 992 + 993 + static inline void afs_op_nomem(struct afs_operation *op) 994 + { 995 + op->error = -ENOMEM; 996 + } 997 + 998 + static inline void afs_op_set_vnode(struct afs_operation *op, unsigned int n, 999 + struct afs_vnode *vnode) 1000 + { 1001 + op->file[n].vnode = vnode; 1002 + op->file[n].need_io_lock = true; 1003 + } 1004 + 1005 + static inline void afs_op_set_fid(struct afs_operation *op, unsigned int n, 1006 + const struct afs_fid *fid) 1007 + { 1008 + op->file[n].fid = *fid; 1009 + } 1040 1010 1041 1011 /* 1042 1012 * fs_probe.c 1043 1013 */ 1044 1014 extern void afs_fileserver_probe_result(struct afs_call *); 1045 - extern int afs_probe_fileservers(struct afs_net *, struct key *, struct afs_server_list *); 1015 + extern void afs_fs_probe_fileserver(struct afs_net *, struct afs_server *, struct key *, bool); 1046 1016 extern int afs_wait_for_fs_probes(struct afs_server_list *, unsigned long); 1017 + extern void afs_probe_fileserver(struct afs_net *, struct afs_server *); 1018 + extern void afs_fs_probe_dispatcher(struct work_struct *); 1019 + extern int afs_wait_for_one_fs_probe(struct afs_server *, bool); 1047 1020 1048 1021 /* 1049 1022 * inode.c 1050 1023 */ 1051 - extern void afs_vnode_commit_status(struct afs_fs_cursor *, 1052 - struct afs_vnode *, 1053 - unsigned int, 1054 - const afs_dataversion_t *, 1055 - struct afs_status_cb *); 1024 + extern void afs_vnode_commit_status(struct afs_operation *, struct afs_vnode_param *); 1056 1025 extern int afs_fetch_status(struct afs_vnode *, struct key *, bool, afs_access_t *); 1057 - extern int afs_iget5_test(struct inode *, void *); 1026 + extern int afs_ilookup5_test_by_fid(struct inode *, void *); 1058 1027 extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool); 1059 - extern struct inode *afs_iget(struct super_block *, struct key *, 1060 - struct afs_iget_data *, struct afs_status_cb *, 1061 - struct afs_cb_interest *, 1062 - struct afs_vnode *); 1028 + extern struct inode *afs_iget(struct afs_operation *, struct afs_vnode_param *); 1029 + extern struct inode *afs_root_iget(struct super_block *, struct key *); 1063 1030 extern void afs_zap_data(struct afs_vnode *); 1064 1031 extern bool afs_check_validity(struct afs_vnode *); 1065 1032 extern int afs_validate(struct afs_vnode *, struct key *); ··· 1157 1104 /* 1158 1105 * rotate.c 1159 1106 */ 1160 - extern bool afs_begin_vnode_operation(struct afs_fs_cursor *, struct afs_vnode *, 1161 - struct key *, bool); 1162 - extern bool afs_select_fileserver(struct afs_fs_cursor *); 1163 - extern bool afs_select_current_fileserver(struct afs_fs_cursor *); 1164 - extern int afs_end_vnode_operation(struct afs_fs_cursor *); 1107 + extern bool afs_select_fileserver(struct afs_operation *); 1108 + extern void afs_dump_edestaddrreq(const struct afs_operation *); 1165 1109 1166 1110 /* 1167 1111 * rxrpc.c ··· 1178 1128 extern void afs_send_empty_reply(struct afs_call *); 1179 1129 extern void afs_send_simple_reply(struct afs_call *, const void *, size_t); 1180 1130 extern int afs_extract_data(struct afs_call *, bool); 1181 - extern int afs_protocol_error(struct afs_call *, int, enum afs_eproto_cause); 1131 + extern int afs_protocol_error(struct afs_call *, enum afs_eproto_cause); 1182 1132 1183 - static inline void afs_set_fc_call(struct afs_call *call, struct afs_fs_cursor *fc) 1133 + static inline void afs_make_op_call(struct afs_operation *op, struct afs_call *call, 1134 + gfp_t gfp) 1184 1135 { 1185 - call->intr = fc->flags & AFS_FS_CURSOR_INTR; 1186 - fc->type = call->type; 1136 + op->call = call; 1137 + op->type = call->type; 1138 + call->op = op; 1139 + call->key = op->key; 1140 + call->intr = !(op->flags & AFS_OPERATION_UNINTR); 1141 + afs_make_call(&op->ac, call, gfp); 1187 1142 } 1188 1143 1189 1144 static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t size) ··· 1296 1241 extern struct afs_server *afs_find_server(struct afs_net *, 1297 1242 const struct sockaddr_rxrpc *); 1298 1243 extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *); 1299 - extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *); 1244 + extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *, u32); 1300 1245 extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace); 1246 + extern struct afs_server *afs_use_server(struct afs_server *, enum afs_server_trace); 1247 + extern void afs_unuse_server(struct afs_net *, struct afs_server *, enum afs_server_trace); 1248 + extern void afs_unuse_server_notime(struct afs_net *, struct afs_server *, enum afs_server_trace); 1301 1249 extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace); 1302 1250 extern void afs_manage_servers(struct work_struct *); 1303 1251 extern void afs_servers_timer(struct timer_list *); 1252 + extern void afs_fs_probe_timer(struct timer_list *); 1304 1253 extern void __net_exit afs_purge_servers(struct afs_net *); 1305 - extern bool afs_check_server_record(struct afs_fs_cursor *, struct afs_server *); 1254 + extern bool afs_check_server_record(struct afs_operation *, struct afs_server *); 1255 + 1256 + static inline void afs_inc_servers_outstanding(struct afs_net *net) 1257 + { 1258 + atomic_inc(&net->servers_outstanding); 1259 + } 1260 + 1261 + static inline void afs_dec_servers_outstanding(struct afs_net *net) 1262 + { 1263 + if (atomic_dec_and_test(&net->servers_outstanding)) 1264 + wake_up_var(&net->servers_outstanding); 1265 + } 1266 + 1267 + static inline bool afs_is_probing_server(struct afs_server *server) 1268 + { 1269 + return list_empty(&server->probe_link); 1270 + } 1306 1271 1307 1272 /* 1308 1273 * server_list.c ··· 1354 1279 extern struct afs_call *afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *, 1355 1280 struct key *, struct afs_vlserver *, unsigned int); 1356 1281 extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *); 1282 + extern char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *); 1283 + 1284 + /* 1285 + * vl_alias.c 1286 + */ 1287 + extern int afs_cell_detect_alias(struct afs_cell *, struct key *); 1357 1288 1358 1289 /* 1359 1290 * vl_probe.c ··· 1403 1322 /* 1404 1323 * volume.c 1405 1324 */ 1406 - static inline struct afs_volume *__afs_get_volume(struct afs_volume *volume) 1407 - { 1408 - if (volume) 1409 - atomic_inc(&volume->usage); 1410 - return volume; 1411 - } 1412 - 1413 1325 extern struct afs_volume *afs_create_volume(struct afs_fs_context *); 1414 1326 extern void afs_activate_volume(struct afs_volume *); 1415 1327 extern void afs_deactivate_volume(struct afs_volume *); 1416 - extern void afs_put_volume(struct afs_cell *, struct afs_volume *); 1417 - extern int afs_check_volume_status(struct afs_volume *, struct afs_fs_cursor *); 1328 + extern struct afs_volume *afs_get_volume(struct afs_volume *, enum afs_volume_trace); 1329 + extern void afs_put_volume(struct afs_net *, struct afs_volume *, enum afs_volume_trace); 1330 + extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *); 1418 1331 1419 1332 /* 1420 1333 * write.c ··· 1437 1362 /* 1438 1363 * yfsclient.c 1439 1364 */ 1440 - extern int yfs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_status_cb *, 1441 - struct afs_volsync *); 1442 - extern int yfs_fs_fetch_data(struct afs_fs_cursor *, struct afs_status_cb *, struct afs_read *); 1443 - extern int yfs_fs_create_file(struct afs_fs_cursor *, const char *, umode_t, struct afs_status_cb *, 1444 - struct afs_fid *, struct afs_status_cb *); 1445 - extern int yfs_fs_make_dir(struct afs_fs_cursor *, const char *, umode_t, struct afs_status_cb *, 1446 - struct afs_fid *, struct afs_status_cb *); 1447 - extern int yfs_fs_remove_file2(struct afs_fs_cursor *, struct afs_vnode *, const char *, 1448 - struct afs_status_cb *, struct afs_status_cb *); 1449 - extern int yfs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool, 1450 - struct afs_status_cb *); 1451 - extern int yfs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, 1452 - struct afs_status_cb *, struct afs_status_cb *); 1453 - extern int yfs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, 1454 - struct afs_status_cb *, struct afs_fid *, struct afs_status_cb *); 1455 - extern int yfs_fs_rename(struct afs_fs_cursor *, const char *, struct afs_vnode *, const char *, 1456 - struct afs_status_cb *, struct afs_status_cb *); 1457 - extern int yfs_fs_store_data(struct afs_fs_cursor *, struct address_space *, 1458 - pgoff_t, pgoff_t, unsigned, unsigned, struct afs_status_cb *); 1459 - extern int yfs_fs_setattr(struct afs_fs_cursor *, struct iattr *, struct afs_status_cb *); 1460 - extern int yfs_fs_get_volume_status(struct afs_fs_cursor *, struct afs_volume_status *); 1461 - extern int yfs_fs_set_lock(struct afs_fs_cursor *, afs_lock_type_t, struct afs_status_cb *); 1462 - extern int yfs_fs_extend_lock(struct afs_fs_cursor *, struct afs_status_cb *); 1463 - extern int yfs_fs_release_lock(struct afs_fs_cursor *, struct afs_status_cb *); 1464 - extern int yfs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *, 1465 - struct afs_fid *, struct afs_status_cb *, 1466 - struct afs_volsync *); 1467 - extern int yfs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, 1468 - struct afs_fid *, struct afs_status_cb *, 1469 - unsigned int, struct afs_volsync *); 1365 + extern void yfs_fs_fetch_file_status(struct afs_operation *); 1366 + extern void yfs_fs_fetch_data(struct afs_operation *); 1367 + extern void yfs_fs_create_file(struct afs_operation *); 1368 + extern void yfs_fs_make_dir(struct afs_operation *); 1369 + extern void yfs_fs_remove_file2(struct afs_operation *); 1370 + extern void yfs_fs_remove_file(struct afs_operation *); 1371 + extern void yfs_fs_remove_dir(struct afs_operation *); 1372 + extern void yfs_fs_link(struct afs_operation *); 1373 + extern void yfs_fs_symlink(struct afs_operation *); 1374 + extern void yfs_fs_rename(struct afs_operation *); 1375 + extern void yfs_fs_store_data(struct afs_operation *); 1376 + extern void yfs_fs_setattr(struct afs_operation *); 1377 + extern void yfs_fs_get_volume_status(struct afs_operation *); 1378 + extern void yfs_fs_set_lock(struct afs_operation *); 1379 + extern void yfs_fs_extend_lock(struct afs_operation *); 1380 + extern void yfs_fs_release_lock(struct afs_operation *); 1381 + extern void yfs_fs_fetch_status(struct afs_operation *); 1382 + extern void yfs_fs_inline_bulk_status(struct afs_operation *); 1470 1383 1471 1384 struct yfs_acl { 1472 1385 struct afs_acl *acl; /* Dir/file/symlink ACL */ ··· 1467 1404 }; 1468 1405 1469 1406 extern void yfs_free_opaque_acl(struct yfs_acl *); 1470 - extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, struct yfs_acl *, 1471 - struct afs_status_cb *); 1472 - extern int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *, const struct afs_acl *, 1473 - struct afs_status_cb *); 1407 + extern void yfs_fs_fetch_opaque_acl(struct afs_operation *); 1408 + extern void yfs_fs_store_opaque_acl2(struct afs_operation *); 1474 1409 1475 1410 /* 1476 1411 * Miscellaneous inline functions. ··· 1483 1422 return &vnode->vfs_inode; 1484 1423 } 1485 1424 1486 - static inline void afs_check_for_remote_deletion(struct afs_fs_cursor *fc, 1425 + static inline void afs_check_for_remote_deletion(struct afs_operation *op, 1487 1426 struct afs_vnode *vnode) 1488 1427 { 1489 - if (fc->ac.error == -ENOENT) { 1428 + if (op->error == -ENOENT) { 1490 1429 set_bit(AFS_VNODE_DELETED, &vnode->flags); 1491 1430 afs_break_callback(vnode, afs_cb_break_for_deleted); 1492 1431 } 1432 + } 1433 + 1434 + /* 1435 + * Note that a dentry got changed. We need to set d_fsdata to the data version 1436 + * number derived from the result of the operation. It doesn't matter if 1437 + * d_fsdata goes backwards as we'll just revalidate. 1438 + */ 1439 + static inline void afs_update_dentry_version(struct afs_operation *op, 1440 + struct afs_vnode_param *dir_vp, 1441 + struct dentry *dentry) 1442 + { 1443 + if (!op->error) 1444 + dentry->d_fsdata = 1445 + (void *)(unsigned long)dir_vp->scb.status.data_version; 1493 1446 } 1494 1447 1495 1448 static inline int afs_io_error(struct afs_call *call, enum afs_io_error where)
+5 -1
fs/afs/main.c
··· 82 82 INIT_WORK(&net->cells_manager, afs_manage_cells); 83 83 timer_setup(&net->cells_timer, afs_cells_timer, 0); 84 84 85 + mutex_init(&net->cells_alias_lock); 85 86 mutex_init(&net->proc_cells_lock); 86 87 INIT_HLIST_HEAD(&net->proc_cells); 87 88 88 89 seqlock_init(&net->fs_lock); 89 90 net->fs_servers = RB_ROOT; 90 - INIT_LIST_HEAD(&net->fs_updates); 91 + INIT_LIST_HEAD(&net->fs_probe_fast); 92 + INIT_LIST_HEAD(&net->fs_probe_slow); 91 93 INIT_HLIST_HEAD(&net->fs_proc); 92 94 93 95 INIT_HLIST_HEAD(&net->fs_addresses4); ··· 98 96 99 97 INIT_WORK(&net->fs_manager, afs_manage_servers); 100 98 timer_setup(&net->fs_timer, afs_servers_timer, 0); 99 + INIT_WORK(&net->fs_prober, afs_fs_probe_dispatcher); 100 + timer_setup(&net->fs_probe_timer, afs_fs_probe_timer, 0); 101 101 102 102 ret = -ENOMEM; 103 103 sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);
+23 -19
fs/afs/proc.c
··· 38 38 39 39 if (v == SEQ_START_TOKEN) { 40 40 /* display header on line 1 */ 41 - seq_puts(m, "USE TTL SV NAME\n"); 41 + seq_puts(m, "USE TTL SV ST NAME\n"); 42 42 return 0; 43 43 } 44 44 ··· 46 46 vllist = rcu_dereference(cell->vl_servers); 47 47 48 48 /* display one cell per line on subsequent lines */ 49 - seq_printf(m, "%3u %6lld %2u %s\n", 49 + seq_printf(m, "%3u %6lld %2u %2u %s\n", 50 50 atomic_read(&cell->usage), 51 51 cell->dns_expiry - ktime_get_real_seconds(), 52 52 vllist->nr_servers, 53 + cell->state, 53 54 cell->name); 54 55 return 0; 55 56 } ··· 209 208 */ 210 209 static int afs_proc_cell_volumes_show(struct seq_file *m, void *v) 211 210 { 212 - struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 213 - struct afs_volume *vol = list_entry(v, struct afs_volume, proc_link); 211 + struct afs_volume *vol = hlist_entry(v, struct afs_volume, proc_link); 214 212 215 213 /* Display header on line 1 */ 216 - if (v == &cell->proc_volumes) { 214 + if (v == SEQ_START_TOKEN) { 217 215 seq_puts(m, "USE VID TY NAME\n"); 218 216 return 0; 219 217 } ··· 230 230 { 231 231 struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 232 232 233 - read_lock(&cell->proc_lock); 234 - return seq_list_start_head(&cell->proc_volumes, *_pos); 233 + rcu_read_lock(); 234 + return seq_hlist_start_head_rcu(&cell->proc_volumes, *_pos); 235 235 } 236 236 237 237 static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v, ··· 239 239 { 240 240 struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 241 241 242 - return seq_list_next(v, &cell->proc_volumes, _pos); 242 + return seq_hlist_next_rcu(v, &cell->proc_volumes, _pos); 243 243 } 244 244 245 245 static void afs_proc_cell_volumes_stop(struct seq_file *m, void *v) 246 246 __releases(cell->proc_lock) 247 247 { 248 - struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 249 - 250 - read_unlock(&cell->proc_lock); 248 + rcu_read_unlock(); 251 249 } 252 250 253 251 static const struct seq_operations afs_proc_cell_volumes_ops = { ··· 376 378 int i; 377 379 378 380 if (v == SEQ_START_TOKEN) { 379 - seq_puts(m, "UUID USE ADDR\n"); 381 + seq_puts(m, "UUID REF ACT\n"); 380 382 return 0; 381 383 } 382 384 383 385 server = list_entry(v, struct afs_server, proc_link); 384 386 alist = rcu_dereference(server->addresses); 385 - seq_printf(m, "%pU %3d %pISpc%s\n", 387 + seq_printf(m, "%pU %3d %3d\n", 386 388 &server->uuid, 387 - atomic_read(&server->usage), 388 - &alist->addrs[0].transport, 389 - alist->preferred == 0 ? "*" : ""); 390 - for (i = 1; i < alist->nr_addrs; i++) 391 - seq_printf(m, " %pISpc%s\n", 392 - &alist->addrs[i].transport, 389 + atomic_read(&server->ref), 390 + atomic_read(&server->active)); 391 + seq_printf(m, " - info: fl=%lx rtt=%u brk=%x\n", 392 + server->flags, server->rtt, server->cb_s_break); 393 + seq_printf(m, " - probe: last=%d out=%d\n", 394 + (int)(jiffies - server->probed_at) / HZ, 395 + atomic_read(&server->probe_outstanding)); 396 + seq_printf(m, " - ALIST v=%u rsp=%lx f=%lx\n", 397 + alist->version, alist->responded, alist->failed); 398 + for (i = 0; i < alist->nr_addrs; i++) 399 + seq_printf(m, " [%x] %pISpc%s\n", 400 + i, &alist->addrs[i].transport, 393 401 alist->preferred == i ? "*" : ""); 394 402 return 0; 395 403 }
+1 -1
fs/afs/protocol_yfs.h
··· 8 8 #define YFS_FS_SERVICE 2500 9 9 #define YFS_CM_SERVICE 2501 10 10 11 - #define YFSCBMAX 1024 11 + #define YFSCBMAX 1024 12 12 13 13 enum YFS_CM_Operations { 14 14 YFSCBProbe = 206, /* probe client */
+162 -285
fs/afs/rotate.c
··· 15 15 #include "afs_fs.h" 16 16 17 17 /* 18 - * Begin an operation on the fileserver. 19 - * 20 - * Fileserver operations are serialised on the server by vnode, so we serialise 21 - * them here also using the io_lock. 22 - */ 23 - bool afs_begin_vnode_operation(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 24 - struct key *key, bool intr) 25 - { 26 - memset(fc, 0, sizeof(*fc)); 27 - fc->vnode = vnode; 28 - fc->key = key; 29 - fc->ac.error = SHRT_MAX; 30 - fc->error = -EDESTADDRREQ; 31 - 32 - if (intr) { 33 - fc->flags |= AFS_FS_CURSOR_INTR; 34 - if (mutex_lock_interruptible(&vnode->io_lock) < 0) { 35 - fc->error = -EINTR; 36 - fc->flags |= AFS_FS_CURSOR_STOP; 37 - return false; 38 - } 39 - } else { 40 - mutex_lock(&vnode->io_lock); 41 - } 42 - 43 - if (vnode->lock_state != AFS_VNODE_LOCK_NONE) 44 - fc->flags |= AFS_FS_CURSOR_CUR_ONLY; 45 - return true; 46 - } 47 - 48 - /* 49 18 * Begin iteration through a server list, starting with the vnode's last used 50 19 * server if possible, or the last recorded good server if not. 51 20 */ 52 - static bool afs_start_fs_iteration(struct afs_fs_cursor *fc, 21 + static bool afs_start_fs_iteration(struct afs_operation *op, 53 22 struct afs_vnode *vnode) 54 23 { 55 - struct afs_cb_interest *cbi; 24 + struct afs_server *server; 25 + void *cb_server; 56 26 int i; 57 27 58 - read_lock(&vnode->volume->servers_lock); 59 - fc->server_list = afs_get_serverlist(vnode->volume->servers); 60 - read_unlock(&vnode->volume->servers_lock); 28 + read_lock(&op->volume->servers_lock); 29 + op->server_list = afs_get_serverlist( 30 + rcu_dereference_protected(op->volume->servers, 31 + lockdep_is_held(&op->volume->servers_lock))); 32 + read_unlock(&op->volume->servers_lock); 61 33 62 - fc->untried = (1UL << fc->server_list->nr_servers) - 1; 63 - fc->index = READ_ONCE(fc->server_list->preferred); 34 + op->untried = (1UL << op->server_list->nr_servers) - 1; 35 + op->index = READ_ONCE(op->server_list->preferred); 64 36 65 - cbi = rcu_dereference_protected(vnode->cb_interest, 66 - lockdep_is_held(&vnode->io_lock)); 67 - if (cbi) { 37 + cb_server = vnode->cb_server; 38 + if (cb_server) { 68 39 /* See if the vnode's preferred record is still available */ 69 - for (i = 0; i < fc->server_list->nr_servers; i++) { 70 - if (fc->server_list->servers[i].cb_interest == cbi) { 71 - fc->index = i; 40 + for (i = 0; i < op->server_list->nr_servers; i++) { 41 + server = op->server_list->servers[i].server; 42 + if (server == cb_server) { 43 + op->index = i; 72 44 goto found_interest; 73 45 } 74 46 } ··· 49 77 * serving this vnode, then we can't switch to another server 50 78 * and have to return an error. 51 79 */ 52 - if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) { 53 - fc->error = -ESTALE; 80 + if (op->flags & AFS_OPERATION_CUR_ONLY) { 81 + op->error = -ESTALE; 54 82 return false; 55 83 } 56 84 57 85 /* Note that the callback promise is effectively broken */ 58 86 write_seqlock(&vnode->cb_lock); 59 - ASSERTCMP(cbi, ==, rcu_access_pointer(vnode->cb_interest)); 60 - rcu_assign_pointer(vnode->cb_interest, NULL); 87 + ASSERTCMP(cb_server, ==, vnode->cb_server); 88 + vnode->cb_server = NULL; 61 89 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) 62 90 vnode->cb_break++; 63 91 write_sequnlock(&vnode->cb_lock); 64 - 65 - afs_put_cb_interest(afs_v2net(vnode), cbi); 66 - cbi = NULL; 67 92 } 68 93 69 94 found_interest: ··· 87 118 /* 88 119 * Sleep and retry the operation to the same fileserver. 89 120 */ 90 - static bool afs_sleep_and_retry(struct afs_fs_cursor *fc) 121 + static bool afs_sleep_and_retry(struct afs_operation *op) 91 122 { 92 - if (fc->flags & AFS_FS_CURSOR_INTR) { 123 + if (!(op->flags & AFS_OPERATION_UNINTR)) { 93 124 msleep_interruptible(1000); 94 125 if (signal_pending(current)) { 95 - fc->error = -ERESTARTSYS; 126 + op->error = -ERESTARTSYS; 96 127 return false; 97 128 } 98 129 } else { ··· 106 137 * Select the fileserver to use. May be called multiple times to rotate 107 138 * through the fileservers. 108 139 */ 109 - bool afs_select_fileserver(struct afs_fs_cursor *fc) 140 + bool afs_select_fileserver(struct afs_operation *op) 110 141 { 111 142 struct afs_addr_list *alist; 112 143 struct afs_server *server; 113 - struct afs_vnode *vnode = fc->vnode; 144 + struct afs_vnode *vnode = op->file[0].vnode; 114 145 struct afs_error e; 115 146 u32 rtt; 116 - int error = fc->ac.error, i; 147 + int error = op->ac.error, i; 117 148 118 149 _enter("%lx[%d],%lx[%d],%d,%d", 119 - fc->untried, fc->index, 120 - fc->ac.tried, fc->ac.index, 121 - error, fc->ac.abort_code); 150 + op->untried, op->index, 151 + op->ac.tried, op->ac.index, 152 + error, op->ac.abort_code); 122 153 123 - if (fc->flags & AFS_FS_CURSOR_STOP) { 154 + if (op->flags & AFS_OPERATION_STOP) { 124 155 _leave(" = f [stopped]"); 125 156 return false; 126 157 } 127 158 128 - fc->nr_iterations++; 159 + op->nr_iterations++; 129 160 130 161 /* Evaluate the result of the previous operation, if there was one. */ 131 162 switch (error) { ··· 135 166 case 0: 136 167 default: 137 168 /* Success or local failure. Stop. */ 138 - fc->error = error; 139 - fc->flags |= AFS_FS_CURSOR_STOP; 169 + op->error = error; 170 + op->flags |= AFS_OPERATION_STOP; 140 171 _leave(" = f [okay/local %d]", error); 141 172 return false; 142 173 ··· 144 175 /* The far side rejected the operation on some grounds. This 145 176 * might involve the server being busy or the volume having been moved. 146 177 */ 147 - switch (fc->ac.abort_code) { 178 + switch (op->ac.abort_code) { 148 179 case VNOVOL: 149 180 /* This fileserver doesn't know about the volume. 150 181 * - May indicate that the VL is wrong - retry once and compare 151 182 * the results. 152 183 * - May indicate that the fileserver couldn't attach to the vol. 153 184 */ 154 - if (fc->flags & AFS_FS_CURSOR_VNOVOL) { 155 - fc->error = -EREMOTEIO; 185 + if (op->flags & AFS_OPERATION_VNOVOL) { 186 + op->error = -EREMOTEIO; 156 187 goto next_server; 157 188 } 158 189 159 - write_lock(&vnode->volume->servers_lock); 160 - fc->server_list->vnovol_mask |= 1 << fc->index; 161 - write_unlock(&vnode->volume->servers_lock); 190 + write_lock(&op->volume->servers_lock); 191 + op->server_list->vnovol_mask |= 1 << op->index; 192 + write_unlock(&op->volume->servers_lock); 162 193 163 - set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags); 164 - error = afs_check_volume_status(vnode->volume, fc); 194 + set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags); 195 + error = afs_check_volume_status(op->volume, op); 165 196 if (error < 0) 166 197 goto failed_set_error; 167 198 168 - if (test_bit(AFS_VOLUME_DELETED, &vnode->volume->flags)) { 169 - fc->error = -ENOMEDIUM; 199 + if (test_bit(AFS_VOLUME_DELETED, &op->volume->flags)) { 200 + op->error = -ENOMEDIUM; 170 201 goto failed; 171 202 } 172 203 173 204 /* If the server list didn't change, then assume that 174 205 * it's the fileserver having trouble. 175 206 */ 176 - if (vnode->volume->servers == fc->server_list) { 177 - fc->error = -EREMOTEIO; 207 + if (rcu_access_pointer(op->volume->servers) == op->server_list) { 208 + op->error = -EREMOTEIO; 178 209 goto next_server; 179 210 } 180 211 181 212 /* Try again */ 182 - fc->flags |= AFS_FS_CURSOR_VNOVOL; 213 + op->flags |= AFS_OPERATION_VNOVOL; 183 214 _leave(" = t [vnovol]"); 184 215 return true; 185 216 ··· 189 220 case VONLINE: 190 221 case VDISKFULL: 191 222 case VOVERQUOTA: 192 - fc->error = afs_abort_to_error(fc->ac.abort_code); 223 + op->error = afs_abort_to_error(op->ac.abort_code); 193 224 goto next_server; 194 225 195 226 case VOFFLINE: 196 - if (!test_and_set_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags)) { 197 - afs_busy(vnode->volume, fc->ac.abort_code); 198 - clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags); 227 + if (!test_and_set_bit(AFS_VOLUME_OFFLINE, &op->volume->flags)) { 228 + afs_busy(op->volume, op->ac.abort_code); 229 + clear_bit(AFS_VOLUME_BUSY, &op->volume->flags); 199 230 } 200 - if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) { 201 - fc->error = -EADV; 231 + if (op->flags & AFS_OPERATION_NO_VSLEEP) { 232 + op->error = -EADV; 202 233 goto failed; 203 234 } 204 - if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) { 205 - fc->error = -ESTALE; 235 + if (op->flags & AFS_OPERATION_CUR_ONLY) { 236 + op->error = -ESTALE; 206 237 goto failed; 207 238 } 208 239 goto busy; ··· 213 244 /* Retry after going round all the servers unless we 214 245 * have a file lock we need to maintain. 215 246 */ 216 - if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) { 217 - fc->error = -EBUSY; 247 + if (op->flags & AFS_OPERATION_NO_VSLEEP) { 248 + op->error = -EBUSY; 218 249 goto failed; 219 250 } 220 - if (!test_and_set_bit(AFS_VOLUME_BUSY, &vnode->volume->flags)) { 221 - afs_busy(vnode->volume, fc->ac.abort_code); 222 - clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags); 251 + if (!test_and_set_bit(AFS_VOLUME_BUSY, &op->volume->flags)) { 252 + afs_busy(op->volume, op->ac.abort_code); 253 + clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags); 223 254 } 224 255 busy: 225 - if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) { 226 - if (!afs_sleep_and_retry(fc)) 256 + if (op->flags & AFS_OPERATION_CUR_ONLY) { 257 + if (!afs_sleep_and_retry(op)) 227 258 goto failed; 228 259 229 260 /* Retry with same server & address */ ··· 231 262 return true; 232 263 } 233 264 234 - fc->flags |= AFS_FS_CURSOR_VBUSY; 265 + op->flags |= AFS_OPERATION_VBUSY; 235 266 goto next_server; 236 267 237 268 case VMOVED: ··· 242 273 * We also limit the number of VMOVED hops we will 243 274 * honour, just in case someone sets up a loop. 244 275 */ 245 - if (fc->flags & AFS_FS_CURSOR_VMOVED) { 246 - fc->error = -EREMOTEIO; 276 + if (op->flags & AFS_OPERATION_VMOVED) { 277 + op->error = -EREMOTEIO; 247 278 goto failed; 248 279 } 249 - fc->flags |= AFS_FS_CURSOR_VMOVED; 280 + op->flags |= AFS_OPERATION_VMOVED; 250 281 251 - set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags); 252 - set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags); 253 - error = afs_check_volume_status(vnode->volume, fc); 282 + set_bit(AFS_VOLUME_WAIT, &op->volume->flags); 283 + set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags); 284 + error = afs_check_volume_status(op->volume, op); 254 285 if (error < 0) 255 286 goto failed_set_error; 256 287 ··· 263 294 * 264 295 * TODO: Retry a few times with sleeps. 265 296 */ 266 - if (vnode->volume->servers == fc->server_list) { 267 - fc->error = -ENOMEDIUM; 297 + if (rcu_access_pointer(op->volume->servers) == op->server_list) { 298 + op->error = -ENOMEDIUM; 268 299 goto failed; 269 300 } 270 301 271 302 goto restart_from_beginning; 272 303 273 304 default: 274 - clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags); 275 - clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags); 276 - fc->error = afs_abort_to_error(fc->ac.abort_code); 305 + clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags); 306 + clear_bit(AFS_VOLUME_BUSY, &op->volume->flags); 307 + op->error = afs_abort_to_error(op->ac.abort_code); 277 308 goto failed; 278 309 } 279 310 280 311 case -ETIMEDOUT: 281 312 case -ETIME: 282 - if (fc->error != -EDESTADDRREQ) 313 + if (op->error != -EDESTADDRREQ) 283 314 goto iterate_address; 284 315 /* Fall through */ 285 316 case -ERFKILL: ··· 289 320 case -EHOSTDOWN: 290 321 case -ECONNREFUSED: 291 322 _debug("no conn"); 292 - fc->error = error; 323 + op->error = error; 293 324 goto iterate_address; 294 325 295 326 case -ECONNRESET: 296 327 _debug("call reset"); 297 - fc->error = error; 328 + op->error = error; 298 329 goto failed; 299 330 } 300 331 301 332 restart_from_beginning: 302 333 _debug("restart"); 303 - afs_end_cursor(&fc->ac); 304 - afs_put_cb_interest(afs_v2net(vnode), fc->cbi); 305 - fc->cbi = NULL; 306 - afs_put_serverlist(afs_v2net(vnode), fc->server_list); 307 - fc->server_list = NULL; 334 + afs_end_cursor(&op->ac); 335 + op->server = NULL; 336 + afs_put_serverlist(op->net, op->server_list); 337 + op->server_list = NULL; 308 338 start: 309 339 _debug("start"); 310 340 /* See if we need to do an update of the volume record. Note that the 311 341 * volume may have moved or even have been deleted. 312 342 */ 313 - error = afs_check_volume_status(vnode->volume, fc); 343 + error = afs_check_volume_status(op->volume, op); 314 344 if (error < 0) 315 345 goto failed_set_error; 316 346 317 - if (!afs_start_fs_iteration(fc, vnode)) 347 + if (!afs_start_fs_iteration(op, vnode)) 318 348 goto failed; 319 349 320 - _debug("__ VOL %llx __", vnode->volume->vid); 321 - error = afs_probe_fileservers(afs_v2net(vnode), fc->key, fc->server_list); 322 - if (error < 0) 323 - goto failed_set_error; 350 + _debug("__ VOL %llx __", op->volume->vid); 324 351 325 352 pick_server: 326 - _debug("pick [%lx]", fc->untried); 353 + _debug("pick [%lx]", op->untried); 327 354 328 - error = afs_wait_for_fs_probes(fc->server_list, fc->untried); 355 + error = afs_wait_for_fs_probes(op->server_list, op->untried); 329 356 if (error < 0) 330 357 goto failed_set_error; 331 358 332 359 /* Pick the untried server with the lowest RTT. If we have outstanding 333 360 * callbacks, we stick with the server we're already using if we can. 334 361 */ 335 - if (fc->cbi) { 336 - _debug("cbi %u", fc->index); 337 - if (test_bit(fc->index, &fc->untried)) 362 + if (op->server) { 363 + _debug("server %u", op->index); 364 + if (test_bit(op->index, &op->untried)) 338 365 goto selected_server; 339 - afs_put_cb_interest(afs_v2net(vnode), fc->cbi); 340 - fc->cbi = NULL; 341 - _debug("nocbi"); 366 + op->server = NULL; 367 + _debug("no server"); 342 368 } 343 369 344 - fc->index = -1; 370 + op->index = -1; 345 371 rtt = U32_MAX; 346 - for (i = 0; i < fc->server_list->nr_servers; i++) { 347 - struct afs_server *s = fc->server_list->servers[i].server; 372 + for (i = 0; i < op->server_list->nr_servers; i++) { 373 + struct afs_server *s = op->server_list->servers[i].server; 348 374 349 - if (!test_bit(i, &fc->untried) || !s->probe.responded) 375 + if (!test_bit(i, &op->untried) || 376 + !test_bit(AFS_SERVER_FL_RESPONDING, &s->flags)) 350 377 continue; 351 378 if (s->probe.rtt < rtt) { 352 - fc->index = i; 379 + op->index = i; 353 380 rtt = s->probe.rtt; 354 381 } 355 382 } 356 383 357 - if (fc->index == -1) 384 + if (op->index == -1) 358 385 goto no_more_servers; 359 386 360 387 selected_server: 361 - _debug("use %d", fc->index); 362 - __clear_bit(fc->index, &fc->untried); 388 + _debug("use %d", op->index); 389 + __clear_bit(op->index, &op->untried); 363 390 364 391 /* We're starting on a different fileserver from the list. We need to 365 392 * check it, create a callback intercept, find its address list and 366 393 * probe its capabilities before we use it. 367 394 */ 368 - ASSERTCMP(fc->ac.alist, ==, NULL); 369 - server = fc->server_list->servers[fc->index].server; 395 + ASSERTCMP(op->ac.alist, ==, NULL); 396 + server = op->server_list->servers[op->index].server; 370 397 371 - if (!afs_check_server_record(fc, server)) 398 + if (!afs_check_server_record(op, server)) 372 399 goto failed; 373 400 374 401 _debug("USING SERVER: %pU", &server->uuid); 375 402 376 - /* Make sure we've got a callback interest record for this server. We 377 - * have to link it in before we send the request as we can be sent a 378 - * break request before we've finished decoding the reply and 379 - * installing the vnode. 380 - */ 381 - error = afs_register_server_cb_interest(vnode, fc->server_list, 382 - fc->index); 383 - if (error < 0) 384 - goto failed_set_error; 385 - 386 - fc->cbi = afs_get_cb_interest( 387 - rcu_dereference_protected(vnode->cb_interest, 388 - lockdep_is_held(&vnode->io_lock))); 403 + op->flags |= AFS_OPERATION_RETRY_SERVER; 404 + op->server = server; 405 + if (vnode->cb_server != server) { 406 + vnode->cb_server = server; 407 + vnode->cb_s_break = server->cb_s_break; 408 + vnode->cb_v_break = vnode->volume->cb_v_break; 409 + clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 410 + } 389 411 390 412 read_lock(&server->fs_lock); 391 413 alist = rcu_dereference_protected(server->addresses, ··· 384 424 afs_get_addrlist(alist); 385 425 read_unlock(&server->fs_lock); 386 426 387 - memset(&fc->ac, 0, sizeof(fc->ac)); 427 + retry_server: 428 + memset(&op->ac, 0, sizeof(op->ac)); 388 429 389 - if (!fc->ac.alist) 390 - fc->ac.alist = alist; 430 + if (!op->ac.alist) 431 + op->ac.alist = alist; 391 432 else 392 433 afs_put_addrlist(alist); 393 434 394 - fc->ac.index = -1; 435 + op->ac.index = -1; 395 436 396 437 iterate_address: 397 - ASSERT(fc->ac.alist); 438 + ASSERT(op->ac.alist); 398 439 /* Iterate over the current server's address list to try and find an 399 440 * address on which it will respond to us. 400 441 */ 401 - if (!afs_iterate_addresses(&fc->ac)) 402 - goto next_server; 442 + if (!afs_iterate_addresses(&op->ac)) 443 + goto out_of_addresses; 403 444 404 - _debug("address [%u] %u/%u", fc->index, fc->ac.index, fc->ac.alist->nr_addrs); 445 + _debug("address [%u] %u/%u %pISp", 446 + op->index, op->ac.index, op->ac.alist->nr_addrs, 447 + &op->ac.alist->addrs[op->ac.index].transport); 405 448 406 449 _leave(" = t"); 407 450 return true; 408 451 452 + out_of_addresses: 453 + /* We've now had a failure to respond on all of a server's addresses - 454 + * immediately probe them again and consider retrying the server. 455 + */ 456 + afs_probe_fileserver(op->net, op->server); 457 + if (op->flags & AFS_OPERATION_RETRY_SERVER) { 458 + alist = op->ac.alist; 459 + error = afs_wait_for_one_fs_probe( 460 + op->server, !(op->flags & AFS_OPERATION_UNINTR)); 461 + switch (error) { 462 + case 0: 463 + op->flags &= ~AFS_OPERATION_RETRY_SERVER; 464 + goto retry_server; 465 + case -ERESTARTSYS: 466 + goto failed_set_error; 467 + case -ETIME: 468 + case -EDESTADDRREQ: 469 + goto next_server; 470 + } 471 + } 472 + 409 473 next_server: 410 474 _debug("next"); 411 - afs_end_cursor(&fc->ac); 475 + afs_end_cursor(&op->ac); 412 476 goto pick_server; 413 477 414 478 no_more_servers: 415 479 /* That's all the servers poked to no good effect. Try again if some 416 480 * of them were busy. 417 481 */ 418 - if (fc->flags & AFS_FS_CURSOR_VBUSY) 482 + if (op->flags & AFS_OPERATION_VBUSY) 419 483 goto restart_from_beginning; 420 484 421 485 e.error = -EDESTADDRREQ; 422 486 e.responded = false; 423 - for (i = 0; i < fc->server_list->nr_servers; i++) { 424 - struct afs_server *s = fc->server_list->servers[i].server; 487 + for (i = 0; i < op->server_list->nr_servers; i++) { 488 + struct afs_server *s = op->server_list->servers[i].server; 425 489 426 490 afs_prioritise_error(&e, READ_ONCE(s->probe.error), 427 491 s->probe.abort_code); ··· 454 470 error = e.error; 455 471 456 472 failed_set_error: 457 - fc->error = error; 473 + op->error = error; 458 474 failed: 459 - fc->flags |= AFS_FS_CURSOR_STOP; 460 - afs_end_cursor(&fc->ac); 461 - _leave(" = f [failed %d]", fc->error); 462 - return false; 463 - } 464 - 465 - /* 466 - * Select the same fileserver we used for a vnode before and only that 467 - * fileserver. We use this when we have a lock on that file, which is backed 468 - * only by the fileserver we obtained it from. 469 - */ 470 - bool afs_select_current_fileserver(struct afs_fs_cursor *fc) 471 - { 472 - struct afs_vnode *vnode = fc->vnode; 473 - struct afs_cb_interest *cbi; 474 - struct afs_addr_list *alist; 475 - int error = fc->ac.error; 476 - 477 - _enter(""); 478 - 479 - cbi = rcu_dereference_protected(vnode->cb_interest, 480 - lockdep_is_held(&vnode->io_lock)); 481 - 482 - switch (error) { 483 - case SHRT_MAX: 484 - if (!cbi) { 485 - fc->error = -ESTALE; 486 - fc->flags |= AFS_FS_CURSOR_STOP; 487 - return false; 488 - } 489 - 490 - fc->cbi = afs_get_cb_interest(cbi); 491 - 492 - read_lock(&cbi->server->fs_lock); 493 - alist = rcu_dereference_protected(cbi->server->addresses, 494 - lockdep_is_held(&cbi->server->fs_lock)); 495 - afs_get_addrlist(alist); 496 - read_unlock(&cbi->server->fs_lock); 497 - if (!alist) { 498 - fc->error = -ESTALE; 499 - fc->flags |= AFS_FS_CURSOR_STOP; 500 - return false; 501 - } 502 - 503 - memset(&fc->ac, 0, sizeof(fc->ac)); 504 - fc->ac.alist = alist; 505 - fc->ac.index = -1; 506 - goto iterate_address; 507 - 508 - case 0: 509 - default: 510 - /* Success or local failure. Stop. */ 511 - fc->error = error; 512 - fc->flags |= AFS_FS_CURSOR_STOP; 513 - _leave(" = f [okay/local %d]", error); 514 - return false; 515 - 516 - case -ECONNABORTED: 517 - fc->error = afs_abort_to_error(fc->ac.abort_code); 518 - fc->flags |= AFS_FS_CURSOR_STOP; 519 - _leave(" = f [abort]"); 520 - return false; 521 - 522 - case -ERFKILL: 523 - case -EADDRNOTAVAIL: 524 - case -ENETUNREACH: 525 - case -EHOSTUNREACH: 526 - case -EHOSTDOWN: 527 - case -ECONNREFUSED: 528 - case -ETIMEDOUT: 529 - case -ETIME: 530 - _debug("no conn"); 531 - fc->error = error; 532 - goto iterate_address; 533 - } 534 - 535 - iterate_address: 536 - /* Iterate over the current server's address list to try and find an 537 - * address on which it will respond to us. 538 - */ 539 - if (afs_iterate_addresses(&fc->ac)) { 540 - _leave(" = t"); 541 - return true; 542 - } 543 - 544 - afs_end_cursor(&fc->ac); 475 + op->flags |= AFS_OPERATION_STOP; 476 + afs_end_cursor(&op->ac); 477 + _leave(" = f [failed %d]", op->error); 545 478 return false; 546 479 } 547 480 548 481 /* 549 482 * Dump cursor state in the case of the error being EDESTADDRREQ. 550 483 */ 551 - static void afs_dump_edestaddrreq(const struct afs_fs_cursor *fc) 484 + void afs_dump_edestaddrreq(const struct afs_operation *op) 552 485 { 553 486 static int count; 554 487 int i; ··· 477 576 rcu_read_lock(); 478 577 479 578 pr_notice("EDESTADDR occurred\n"); 480 - pr_notice("FC: cbb=%x cbb2=%x fl=%hx err=%hd\n", 481 - fc->cb_break, fc->cb_break_2, fc->flags, fc->error); 579 + pr_notice("FC: cbb=%x cbb2=%x fl=%x err=%hd\n", 580 + op->file[0].cb_break_before, 581 + op->file[1].cb_break_before, op->flags, op->error); 482 582 pr_notice("FC: ut=%lx ix=%d ni=%u\n", 483 - fc->untried, fc->index, fc->nr_iterations); 583 + op->untried, op->index, op->nr_iterations); 484 584 485 - if (fc->server_list) { 486 - const struct afs_server_list *sl = fc->server_list; 585 + if (op->server_list) { 586 + const struct afs_server_list *sl = op->server_list; 487 587 pr_notice("FC: SL nr=%u pr=%u vnov=%hx\n", 488 588 sl->nr_servers, sl->preferred, sl->vnovol_mask); 489 589 for (i = 0; i < sl->nr_servers; i++) { ··· 498 596 a->version, 499 597 a->nr_ipv4, a->nr_addrs, a->max_addrs, 500 598 a->preferred); 501 - pr_notice("FC: - pr=%lx R=%lx F=%lx\n", 502 - a->probed, a->responded, a->failed); 503 - if (a == fc->ac.alist) 599 + pr_notice("FC: - R=%lx F=%lx\n", 600 + a->responded, a->failed); 601 + if (a == op->ac.alist) 504 602 pr_notice("FC: - current\n"); 505 603 } 506 604 } 507 605 } 508 606 509 607 pr_notice("AC: t=%lx ax=%u ac=%d er=%d r=%u ni=%u\n", 510 - fc->ac.tried, fc->ac.index, fc->ac.abort_code, fc->ac.error, 511 - fc->ac.responded, fc->ac.nr_iterations); 608 + op->ac.tried, op->ac.index, op->ac.abort_code, op->ac.error, 609 + op->ac.responded, op->ac.nr_iterations); 512 610 rcu_read_unlock(); 513 - } 514 - 515 - /* 516 - * Tidy up a filesystem cursor and unlock the vnode. 517 - */ 518 - int afs_end_vnode_operation(struct afs_fs_cursor *fc) 519 - { 520 - struct afs_net *net = afs_v2net(fc->vnode); 521 - 522 - if (fc->error == -EDESTADDRREQ || 523 - fc->error == -EADDRNOTAVAIL || 524 - fc->error == -ENETUNREACH || 525 - fc->error == -EHOSTUNREACH) 526 - afs_dump_edestaddrreq(fc); 527 - 528 - mutex_unlock(&fc->vnode->io_lock); 529 - 530 - afs_end_cursor(&fc->ac); 531 - afs_put_cb_interest(net, fc->cbi); 532 - afs_put_serverlist(net, fc->server_list); 533 - 534 - if (fc->error == -ECONNABORTED) 535 - fc->error = afs_abort_to_error(fc->ac.abort_code); 536 - 537 - return fc->error; 538 611 }
+26 -19
fs/afs/rxrpc.c
··· 181 181 if (call->type->destructor) 182 182 call->type->destructor(call); 183 183 184 - afs_put_server(call->net, call->server, afs_server_trace_put_call); 185 - afs_put_cb_interest(call->net, call->cbi); 184 + afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call); 186 185 afs_put_addrlist(call->alist); 187 186 kfree(call->request); 188 187 ··· 280 281 struct bio_vec *bv, pgoff_t first, pgoff_t last, 281 282 unsigned offset) 282 283 { 284 + struct afs_operation *op = call->op; 283 285 struct page *pages[AFS_BVEC_MAX]; 284 286 unsigned int nr, n, i, to, bytes = 0; 285 287 286 288 nr = min_t(pgoff_t, last - first + 1, AFS_BVEC_MAX); 287 - n = find_get_pages_contig(call->mapping, first, nr, pages); 289 + n = find_get_pages_contig(op->store.mapping, first, nr, pages); 288 290 ASSERTCMP(n, ==, nr); 289 291 290 292 msg->msg_flags |= MSG_MORE; 291 293 for (i = 0; i < nr; i++) { 292 294 to = PAGE_SIZE; 293 295 if (first + i >= last) { 294 - to = call->last_to; 296 + to = op->store.last_to; 295 297 msg->msg_flags &= ~MSG_MORE; 296 298 } 297 299 bv[i].bv_page = pages[i]; ··· 322 322 */ 323 323 static int afs_send_pages(struct afs_call *call, struct msghdr *msg) 324 324 { 325 + struct afs_operation *op = call->op; 325 326 struct bio_vec bv[AFS_BVEC_MAX]; 326 327 unsigned int bytes, nr, loop, offset; 327 - pgoff_t first = call->first, last = call->last; 328 + pgoff_t first = op->store.first, last = op->store.last; 328 329 int ret; 329 330 330 - offset = call->first_offset; 331 - call->first_offset = 0; 331 + offset = op->store.first_offset; 332 + op->store.first_offset = 0; 332 333 333 334 do { 334 335 afs_load_bvec(call, msg, bv, first, last, offset); ··· 339 338 bytes = msg->msg_iter.count; 340 339 nr = msg->msg_iter.nr_segs; 341 340 342 - ret = rxrpc_kernel_send_data(call->net->socket, call->rxcall, msg, 341 + ret = rxrpc_kernel_send_data(op->net->socket, call->rxcall, msg, 343 342 bytes, afs_notify_end_request_tx); 344 343 for (loop = 0; loop < nr; loop++) 345 344 put_page(bv[loop].bv_page); ··· 349 348 first += nr; 350 349 } while (first <= last); 351 350 352 - trace_afs_sent_pages(call, call->first, last, first, ret); 351 + trace_afs_sent_pages(call, op->store.first, last, first, ret); 353 352 return ret; 354 353 } 355 354 ··· 384 383 */ 385 384 tx_total_len = call->request_size; 386 385 if (call->send_pages) { 387 - if (call->last == call->first) { 388 - tx_total_len += call->last_to - call->first_offset; 386 + struct afs_operation *op = call->op; 387 + 388 + if (op->store.last == op->store.first) { 389 + tx_total_len += op->store.last_to - op->store.first_offset; 389 390 } else { 390 391 /* It looks mathematically like you should be able to 391 392 * combine the following lines with the ones above, but 392 393 * unsigned arithmetic is fun when it wraps... 393 394 */ 394 - tx_total_len += PAGE_SIZE - call->first_offset; 395 - tx_total_len += call->last_to; 396 - tx_total_len += (call->last - call->first - 1) * PAGE_SIZE; 395 + tx_total_len += PAGE_SIZE - op->store.first_offset; 396 + tx_total_len += op->store.last_to; 397 + tx_total_len += (op->store.last - op->store.first - 1) * PAGE_SIZE; 397 398 } 398 399 } 399 400 ··· 541 538 542 539 ret = call->type->deliver(call); 543 540 state = READ_ONCE(call->state); 541 + if (ret == 0 && call->unmarshalling_error) 542 + ret = -EBADMSG; 544 543 switch (ret) { 545 544 case 0: 546 545 afs_queue_call_work(call); 547 546 if (state == AFS_CALL_CL_PROC_REPLY) { 548 - if (call->cbi) 547 + if (call->op) 549 548 set_bit(AFS_SERVER_FL_MAY_HAVE_CB, 550 - &call->cbi->server->flags); 549 + &call->op->server->flags); 551 550 goto call_complete; 552 551 } 553 552 ASSERTCMP(state, >, AFS_CALL_CL_PROC_REPLY); ··· 962 957 /* 963 958 * Log protocol error production. 964 959 */ 965 - noinline int afs_protocol_error(struct afs_call *call, int error, 960 + noinline int afs_protocol_error(struct afs_call *call, 966 961 enum afs_eproto_cause cause) 967 962 { 968 - trace_afs_protocol_error(call, error, cause); 969 - return error; 963 + trace_afs_protocol_error(call, cause); 964 + if (call) 965 + call->unmarshalling_error = true; 966 + return -EBADMSG; 970 967 }
+3 -5
fs/afs/security.c
··· 170 170 break; 171 171 } 172 172 173 - if (afs_cb_is_broken(cb_break, vnode, 174 - rcu_dereference(vnode->cb_interest))) { 173 + if (afs_cb_is_broken(cb_break, vnode)) { 175 174 changed = true; 176 175 break; 177 176 } ··· 200 201 } 201 202 } 202 203 203 - if (afs_cb_is_broken(cb_break, vnode, rcu_dereference(vnode->cb_interest))) 204 + if (afs_cb_is_broken(cb_break, vnode)) 204 205 goto someone_else_changed_it; 205 206 206 207 /* We need a ref on any permits list we want to copy as we'll have to ··· 280 281 rcu_read_lock(); 281 282 spin_lock(&vnode->lock); 282 283 zap = rcu_access_pointer(vnode->permit_cache); 283 - if (!afs_cb_is_broken(cb_break, vnode, rcu_dereference(vnode->cb_interest)) && 284 - zap == permits) 284 + if (!afs_cb_is_broken(cb_break, vnode) && zap == permits) 285 285 rcu_assign_pointer(vnode->permit_cache, replacement); 286 286 else 287 287 zap = replacement;
+197 -102
fs/afs/server.c
··· 12 12 #include "protocol_yfs.h" 13 13 14 14 static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */ 15 - static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */ 16 15 static atomic_t afs_server_debug_id; 17 16 18 - static void afs_inc_servers_outstanding(struct afs_net *net) 19 - { 20 - atomic_inc(&net->servers_outstanding); 21 - } 22 - 23 - static void afs_dec_servers_outstanding(struct afs_net *net) 24 - { 25 - if (atomic_dec_and_test(&net->servers_outstanding)) 26 - wake_up_var(&net->servers_outstanding); 27 - } 17 + static struct afs_server *afs_maybe_use_server(struct afs_server *, 18 + enum afs_server_trace); 19 + static void __afs_put_server(struct afs_net *, struct afs_server *); 28 20 29 21 /* 30 22 * Find a server by one of its addresses. ··· 33 41 34 42 do { 35 43 if (server) 36 - afs_put_server(net, server, afs_server_trace_put_find_rsq); 44 + afs_unuse_server_notime(net, server, afs_server_trace_put_find_rsq); 37 45 server = NULL; 38 46 read_seqbegin_or_lock(&net->fs_addr_lock, &seq); 39 47 ··· 71 79 } 72 80 73 81 server = NULL; 82 + continue; 74 83 found: 75 - if (server && !atomic_inc_not_zero(&server->usage)) 76 - server = NULL; 84 + server = afs_maybe_use_server(server, afs_server_trace_get_by_addr); 77 85 78 86 } while (need_seqretry(&net->fs_addr_lock, seq)); 79 87 ··· 84 92 } 85 93 86 94 /* 87 - * Look up a server by its UUID 95 + * Look up a server by its UUID and mark it active. 88 96 */ 89 97 struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uuid) 90 98 { ··· 100 108 * changes. 101 109 */ 102 110 if (server) 103 - afs_put_server(net, server, afs_server_trace_put_uuid_rsq); 111 + afs_unuse_server(net, server, afs_server_trace_put_uuid_rsq); 104 112 server = NULL; 105 113 106 114 read_seqbegin_or_lock(&net->fs_lock, &seq); ··· 115 123 } else if (diff > 0) { 116 124 p = p->rb_right; 117 125 } else { 118 - afs_get_server(server, afs_server_trace_get_by_uuid); 126 + afs_use_server(server, afs_server_trace_get_by_uuid); 119 127 break; 120 128 } 121 129 ··· 130 138 } 131 139 132 140 /* 133 - * Install a server record in the namespace tree 141 + * Install a server record in the namespace tree. If there's a clash, we stick 142 + * it into a list anchored on whichever afs_server struct is actually in the 143 + * tree. 134 144 */ 135 - static struct afs_server *afs_install_server(struct afs_net *net, 145 + static struct afs_server *afs_install_server(struct afs_cell *cell, 136 146 struct afs_server *candidate) 137 147 { 138 148 const struct afs_addr_list *alist; 139 - struct afs_server *server; 149 + struct afs_server *server, *next; 150 + struct afs_net *net = cell->net; 140 151 struct rb_node **pp, *p; 141 152 int diff; 142 153 ··· 155 160 _debug("- consider %p", p); 156 161 server = rb_entry(p, struct afs_server, uuid_rb); 157 162 diff = memcmp(&candidate->uuid, &server->uuid, sizeof(uuid_t)); 158 - if (diff < 0) 163 + if (diff < 0) { 159 164 pp = &(*pp)->rb_left; 160 - else if (diff > 0) 165 + } else if (diff > 0) { 161 166 pp = &(*pp)->rb_right; 162 - else 163 - goto exists; 167 + } else { 168 + if (server->cell == cell) 169 + goto exists; 170 + 171 + /* We have the same UUID representing servers in 172 + * different cells. Append the new server to the list. 173 + */ 174 + for (;;) { 175 + next = rcu_dereference_protected( 176 + server->uuid_next, 177 + lockdep_is_held(&net->fs_lock.lock)); 178 + if (!next) 179 + break; 180 + server = next; 181 + } 182 + rcu_assign_pointer(server->uuid_next, candidate); 183 + candidate->uuid_prev = server; 184 + server = candidate; 185 + goto added_dup; 186 + } 164 187 } 165 188 166 189 server = candidate; ··· 186 173 rb_insert_color(&server->uuid_rb, &net->fs_servers); 187 174 hlist_add_head_rcu(&server->proc_link, &net->fs_proc); 188 175 176 + added_dup: 189 177 write_seqlock(&net->fs_addr_lock); 190 178 alist = rcu_dereference_protected(server->addresses, 191 179 lockdep_is_held(&net->fs_addr_lock.lock)); ··· 213 199 } 214 200 215 201 /* 216 - * allocate a new server record 202 + * Allocate a new server record and mark it active. 217 203 */ 218 - static struct afs_server *afs_alloc_server(struct afs_net *net, 204 + static struct afs_server *afs_alloc_server(struct afs_cell *cell, 219 205 const uuid_t *uuid, 220 206 struct afs_addr_list *alist) 221 207 { 222 208 struct afs_server *server; 209 + struct afs_net *net = cell->net; 223 210 224 211 _enter(""); 225 212 ··· 228 213 if (!server) 229 214 goto enomem; 230 215 231 - atomic_set(&server->usage, 1); 216 + atomic_set(&server->ref, 1); 217 + atomic_set(&server->active, 1); 232 218 server->debug_id = atomic_inc_return(&afs_server_debug_id); 233 219 RCU_INIT_POINTER(server->addresses, alist); 234 220 server->addr_version = alist->version; 235 221 server->uuid = *uuid; 236 - server->update_at = ktime_get_real_seconds() + afs_server_update_delay; 237 222 rwlock_init(&server->fs_lock); 238 - INIT_HLIST_HEAD(&server->cb_volumes); 239 - rwlock_init(&server->cb_break_lock); 240 223 init_waitqueue_head(&server->probe_wq); 224 + INIT_LIST_HEAD(&server->probe_link); 241 225 spin_lock_init(&server->probe_lock); 226 + server->cell = cell; 227 + server->rtt = UINT_MAX; 242 228 243 229 afs_inc_servers_outstanding(net); 244 - trace_afs_server(server, 1, afs_server_trace_alloc); 230 + trace_afs_server(server, 1, 1, afs_server_trace_alloc); 245 231 _leave(" = %p", server); 246 232 return server; 247 233 ··· 280 264 * Get or create a fileserver record. 281 265 */ 282 266 struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key, 283 - const uuid_t *uuid) 267 + const uuid_t *uuid, u32 addr_version) 284 268 { 285 269 struct afs_addr_list *alist; 286 270 struct afs_server *server, *candidate; ··· 288 272 _enter("%p,%pU", cell->net, uuid); 289 273 290 274 server = afs_find_server_by_uuid(cell->net, uuid); 291 - if (server) 275 + if (server) { 276 + if (server->addr_version != addr_version) 277 + set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags); 292 278 return server; 279 + } 293 280 294 281 alist = afs_vl_lookup_addrs(cell, key, uuid); 295 282 if (IS_ERR(alist)) 296 283 return ERR_CAST(alist); 297 284 298 - candidate = afs_alloc_server(cell->net, uuid, alist); 285 + candidate = afs_alloc_server(cell, uuid, alist); 299 286 if (!candidate) { 300 287 afs_put_addrlist(alist); 301 288 return ERR_PTR(-ENOMEM); 302 289 } 303 290 304 - server = afs_install_server(cell->net, candidate); 291 + server = afs_install_server(cell, candidate); 305 292 if (server != candidate) { 306 293 afs_put_addrlist(alist); 307 294 kfree(candidate); 295 + } else { 296 + /* Immediately dispatch an asynchronous probe to each interface 297 + * on the fileserver. This will make sure the repeat-probing 298 + * service is started. 299 + */ 300 + afs_fs_probe_fileserver(cell->net, server, key, true); 308 301 } 309 302 310 - _leave(" = %p{%d}", server, atomic_read(&server->usage)); 311 303 return server; 312 304 } 313 305 ··· 351 327 struct afs_server *afs_get_server(struct afs_server *server, 352 328 enum afs_server_trace reason) 353 329 { 354 - unsigned int u = atomic_inc_return(&server->usage); 330 + unsigned int u = atomic_inc_return(&server->ref); 355 331 356 - trace_afs_server(server, u, reason); 332 + trace_afs_server(server, u, atomic_read(&server->active), reason); 333 + return server; 334 + } 335 + 336 + /* 337 + * Try to get a reference on a server object. 338 + */ 339 + static struct afs_server *afs_maybe_use_server(struct afs_server *server, 340 + enum afs_server_trace reason) 341 + { 342 + unsigned int r = atomic_fetch_add_unless(&server->ref, 1, 0); 343 + unsigned int a; 344 + 345 + if (r == 0) 346 + return NULL; 347 + 348 + a = atomic_inc_return(&server->active); 349 + trace_afs_server(server, r, a, reason); 350 + return server; 351 + } 352 + 353 + /* 354 + * Get an active count on a server object. 355 + */ 356 + struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason) 357 + { 358 + unsigned int r = atomic_inc_return(&server->ref); 359 + unsigned int a = atomic_inc_return(&server->active); 360 + 361 + trace_afs_server(server, r, a, reason); 357 362 return server; 358 363 } 359 364 ··· 397 344 if (!server) 398 345 return; 399 346 400 - server->put_time = ktime_get_real_seconds(); 347 + usage = atomic_dec_return(&server->ref); 348 + trace_afs_server(server, usage, atomic_read(&server->active), reason); 349 + if (unlikely(usage == 0)) 350 + __afs_put_server(net, server); 351 + } 401 352 402 - usage = atomic_dec_return(&server->usage); 353 + /* 354 + * Drop an active count on a server object without updating the last-unused 355 + * time. 356 + */ 357 + void afs_unuse_server_notime(struct afs_net *net, struct afs_server *server, 358 + enum afs_server_trace reason) 359 + { 360 + if (server) { 361 + unsigned int active = atomic_dec_return(&server->active); 403 362 404 - trace_afs_server(server, usage, reason); 363 + if (active == 0) 364 + afs_set_server_timer(net, afs_server_gc_delay); 365 + afs_put_server(net, server, reason); 366 + } 367 + } 405 368 406 - if (likely(usage > 0)) 407 - return; 408 - 409 - afs_set_server_timer(net, afs_server_gc_delay); 369 + /* 370 + * Drop an active count on a server object. 371 + */ 372 + void afs_unuse_server(struct afs_net *net, struct afs_server *server, 373 + enum afs_server_trace reason) 374 + { 375 + if (server) { 376 + server->unuse_time = ktime_get_real_seconds(); 377 + afs_unuse_server_notime(net, server, reason); 378 + } 410 379 } 411 380 412 381 static void afs_server_rcu(struct rcu_head *rcu) 413 382 { 414 383 struct afs_server *server = container_of(rcu, struct afs_server, rcu); 415 384 416 - trace_afs_server(server, atomic_read(&server->usage), 417 - afs_server_trace_free); 385 + trace_afs_server(server, atomic_read(&server->ref), 386 + atomic_read(&server->active), afs_server_trace_free); 418 387 afs_put_addrlist(rcu_access_pointer(server->addresses)); 419 388 kfree(server); 420 389 } 421 390 422 - /* 423 - * destroy a dead server 424 - */ 425 - static void afs_destroy_server(struct afs_net *net, struct afs_server *server) 391 + static void __afs_put_server(struct afs_net *net, struct afs_server *server) 392 + { 393 + call_rcu(&server->rcu, afs_server_rcu); 394 + afs_dec_servers_outstanding(net); 395 + } 396 + 397 + static void afs_give_up_callbacks(struct afs_net *net, struct afs_server *server) 426 398 { 427 399 struct afs_addr_list *alist = rcu_access_pointer(server->addresses); 428 400 struct afs_addr_cursor ac = { ··· 456 378 .error = 0, 457 379 }; 458 380 459 - trace_afs_server(server, atomic_read(&server->usage), 460 - afs_server_trace_give_up_cb); 381 + afs_fs_give_up_all_callbacks(net, server, &ac, NULL); 382 + } 461 383 384 + /* 385 + * destroy a dead server 386 + */ 387 + static void afs_destroy_server(struct afs_net *net, struct afs_server *server) 388 + { 462 389 if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags)) 463 - afs_fs_give_up_all_callbacks(net, server, &ac, NULL); 390 + afs_give_up_callbacks(net, server); 464 391 465 - wait_var_event(&server->probe_outstanding, 466 - atomic_read(&server->probe_outstanding) == 0); 467 - 468 - trace_afs_server(server, atomic_read(&server->usage), 469 - afs_server_trace_destroy); 470 - call_rcu(&server->rcu, afs_server_rcu); 471 - afs_dec_servers_outstanding(net); 392 + afs_put_server(net, server, afs_server_trace_destroy); 472 393 } 473 394 474 395 /* ··· 475 398 */ 476 399 static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list) 477 400 { 478 - struct afs_server *server; 479 - bool deleted; 480 - int usage; 401 + struct afs_server *server, *next, *prev; 402 + int active; 481 403 482 404 while ((server = gc_list)) { 483 405 gc_list = server->gc_next; 484 406 485 407 write_seqlock(&net->fs_lock); 486 - usage = 1; 487 - deleted = atomic_try_cmpxchg(&server->usage, &usage, 0); 488 - trace_afs_server(server, usage, afs_server_trace_gc); 489 - if (deleted) { 490 - rb_erase(&server->uuid_rb, &net->fs_servers); 491 - hlist_del_rcu(&server->proc_link); 492 - } 493 - write_sequnlock(&net->fs_lock); 494 408 495 - if (deleted) { 496 - write_seqlock(&net->fs_addr_lock); 409 + active = atomic_read(&server->active); 410 + if (active == 0) { 411 + trace_afs_server(server, atomic_read(&server->ref), 412 + active, afs_server_trace_gc); 413 + next = rcu_dereference_protected( 414 + server->uuid_next, lockdep_is_held(&net->fs_lock.lock)); 415 + prev = server->uuid_prev; 416 + if (!prev) { 417 + /* The one at the front is in the tree */ 418 + if (!next) { 419 + rb_erase(&server->uuid_rb, &net->fs_servers); 420 + } else { 421 + rb_replace_node_rcu(&server->uuid_rb, 422 + &next->uuid_rb, 423 + &net->fs_servers); 424 + next->uuid_prev = NULL; 425 + } 426 + } else { 427 + /* This server is not at the front */ 428 + rcu_assign_pointer(prev->uuid_next, next); 429 + if (next) 430 + next->uuid_prev = prev; 431 + } 432 + 433 + list_del(&server->probe_link); 434 + hlist_del_rcu(&server->proc_link); 497 435 if (!hlist_unhashed(&server->addr4_link)) 498 436 hlist_del_rcu(&server->addr4_link); 499 437 if (!hlist_unhashed(&server->addr6_link)) 500 438 hlist_del_rcu(&server->addr6_link); 501 - write_sequnlock(&net->fs_addr_lock); 502 - afs_destroy_server(net, server); 503 439 } 440 + write_sequnlock(&net->fs_lock); 441 + 442 + if (active == 0) 443 + afs_destroy_server(net, server); 504 444 } 505 445 } 506 446 ··· 546 452 for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) { 547 453 struct afs_server *server = 548 454 rb_entry(cursor, struct afs_server, uuid_rb); 549 - int usage = atomic_read(&server->usage); 455 + int active = atomic_read(&server->active); 550 456 551 - _debug("manage %pU %u", &server->uuid, usage); 457 + _debug("manage %pU %u", &server->uuid, active); 552 458 553 - ASSERTCMP(usage, >=, 1); 554 - ASSERTIFCMP(purging, usage, ==, 1); 459 + ASSERTIFCMP(purging, active, ==, 0); 555 460 556 - if (usage == 1) { 557 - time64_t expire_at = server->put_time; 461 + if (active == 0) { 462 + time64_t expire_at = server->unuse_time; 558 463 559 464 if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) && 560 465 !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags)) ··· 618 525 /* 619 526 * Get an update for a server's address list. 620 527 */ 621 - static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct afs_server *server) 528 + static noinline bool afs_update_server_record(struct afs_operation *op, 529 + struct afs_server *server) 622 530 { 623 531 struct afs_addr_list *alist, *discard; 624 532 625 533 _enter(""); 626 534 627 - trace_afs_server(server, atomic_read(&server->usage), afs_server_trace_update); 535 + trace_afs_server(server, atomic_read(&server->ref), atomic_read(&server->active), 536 + afs_server_trace_update); 628 537 629 - alist = afs_vl_lookup_addrs(fc->vnode->volume->cell, fc->key, 630 - &server->uuid); 538 + alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid); 631 539 if (IS_ERR(alist)) { 632 540 if ((PTR_ERR(alist) == -ERESTARTSYS || 633 541 PTR_ERR(alist) == -EINTR) && 634 - !(fc->flags & AFS_FS_CURSOR_INTR) && 542 + (op->flags & AFS_OPERATION_UNINTR) && 635 543 server->addresses) { 636 544 _leave(" = t [intr]"); 637 545 return true; 638 546 } 639 - fc->error = PTR_ERR(alist); 640 - _leave(" = f [%d]", fc->error); 547 + op->error = PTR_ERR(alist); 548 + _leave(" = f [%d]", op->error); 641 549 return false; 642 550 } 643 551 ··· 652 558 write_unlock(&server->fs_lock); 653 559 } 654 560 655 - server->update_at = ktime_get_real_seconds() + afs_server_update_delay; 656 561 afs_put_addrlist(discard); 657 562 _leave(" = t"); 658 563 return true; ··· 660 567 /* 661 568 * See if a server's address list needs updating. 662 569 */ 663 - bool afs_check_server_record(struct afs_fs_cursor *fc, struct afs_server *server) 570 + bool afs_check_server_record(struct afs_operation *op, struct afs_server *server) 664 571 { 665 - time64_t now = ktime_get_real_seconds(); 666 - long diff; 667 572 bool success; 668 573 int ret, retries = 0; 669 574 ··· 670 579 ASSERT(server); 671 580 672 581 retry: 673 - diff = READ_ONCE(server->update_at) - now; 674 - if (diff > 0) { 675 - _leave(" = t [not now %ld]", diff); 676 - return true; 677 - } 582 + if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags)) 583 + goto wait; 584 + if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags)) 585 + goto update; 586 + _leave(" = t [good]"); 587 + return true; 678 588 589 + update: 679 590 if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) { 680 - success = afs_update_server_record(fc, server); 591 + clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags); 592 + success = afs_update_server_record(op, server); 681 593 clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags); 682 594 wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING); 683 595 _leave(" = %d", success); 684 596 return success; 685 597 } 686 598 599 + wait: 687 600 ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING, 688 - (fc->flags & AFS_FS_CURSOR_INTR) ? 689 - TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 601 + (op->flags & AFS_OPERATION_UNINTR) ? 602 + TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE); 690 603 if (ret == -ERESTARTSYS) { 691 - fc->error = ret; 604 + op->error = ret; 692 605 _leave(" = f [intr]"); 693 606 return false; 694 607 }
+8 -32
fs/afs/server_list.c
··· 14 14 int i; 15 15 16 16 if (slist && refcount_dec_and_test(&slist->usage)) { 17 - for (i = 0; i < slist->nr_servers; i++) { 18 - afs_put_cb_interest(net, slist->servers[i].cb_interest); 19 - afs_put_server(net, slist->servers[i].server, 20 - afs_server_trace_put_slist); 21 - } 17 + for (i = 0; i < slist->nr_servers; i++) 18 + afs_unuse_server(net, slist->servers[i].server, 19 + afs_server_trace_put_slist); 22 20 kfree(slist); 23 21 } 24 22 } ··· 44 46 refcount_set(&slist->usage, 1); 45 47 rwlock_init(&slist->lock); 46 48 49 + for (i = 0; i < AFS_MAXTYPES; i++) 50 + slist->vids[i] = vldb->vid[i]; 51 + 47 52 /* Make sure a records exists for each server in the list. */ 48 53 for (i = 0; i < vldb->nr_servers; i++) { 49 54 if (!(vldb->fs_mask[i] & type_mask)) 50 55 continue; 51 56 52 - server = afs_lookup_server(cell, key, &vldb->fs_server[i]); 57 + server = afs_lookup_server(cell, key, &vldb->fs_server[i], 58 + vldb->addr_version[i]); 53 59 if (IS_ERR(server)) { 54 60 ret = PTR_ERR(server); 55 61 if (ret == -ENOENT || ··· 123 121 new->preferred = j; 124 122 break; 125 123 } 126 - } 127 - 128 - /* Keep the old callback interest records where possible so that we 129 - * maintain callback interception. 130 - */ 131 - i = 0; 132 - j = 0; 133 - while (i < old->nr_servers && j < new->nr_servers) { 134 - if (new->servers[j].server == old->servers[i].server) { 135 - struct afs_cb_interest *cbi = old->servers[i].cb_interest; 136 - if (cbi) { 137 - new->servers[j].cb_interest = cbi; 138 - refcount_inc(&cbi->usage); 139 - } 140 - i++; 141 - j++; 142 - continue; 143 - } 144 - 145 - if (new->servers[j].server < old->servers[i].server) { 146 - j++; 147 - continue; 148 - } 149 - 150 - i++; 151 - continue; 152 124 } 153 125 154 126 return true;
+59 -48
fs/afs/super.c
··· 352 352 { 353 353 struct afs_fs_context *ctx = fc->fs_private; 354 354 struct afs_volume *volume; 355 + struct afs_cell *cell; 355 356 struct key *key; 357 + int ret; 356 358 357 359 if (!ctx->dyn_root) { 358 360 if (ctx->no_cell) { ··· 367 365 return -EDESTADDRREQ; 368 366 } 369 367 368 + reget_key: 370 369 /* We try to do the mount securely. */ 371 370 key = afs_request_key(ctx->cell); 372 371 if (IS_ERR(key)) ··· 376 373 ctx->key = key; 377 374 378 375 if (ctx->volume) { 379 - afs_put_volume(ctx->cell, ctx->volume); 376 + afs_put_volume(ctx->net, ctx->volume, 377 + afs_volume_trace_put_validate_fc); 380 378 ctx->volume = NULL; 379 + } 380 + 381 + if (test_bit(AFS_CELL_FL_CHECK_ALIAS, &ctx->cell->flags)) { 382 + ret = afs_cell_detect_alias(ctx->cell, key); 383 + if (ret < 0) 384 + return ret; 385 + if (ret == 1) { 386 + _debug("switch to alias"); 387 + key_put(ctx->key); 388 + ctx->key = NULL; 389 + cell = afs_get_cell(ctx->cell->alias_of); 390 + afs_put_cell(ctx->net, ctx->cell); 391 + ctx->cell = cell; 392 + goto reget_key; 393 + } 381 394 } 382 395 383 396 volume = afs_create_volume(ctx); ··· 440 421 static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) 441 422 { 442 423 struct afs_super_info *as = AFS_FS_S(sb); 443 - struct afs_iget_data iget_data; 444 424 struct inode *inode = NULL; 445 425 int ret; 446 426 ··· 464 446 } else { 465 447 sprintf(sb->s_id, "%llu", as->volume->vid); 466 448 afs_activate_volume(as->volume); 467 - iget_data.fid.vid = as->volume->vid; 468 - iget_data.fid.vnode = 1; 469 - iget_data.fid.vnode_hi = 0; 470 - iget_data.fid.unique = 1; 471 - iget_data.cb_v_break = as->volume->cb_v_break; 472 - iget_data.cb_s_break = 0; 473 - inode = afs_iget(sb, ctx->key, &iget_data, NULL, NULL, NULL); 449 + inode = afs_root_iget(sb, ctx->key); 474 450 } 475 451 476 452 if (IS_ERR(inode)) ··· 485 473 goto error; 486 474 } else { 487 475 sb->s_d_op = &afs_fs_dentry_operations; 476 + rcu_assign_pointer(as->volume->sb, sb); 488 477 } 489 478 490 479 _leave(" = 0"); ··· 509 496 as->dyn_root = true; 510 497 } else { 511 498 as->cell = afs_get_cell(ctx->cell); 512 - as->volume = __afs_get_volume(ctx->volume); 499 + as->volume = afs_get_volume(ctx->volume, 500 + afs_volume_trace_get_alloc_sbi); 513 501 } 514 502 } 515 503 return as; ··· 519 505 static void afs_destroy_sbi(struct afs_super_info *as) 520 506 { 521 507 if (as) { 522 - afs_put_volume(as->cell, as->volume); 523 - afs_put_cell(afs_net(as->net_ns), as->cell); 508 + struct afs_net *net = afs_net(as->net_ns); 509 + afs_put_volume(net, as->volume, afs_volume_trace_put_destroy_sbi); 510 + afs_put_cell(net, as->cell); 524 511 put_net(as->net_ns); 525 512 kfree(as); 526 513 } ··· 530 515 static void afs_kill_super(struct super_block *sb) 531 516 { 532 517 struct afs_super_info *as = AFS_FS_S(sb); 533 - struct afs_net *net = afs_net(as->net_ns); 534 518 535 519 if (as->dyn_root) 536 520 afs_dynroot_depopulate(sb); ··· 538 524 * deactivating the superblock. 539 525 */ 540 526 if (as->volume) 541 - afs_clear_callback_interests(net, as->volume->servers); 527 + rcu_assign_pointer(as->volume->sb, NULL); 542 528 kill_anon_super(sb); 543 529 if (as->volume) 544 530 afs_deactivate_volume(as->volume); ··· 606 592 struct afs_fs_context *ctx = fc->fs_private; 607 593 608 594 afs_destroy_sbi(fc->s_fs_info); 609 - afs_put_volume(ctx->cell, ctx->volume); 595 + afs_put_volume(ctx->net, ctx->volume, afs_volume_trace_put_free_fc); 610 596 afs_put_cell(ctx->net, ctx->cell); 611 597 key_put(ctx->key); 612 598 kfree(ctx); ··· 688 674 vnode->volume = NULL; 689 675 vnode->lock_key = NULL; 690 676 vnode->permit_cache = NULL; 691 - RCU_INIT_POINTER(vnode->cb_interest, NULL); 692 677 #ifdef CONFIG_AFS_FSCACHE 693 678 vnode->cache = NULL; 694 679 #endif ··· 717 704 718 705 _debug("DESTROY INODE %p", inode); 719 706 720 - ASSERTCMP(rcu_access_pointer(vnode->cb_interest), ==, NULL); 721 - 722 707 atomic_dec(&afs_count_active_inodes); 723 708 } 709 + 710 + static void afs_get_volume_status_success(struct afs_operation *op) 711 + { 712 + struct afs_volume_status *vs = &op->volstatus.vs; 713 + struct kstatfs *buf = op->volstatus.buf; 714 + 715 + if (vs->max_quota == 0) 716 + buf->f_blocks = vs->part_max_blocks; 717 + else 718 + buf->f_blocks = vs->max_quota; 719 + 720 + if (buf->f_blocks > vs->blocks_in_use) 721 + buf->f_bavail = buf->f_bfree = 722 + buf->f_blocks - vs->blocks_in_use; 723 + } 724 + 725 + static const struct afs_operation_ops afs_get_volume_status_operation = { 726 + .issue_afs_rpc = afs_fs_get_volume_status, 727 + .issue_yfs_rpc = yfs_fs_get_volume_status, 728 + .success = afs_get_volume_status_success, 729 + }; 724 730 725 731 /* 726 732 * return information about an AFS volume ··· 747 715 static int afs_statfs(struct dentry *dentry, struct kstatfs *buf) 748 716 { 749 717 struct afs_super_info *as = AFS_FS_S(dentry->d_sb); 750 - struct afs_fs_cursor fc; 751 - struct afs_volume_status vs; 718 + struct afs_operation *op; 752 719 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); 753 - struct key *key; 754 - int ret; 755 720 756 721 buf->f_type = dentry->d_sb->s_magic; 757 722 buf->f_bsize = AFS_BLOCK_SIZE; ··· 761 732 return 0; 762 733 } 763 734 764 - key = afs_request_key(vnode->volume->cell); 765 - if (IS_ERR(key)) 766 - return PTR_ERR(key); 735 + op = afs_alloc_operation(NULL, as->volume); 736 + if (IS_ERR(op)) 737 + return PTR_ERR(op); 767 738 768 - ret = -ERESTARTSYS; 769 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 770 - fc.flags |= AFS_FS_CURSOR_NO_VSLEEP; 771 - while (afs_select_fileserver(&fc)) { 772 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 773 - afs_fs_get_volume_status(&fc, &vs); 774 - } 775 - 776 - afs_check_for_remote_deletion(&fc, fc.vnode); 777 - ret = afs_end_vnode_operation(&fc); 778 - } 779 - 780 - key_put(key); 781 - 782 - if (ret == 0) { 783 - if (vs.max_quota == 0) 784 - buf->f_blocks = vs.part_max_blocks; 785 - else 786 - buf->f_blocks = vs.max_quota; 787 - buf->f_bavail = buf->f_bfree = buf->f_blocks - vs.blocks_in_use; 788 - } 789 - 790 - return ret; 739 + afs_op_set_vnode(op, 0, vnode); 740 + op->nr_files = 1; 741 + op->volstatus.buf = buf; 742 + op->ops = &afs_get_volume_status_operation; 743 + return afs_do_sync_operation(op); 791 744 }
+382
fs/afs/vl_alias.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* AFS cell alias detection 3 + * 4 + * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #include <linux/slab.h> 9 + #include <linux/sched.h> 10 + #include <linux/namei.h> 11 + #include <keys/rxrpc-type.h> 12 + #include "internal.h" 13 + 14 + /* 15 + * Sample a volume. 16 + */ 17 + static struct afs_volume *afs_sample_volume(struct afs_cell *cell, struct key *key, 18 + const char *name, unsigned int namelen) 19 + { 20 + struct afs_volume *volume; 21 + struct afs_fs_context fc = { 22 + .type = 0, /* Explicitly leave it to the VLDB */ 23 + .volnamesz = namelen, 24 + .volname = name, 25 + .net = cell->net, 26 + .cell = cell, 27 + .key = key, /* This might need to be something */ 28 + }; 29 + 30 + volume = afs_create_volume(&fc); 31 + _leave(" = %px", volume); 32 + return volume; 33 + } 34 + 35 + /* 36 + * Compare two addresses. 37 + */ 38 + static int afs_compare_addrs(const struct sockaddr_rxrpc *srx_a, 39 + const struct sockaddr_rxrpc *srx_b) 40 + { 41 + short port_a, port_b; 42 + int addr_a, addr_b, diff; 43 + 44 + diff = (short)srx_a->transport_type - (short)srx_b->transport_type; 45 + if (diff) 46 + goto out; 47 + 48 + switch (srx_a->transport_type) { 49 + case AF_INET: { 50 + const struct sockaddr_in *a = &srx_a->transport.sin; 51 + const struct sockaddr_in *b = &srx_b->transport.sin; 52 + addr_a = ntohl(a->sin_addr.s_addr); 53 + addr_b = ntohl(b->sin_addr.s_addr); 54 + diff = addr_a - addr_b; 55 + if (diff == 0) { 56 + port_a = ntohs(a->sin_port); 57 + port_b = ntohs(b->sin_port); 58 + diff = port_a - port_b; 59 + } 60 + break; 61 + } 62 + 63 + case AF_INET6: { 64 + const struct sockaddr_in6 *a = &srx_a->transport.sin6; 65 + const struct sockaddr_in6 *b = &srx_b->transport.sin6; 66 + diff = memcmp(&a->sin6_addr, &b->sin6_addr, 16); 67 + if (diff == 0) { 68 + port_a = ntohs(a->sin6_port); 69 + port_b = ntohs(b->sin6_port); 70 + diff = port_a - port_b; 71 + } 72 + break; 73 + } 74 + 75 + default: 76 + BUG(); 77 + } 78 + 79 + out: 80 + return diff; 81 + } 82 + 83 + /* 84 + * Compare the address lists of a pair of fileservers. 85 + */ 86 + static int afs_compare_fs_alists(const struct afs_server *server_a, 87 + const struct afs_server *server_b) 88 + { 89 + const struct afs_addr_list *la, *lb; 90 + int a = 0, b = 0, addr_matches = 0; 91 + 92 + la = rcu_dereference(server_a->addresses); 93 + lb = rcu_dereference(server_b->addresses); 94 + 95 + while (a < la->nr_addrs && b < lb->nr_addrs) { 96 + const struct sockaddr_rxrpc *srx_a = &la->addrs[a]; 97 + const struct sockaddr_rxrpc *srx_b = &lb->addrs[b]; 98 + int diff = afs_compare_addrs(srx_a, srx_b); 99 + 100 + if (diff < 0) { 101 + a++; 102 + } else if (diff > 0) { 103 + b++; 104 + } else { 105 + addr_matches++; 106 + a++; 107 + b++; 108 + } 109 + } 110 + 111 + return addr_matches; 112 + } 113 + 114 + /* 115 + * Compare the fileserver lists of two volumes. The server lists are sorted in 116 + * order of ascending UUID. 117 + */ 118 + static int afs_compare_volume_slists(const struct afs_volume *vol_a, 119 + const struct afs_volume *vol_b) 120 + { 121 + const struct afs_server_list *la, *lb; 122 + int i, a = 0, b = 0, uuid_matches = 0, addr_matches = 0; 123 + 124 + la = rcu_dereference(vol_a->servers); 125 + lb = rcu_dereference(vol_b->servers); 126 + 127 + for (i = 0; i < AFS_MAXTYPES; i++) 128 + if (la->vids[i] != lb->vids[i]) 129 + return 0; 130 + 131 + while (a < la->nr_servers && b < lb->nr_servers) { 132 + const struct afs_server *server_a = la->servers[a].server; 133 + const struct afs_server *server_b = lb->servers[b].server; 134 + int diff = memcmp(&server_a->uuid, &server_b->uuid, sizeof(uuid_t)); 135 + 136 + if (diff < 0) { 137 + a++; 138 + } else if (diff > 0) { 139 + b++; 140 + } else { 141 + uuid_matches++; 142 + addr_matches += afs_compare_fs_alists(server_a, server_b); 143 + a++; 144 + b++; 145 + } 146 + } 147 + 148 + _leave(" = %d [um %d]", addr_matches, uuid_matches); 149 + return addr_matches; 150 + } 151 + 152 + /* 153 + * Compare root.cell volumes. 154 + */ 155 + static int afs_compare_cell_roots(struct afs_cell *cell) 156 + { 157 + struct afs_cell *p; 158 + 159 + _enter(""); 160 + 161 + rcu_read_lock(); 162 + 163 + hlist_for_each_entry_rcu(p, &cell->net->proc_cells, proc_link) { 164 + if (p == cell || p->alias_of) 165 + continue; 166 + if (!p->root_volume) 167 + continue; /* Ignore cells that don't have a root.cell volume. */ 168 + 169 + if (afs_compare_volume_slists(cell->root_volume, p->root_volume) != 0) 170 + goto is_alias; 171 + } 172 + 173 + rcu_read_unlock(); 174 + _leave(" = 0"); 175 + return 0; 176 + 177 + is_alias: 178 + rcu_read_unlock(); 179 + cell->alias_of = afs_get_cell(p); 180 + return 1; 181 + } 182 + 183 + /* 184 + * Query the new cell for a volume from a cell we're already using. 185 + */ 186 + static int afs_query_for_alias_one(struct afs_cell *cell, struct key *key, 187 + struct afs_cell *p) 188 + { 189 + struct afs_volume *volume, *pvol = NULL; 190 + int ret; 191 + 192 + /* Arbitrarily pick a volume from the list. */ 193 + read_seqlock_excl(&p->volume_lock); 194 + if (!RB_EMPTY_ROOT(&p->volumes)) 195 + pvol = afs_get_volume(rb_entry(p->volumes.rb_node, 196 + struct afs_volume, cell_node), 197 + afs_volume_trace_get_query_alias); 198 + read_sequnlock_excl(&p->volume_lock); 199 + if (!pvol) 200 + return 0; 201 + 202 + _enter("%s:%s", cell->name, pvol->name); 203 + 204 + /* And see if it's in the new cell. */ 205 + volume = afs_sample_volume(cell, key, pvol->name, pvol->name_len); 206 + if (IS_ERR(volume)) { 207 + afs_put_volume(cell->net, pvol, afs_volume_trace_put_query_alias); 208 + if (PTR_ERR(volume) != -ENOMEDIUM) 209 + return PTR_ERR(volume); 210 + /* That volume is not in the new cell, so not an alias */ 211 + return 0; 212 + } 213 + 214 + /* The new cell has a like-named volume also - compare volume ID, 215 + * server and address lists. 216 + */ 217 + ret = 0; 218 + if (pvol->vid == volume->vid) { 219 + rcu_read_lock(); 220 + if (afs_compare_volume_slists(volume, pvol)) 221 + ret = 1; 222 + rcu_read_unlock(); 223 + } 224 + 225 + afs_put_volume(cell->net, volume, afs_volume_trace_put_query_alias); 226 + afs_put_volume(cell->net, pvol, afs_volume_trace_put_query_alias); 227 + return ret; 228 + } 229 + 230 + /* 231 + * Query the new cell for volumes we know exist in cells we're already using. 232 + */ 233 + static int afs_query_for_alias(struct afs_cell *cell, struct key *key) 234 + { 235 + struct afs_cell *p; 236 + 237 + _enter("%s", cell->name); 238 + 239 + if (mutex_lock_interruptible(&cell->net->proc_cells_lock) < 0) 240 + return -ERESTARTSYS; 241 + 242 + hlist_for_each_entry(p, &cell->net->proc_cells, proc_link) { 243 + if (p == cell || p->alias_of) 244 + continue; 245 + if (RB_EMPTY_ROOT(&p->volumes)) 246 + continue; 247 + if (p->root_volume) 248 + continue; /* Ignore cells that have a root.cell volume. */ 249 + afs_get_cell(p); 250 + mutex_unlock(&cell->net->proc_cells_lock); 251 + 252 + if (afs_query_for_alias_one(cell, key, p) != 0) 253 + goto is_alias; 254 + 255 + if (mutex_lock_interruptible(&cell->net->proc_cells_lock) < 0) { 256 + afs_put_cell(cell->net, p); 257 + return -ERESTARTSYS; 258 + } 259 + 260 + afs_put_cell(cell->net, p); 261 + } 262 + 263 + mutex_unlock(&cell->net->proc_cells_lock); 264 + _leave(" = 0"); 265 + return 0; 266 + 267 + is_alias: 268 + cell->alias_of = p; /* Transfer our ref */ 269 + return 1; 270 + } 271 + 272 + /* 273 + * Look up a VLDB record for a volume. 274 + */ 275 + static char *afs_vl_get_cell_name(struct afs_cell *cell, struct key *key) 276 + { 277 + struct afs_vl_cursor vc; 278 + char *cell_name = ERR_PTR(-EDESTADDRREQ); 279 + bool skipped = false, not_skipped = false; 280 + int ret; 281 + 282 + if (!afs_begin_vlserver_operation(&vc, cell, key)) 283 + return ERR_PTR(-ERESTARTSYS); 284 + 285 + while (afs_select_vlserver(&vc)) { 286 + if (!test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags)) { 287 + vc.ac.error = -EOPNOTSUPP; 288 + skipped = true; 289 + continue; 290 + } 291 + not_skipped = true; 292 + cell_name = afs_yfsvl_get_cell_name(&vc); 293 + } 294 + 295 + ret = afs_end_vlserver_operation(&vc); 296 + if (skipped && !not_skipped) 297 + ret = -EOPNOTSUPP; 298 + return ret < 0 ? ERR_PTR(ret) : cell_name; 299 + } 300 + 301 + static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key) 302 + { 303 + struct afs_cell *master; 304 + char *cell_name; 305 + 306 + cell_name = afs_vl_get_cell_name(cell, key); 307 + if (IS_ERR(cell_name)) 308 + return PTR_ERR(cell_name); 309 + 310 + if (strcmp(cell_name, cell->name) == 0) { 311 + kfree(cell_name); 312 + return 0; 313 + } 314 + 315 + master = afs_lookup_cell(cell->net, cell_name, strlen(cell_name), 316 + NULL, false); 317 + kfree(cell_name); 318 + if (IS_ERR(master)) 319 + return PTR_ERR(master); 320 + 321 + cell->alias_of = master; /* Transfer our ref */ 322 + return 1; 323 + } 324 + 325 + static int afs_do_cell_detect_alias(struct afs_cell *cell, struct key *key) 326 + { 327 + struct afs_volume *root_volume; 328 + int ret; 329 + 330 + _enter("%s", cell->name); 331 + 332 + ret = yfs_check_canonical_cell_name(cell, key); 333 + if (ret != -EOPNOTSUPP) 334 + return ret; 335 + 336 + /* Try and get the root.cell volume for comparison with other cells */ 337 + root_volume = afs_sample_volume(cell, key, "root.cell", 9); 338 + if (!IS_ERR(root_volume)) { 339 + cell->root_volume = root_volume; 340 + return afs_compare_cell_roots(cell); 341 + } 342 + 343 + if (PTR_ERR(root_volume) != -ENOMEDIUM) 344 + return PTR_ERR(root_volume); 345 + 346 + /* Okay, this cell doesn't have an root.cell volume. We need to 347 + * locate some other random volume and use that to check. 348 + */ 349 + return afs_query_for_alias(cell, key); 350 + } 351 + 352 + /* 353 + * Check to see if a new cell is an alias of a cell we already have. At this 354 + * point we have the cell's volume server list. 355 + * 356 + * Returns 0 if we didn't detect an alias, 1 if we found an alias and an error 357 + * if we had problems gathering the data required. In the case the we did 358 + * detect an alias, cell->alias_of is set to point to the assumed master. 359 + */ 360 + int afs_cell_detect_alias(struct afs_cell *cell, struct key *key) 361 + { 362 + struct afs_net *net = cell->net; 363 + int ret; 364 + 365 + if (mutex_lock_interruptible(&net->cells_alias_lock) < 0) 366 + return -ERESTARTSYS; 367 + 368 + if (test_bit(AFS_CELL_FL_CHECK_ALIAS, &cell->flags)) { 369 + ret = afs_do_cell_detect_alias(cell, key); 370 + if (ret >= 0) 371 + clear_bit_unlock(AFS_CELL_FL_CHECK_ALIAS, &cell->flags); 372 + } else { 373 + ret = cell->alias_of ? 1 : 0; 374 + } 375 + 376 + mutex_unlock(&net->cells_alias_lock); 377 + 378 + if (ret == 1) 379 + pr_notice("kAFS: Cell %s is an alias of %s\n", 380 + cell->name, cell->alias_of->name); 381 + return ret; 382 + }
+4
fs/afs/vl_rotate.c
··· 151 151 vc->error = error; 152 152 vc->flags |= AFS_VL_CURSOR_RETRY; 153 153 goto next_server; 154 + 155 + case -EOPNOTSUPP: 156 + _debug("notsupp"); 157 + goto next_server; 154 158 } 155 159 156 160 restart_from_beginning:
+126 -20
fs/afs/vlclient.c
··· 82 82 for (j = 0; j < 6; j++) 83 83 uuid->node[j] = (u8)ntohl(xdr->node[j]); 84 84 85 + entry->addr_version[n] = ntohl(uvldb->serverUnique[i]); 85 86 entry->nr_servers++; 86 87 } 87 88 ··· 448 447 call->count2 = ntohl(*bp); /* Type or next count */ 449 448 450 449 if (call->count > YFS_MAXENDPOINTS) 451 - return afs_protocol_error(call, -EBADMSG, 452 - afs_eproto_yvl_fsendpt_num); 450 + return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num); 453 451 454 452 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT); 455 453 if (!alist) ··· 468 468 size = sizeof(__be32) * (1 + 4 + 1); 469 469 break; 470 470 default: 471 - return afs_protocol_error(call, -EBADMSG, 472 - afs_eproto_yvl_fsendpt_type); 471 + return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type); 473 472 } 474 473 475 474 size += sizeof(__be32); ··· 486 487 switch (call->count2) { 487 488 case YFS_ENDPOINT_IPV4: 488 489 if (ntohl(bp[0]) != sizeof(__be32) * 2) 489 - return afs_protocol_error(call, -EBADMSG, 490 - afs_eproto_yvl_fsendpt4_len); 490 + return afs_protocol_error( 491 + call, afs_eproto_yvl_fsendpt4_len); 491 492 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2])); 492 493 bp += 3; 493 494 break; 494 495 case YFS_ENDPOINT_IPV6: 495 496 if (ntohl(bp[0]) != sizeof(__be32) * 5) 496 - return afs_protocol_error(call, -EBADMSG, 497 - afs_eproto_yvl_fsendpt6_len); 497 + return afs_protocol_error( 498 + call, afs_eproto_yvl_fsendpt6_len); 498 499 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5])); 499 500 bp += 6; 500 501 break; 501 502 default: 502 - return afs_protocol_error(call, -EBADMSG, 503 - afs_eproto_yvl_fsendpt_type); 503 + return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type); 504 504 } 505 505 506 506 /* Got either the type of the next entry or the count of ··· 517 519 if (!call->count) 518 520 goto end; 519 521 if (call->count > YFS_MAXENDPOINTS) 520 - return afs_protocol_error(call, -EBADMSG, 521 - afs_eproto_yvl_vlendpt_type); 522 + return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 522 523 523 524 afs_extract_to_buf(call, 1 * sizeof(__be32)); 524 525 call->unmarshall = 3; ··· 544 547 size = sizeof(__be32) * (1 + 4 + 1); 545 548 break; 546 549 default: 547 - return afs_protocol_error(call, -EBADMSG, 548 - afs_eproto_yvl_vlendpt_type); 550 + return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 549 551 } 550 552 551 553 if (call->count > 1) ··· 562 566 switch (call->count2) { 563 567 case YFS_ENDPOINT_IPV4: 564 568 if (ntohl(bp[0]) != sizeof(__be32) * 2) 565 - return afs_protocol_error(call, -EBADMSG, 566 - afs_eproto_yvl_vlendpt4_len); 569 + return afs_protocol_error( 570 + call, afs_eproto_yvl_vlendpt4_len); 567 571 bp += 3; 568 572 break; 569 573 case YFS_ENDPOINT_IPV6: 570 574 if (ntohl(bp[0]) != sizeof(__be32) * 5) 571 - return afs_protocol_error(call, -EBADMSG, 572 - afs_eproto_yvl_vlendpt6_len); 575 + return afs_protocol_error( 576 + call, afs_eproto_yvl_vlendpt6_len); 573 577 bp += 6; 574 578 break; 575 579 default: 576 - return afs_protocol_error(call, -EBADMSG, 577 - afs_eproto_yvl_vlendpt_type); 580 + return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type); 578 581 } 579 582 580 583 /* Got either the type of the next entry or the count of ··· 644 649 trace_afs_make_vl_call(call); 645 650 afs_make_call(&vc->ac, call, GFP_KERNEL); 646 651 return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac); 652 + } 653 + 654 + /* 655 + * Deliver reply data to a YFSVL.GetCellName operation. 656 + */ 657 + static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call) 658 + { 659 + char *cell_name; 660 + u32 namesz, paddedsz; 661 + int ret; 662 + 663 + _enter("{%u,%zu/%u}", 664 + call->unmarshall, iov_iter_count(call->iter), call->count); 665 + 666 + switch (call->unmarshall) { 667 + case 0: 668 + afs_extract_to_tmp(call); 669 + call->unmarshall++; 670 + 671 + /* Fall through - and extract the cell name length */ 672 + case 1: 673 + ret = afs_extract_data(call, true); 674 + if (ret < 0) 675 + return ret; 676 + 677 + namesz = ntohl(call->tmp); 678 + if (namesz > AFS_MAXCELLNAME) 679 + return afs_protocol_error(call, afs_eproto_cellname_len); 680 + paddedsz = (namesz + 3) & ~3; 681 + call->count = namesz; 682 + call->count2 = paddedsz - namesz; 683 + 684 + cell_name = kmalloc(namesz + 1, GFP_KERNEL); 685 + if (!cell_name) 686 + return -ENOMEM; 687 + cell_name[namesz] = 0; 688 + call->ret_str = cell_name; 689 + 690 + afs_extract_begin(call, cell_name, namesz); 691 + call->unmarshall++; 692 + 693 + /* Fall through - and extract cell name */ 694 + case 2: 695 + ret = afs_extract_data(call, true); 696 + if (ret < 0) 697 + return ret; 698 + 699 + afs_extract_discard(call, call->count2); 700 + call->unmarshall++; 701 + 702 + /* Fall through - and extract padding */ 703 + case 3: 704 + ret = afs_extract_data(call, false); 705 + if (ret < 0) 706 + return ret; 707 + 708 + call->unmarshall++; 709 + break; 710 + } 711 + 712 + _leave(" = 0 [done]"); 713 + return 0; 714 + } 715 + 716 + static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call) 717 + { 718 + kfree(call->ret_str); 719 + afs_flat_call_destructor(call); 720 + } 721 + 722 + /* 723 + * VL.GetCapabilities operation type 724 + */ 725 + static const struct afs_call_type afs_YFSVLGetCellName = { 726 + .name = "YFSVL.GetCellName", 727 + .op = afs_YFSVL_GetCellName, 728 + .deliver = afs_deliver_yfsvl_get_cell_name, 729 + .destructor = afs_destroy_yfsvl_get_cell_name, 730 + }; 731 + 732 + /* 733 + * Probe a volume server for the capabilities that it supports. This can 734 + * return up to 196 words. 735 + * 736 + * We use this to probe for service upgrade to determine what the server at the 737 + * other end supports. 738 + */ 739 + char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc) 740 + { 741 + struct afs_call *call; 742 + struct afs_net *net = vc->cell->net; 743 + __be32 *bp; 744 + 745 + _enter(""); 746 + 747 + call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0); 748 + if (!call) 749 + return ERR_PTR(-ENOMEM); 750 + 751 + call->key = vc->key; 752 + call->ret_str = NULL; 753 + call->max_lifespan = AFS_VL_MAX_LIFESPAN; 754 + 755 + /* marshall the parameters */ 756 + bp = call->request; 757 + *bp++ = htonl(YVLGETCELLNAME); 758 + 759 + /* Can't take a ref on server */ 760 + trace_afs_make_vl_call(call); 761 + afs_make_call(&vc->ac, call, GFP_KERNEL); 762 + return (char *)afs_wait_for_call_to_complete(call, &vc->ac); 647 763 }
+118 -34
fs/afs/volume.c
··· 13 13 unsigned __read_mostly afs_volume_record_life = 60 * 60; 14 14 15 15 /* 16 + * Insert a volume into a cell. If there's an existing volume record, that is 17 + * returned instead with a ref held. 18 + */ 19 + static struct afs_volume *afs_insert_volume_into_cell(struct afs_cell *cell, 20 + struct afs_volume *volume) 21 + { 22 + struct afs_volume *p; 23 + struct rb_node *parent = NULL, **pp; 24 + 25 + write_seqlock(&cell->volume_lock); 26 + 27 + pp = &cell->volumes.rb_node; 28 + while (*pp) { 29 + parent = *pp; 30 + p = rb_entry(parent, struct afs_volume, cell_node); 31 + if (p->vid < volume->vid) { 32 + pp = &(*pp)->rb_left; 33 + } else if (p->vid > volume->vid) { 34 + pp = &(*pp)->rb_right; 35 + } else { 36 + volume = afs_get_volume(p, afs_volume_trace_get_cell_insert); 37 + goto found; 38 + } 39 + } 40 + 41 + rb_link_node_rcu(&volume->cell_node, parent, pp); 42 + rb_insert_color(&volume->cell_node, &cell->volumes); 43 + hlist_add_head_rcu(&volume->proc_link, &cell->proc_volumes); 44 + 45 + found: 46 + write_sequnlock(&cell->volume_lock); 47 + return volume; 48 + 49 + } 50 + 51 + static void afs_remove_volume_from_cell(struct afs_volume *volume) 52 + { 53 + struct afs_cell *cell = volume->cell; 54 + 55 + if (!hlist_unhashed(&volume->proc_link)) { 56 + trace_afs_volume(volume->vid, atomic_read(&volume->usage), 57 + afs_volume_trace_remove); 58 + write_seqlock(&cell->volume_lock); 59 + hlist_del_rcu(&volume->proc_link); 60 + rb_erase(&volume->cell_node, &cell->volumes); 61 + write_sequnlock(&cell->volume_lock); 62 + } 63 + } 64 + 65 + /* 16 66 * Allocate a volume record and load it up from a vldb record. 17 67 */ 18 68 static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, ··· 89 39 volume->name_len = vldb->name_len; 90 40 91 41 atomic_set(&volume->usage, 1); 92 - INIT_LIST_HEAD(&volume->proc_link); 42 + INIT_HLIST_NODE(&volume->proc_link); 93 43 rwlock_init(&volume->servers_lock); 94 44 rwlock_init(&volume->cb_v_break_lock); 95 45 memcpy(volume->name, vldb->name, vldb->name_len + 1); ··· 101 51 } 102 52 103 53 refcount_set(&slist->usage, 1); 104 - volume->servers = slist; 54 + rcu_assign_pointer(volume->servers, slist); 55 + trace_afs_volume(volume->vid, 1, afs_volume_trace_alloc); 105 56 return volume; 106 57 107 58 error_1: ··· 110 59 kfree(volume); 111 60 error_0: 112 61 return ERR_PTR(ret); 62 + } 63 + 64 + /* 65 + * Look up or allocate a volume record. 66 + */ 67 + static struct afs_volume *afs_lookup_volume(struct afs_fs_context *params, 68 + struct afs_vldb_entry *vldb, 69 + unsigned long type_mask) 70 + { 71 + struct afs_volume *candidate, *volume; 72 + 73 + candidate = afs_alloc_volume(params, vldb, type_mask); 74 + if (IS_ERR(candidate)) 75 + return candidate; 76 + 77 + volume = afs_insert_volume_into_cell(params->cell, candidate); 78 + if (volume != candidate) 79 + afs_put_volume(params->net, candidate, afs_volume_trace_put_cell_dup); 80 + return volume; 113 81 } 114 82 115 83 /* ··· 208 138 } 209 139 210 140 type_mask = 1UL << params->type; 211 - volume = afs_alloc_volume(params, vldb, type_mask); 141 + volume = afs_lookup_volume(params, vldb, type_mask); 212 142 213 143 error: 214 144 kfree(vldb); ··· 226 156 ASSERTCMP(volume->cache, ==, NULL); 227 157 #endif 228 158 229 - afs_put_serverlist(net, volume->servers); 159 + afs_remove_volume_from_cell(volume); 160 + afs_put_serverlist(net, rcu_access_pointer(volume->servers)); 230 161 afs_put_cell(net, volume->cell); 231 - kfree(volume); 162 + trace_afs_volume(volume->vid, atomic_read(&volume->usage), 163 + afs_volume_trace_free); 164 + kfree_rcu(volume, rcu); 232 165 233 166 _leave(" [destroyed]"); 234 167 } 235 168 236 169 /* 237 - * Drop a reference on a volume record. 170 + * Get a reference on a volume record. 238 171 */ 239 - void afs_put_volume(struct afs_cell *cell, struct afs_volume *volume) 172 + struct afs_volume *afs_get_volume(struct afs_volume *volume, 173 + enum afs_volume_trace reason) 240 174 { 241 175 if (volume) { 242 - _enter("%s", volume->name); 176 + int u = atomic_inc_return(&volume->usage); 177 + trace_afs_volume(volume->vid, u, reason); 178 + } 179 + return volume; 180 + } 243 181 244 - if (atomic_dec_and_test(&volume->usage)) 245 - afs_destroy_volume(cell->net, volume); 182 + 183 + /* 184 + * Drop a reference on a volume record. 185 + */ 186 + void afs_put_volume(struct afs_net *net, struct afs_volume *volume, 187 + enum afs_volume_trace reason) 188 + { 189 + if (volume) { 190 + afs_volid_t vid = volume->vid; 191 + int u = atomic_dec_return(&volume->usage); 192 + trace_afs_volume(vid, u, reason); 193 + if (u == 0) 194 + afs_destroy_volume(net, volume); 246 195 } 247 196 } 248 197 ··· 277 188 NULL, 0, 278 189 volume, 0, true); 279 190 #endif 280 - 281 - write_lock(&volume->cell->proc_lock); 282 - list_add_tail(&volume->proc_link, &volume->cell->proc_volumes); 283 - write_unlock(&volume->cell->proc_lock); 284 191 } 285 192 286 193 /* ··· 285 200 void afs_deactivate_volume(struct afs_volume *volume) 286 201 { 287 202 _enter("%s", volume->name); 288 - 289 - write_lock(&volume->cell->proc_lock); 290 - list_del_init(&volume->proc_link); 291 - write_unlock(&volume->cell->proc_lock); 292 203 293 204 #ifdef CONFIG_AFS_FSCACHE 294 205 fscache_relinquish_cookie(volume->cache, NULL, ··· 337 256 write_lock(&volume->servers_lock); 338 257 339 258 discard = new; 340 - old = volume->servers; 259 + old = rcu_dereference_protected(volume->servers, 260 + lockdep_is_held(&volume->servers_lock)); 341 261 if (afs_annotate_server_list(new, old)) { 342 262 new->seq = volume->servers_seq + 1; 343 - volume->servers = new; 263 + rcu_assign_pointer(volume->servers, new); 344 264 smp_wmb(); 345 265 volume->servers_seq++; 346 266 discard = old; 347 267 } 348 268 349 269 volume->update_at = ktime_get_real_seconds() + afs_volume_record_life; 350 - clear_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 351 270 write_unlock(&volume->servers_lock); 352 271 ret = 0; 353 272 ··· 362 281 /* 363 282 * Make sure the volume record is up to date. 364 283 */ 365 - int afs_check_volume_status(struct afs_volume *volume, struct afs_fs_cursor *fc) 284 + int afs_check_volume_status(struct afs_volume *volume, struct afs_operation *op) 366 285 { 367 - time64_t now = ktime_get_real_seconds(); 368 286 int ret, retries = 0; 369 287 370 288 _enter(""); 371 289 372 - if (volume->update_at <= now) 373 - set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 374 - 375 290 retry: 376 - if (!test_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags) && 377 - !test_bit(AFS_VOLUME_WAIT, &volume->flags)) { 378 - _leave(" = 0"); 379 - return 0; 380 - } 291 + if (test_bit(AFS_VOLUME_WAIT, &volume->flags)) 292 + goto wait; 293 + if (volume->update_at <= ktime_get_real_seconds() || 294 + test_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags)) 295 + goto update; 296 + _leave(" = 0"); 297 + return 0; 381 298 299 + update: 382 300 if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) { 383 - ret = afs_update_volume_status(volume, fc->key); 301 + clear_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 302 + ret = afs_update_volume_status(volume, op->key); 303 + if (ret < 0) 304 + set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); 384 305 clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags); 385 306 clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags); 386 307 wake_up_bit(&volume->flags, AFS_VOLUME_WAIT); ··· 390 307 return ret; 391 308 } 392 309 310 + wait: 393 311 if (!test_bit(AFS_VOLUME_WAIT, &volume->flags)) { 394 312 _leave(" = 0 [no wait]"); 395 313 return 0; 396 314 } 397 315 398 316 ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT, 399 - (fc->flags & AFS_FS_CURSOR_INTR) ? 400 - TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 317 + (op->flags & AFS_OPERATION_UNINTR) ? 318 + TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE); 401 319 if (ret == -ERESTARTSYS) { 402 320 _leave(" = %d", ret); 403 321 return ret;
+94 -62
fs/afs/write.c
··· 349 349 } 350 350 351 351 /* 352 + * Find a key to use for the writeback. We cached the keys used to author the 353 + * writes on the vnode. *_wbk will contain the last writeback key used or NULL 354 + * and we need to start from there if it's set. 355 + */ 356 + static int afs_get_writeback_key(struct afs_vnode *vnode, 357 + struct afs_wb_key **_wbk) 358 + { 359 + struct afs_wb_key *wbk = NULL; 360 + struct list_head *p; 361 + int ret = -ENOKEY, ret2; 362 + 363 + spin_lock(&vnode->wb_lock); 364 + if (*_wbk) 365 + p = (*_wbk)->vnode_link.next; 366 + else 367 + p = vnode->wb_keys.next; 368 + 369 + while (p != &vnode->wb_keys) { 370 + wbk = list_entry(p, struct afs_wb_key, vnode_link); 371 + _debug("wbk %u", key_serial(wbk->key)); 372 + ret2 = key_validate(wbk->key); 373 + if (ret2 == 0) { 374 + refcount_inc(&wbk->usage); 375 + _debug("USE WB KEY %u", key_serial(wbk->key)); 376 + break; 377 + } 378 + 379 + wbk = NULL; 380 + if (ret == -ENOKEY) 381 + ret = ret2; 382 + p = p->next; 383 + } 384 + 385 + spin_unlock(&vnode->wb_lock); 386 + if (*_wbk) 387 + afs_put_wb_key(*_wbk); 388 + *_wbk = wbk; 389 + return 0; 390 + } 391 + 392 + static void afs_store_data_success(struct afs_operation *op) 393 + { 394 + struct afs_vnode *vnode = op->file[0].vnode; 395 + 396 + afs_vnode_commit_status(op, &op->file[0]); 397 + if (op->error == 0) { 398 + afs_pages_written_back(vnode, op->store.first, op->store.last); 399 + afs_stat_v(vnode, n_stores); 400 + atomic_long_add((op->store.last * PAGE_SIZE + op->store.last_to) - 401 + (op->store.first * PAGE_SIZE + op->store.first_offset), 402 + &afs_v2net(vnode)->n_store_bytes); 403 + } 404 + } 405 + 406 + static const struct afs_operation_ops afs_store_data_operation = { 407 + .issue_afs_rpc = afs_fs_store_data, 408 + .issue_yfs_rpc = yfs_fs_store_data, 409 + .success = afs_store_data_success, 410 + }; 411 + 412 + /* 352 413 * write to a file 353 414 */ 354 415 static int afs_store_data(struct address_space *mapping, ··· 417 356 unsigned offset, unsigned to) 418 357 { 419 358 struct afs_vnode *vnode = AFS_FS_I(mapping->host); 420 - struct afs_fs_cursor fc; 421 - struct afs_status_cb *scb; 359 + struct afs_operation *op; 422 360 struct afs_wb_key *wbk = NULL; 423 - struct list_head *p; 424 - int ret = -ENOKEY, ret2; 361 + int ret; 425 362 426 363 _enter("%s{%llx:%llu.%u},%lx,%lx,%x,%x", 427 364 vnode->volume->name, ··· 428 369 vnode->fid.unique, 429 370 first, last, offset, to); 430 371 431 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS); 432 - if (!scb) 372 + ret = afs_get_writeback_key(vnode, &wbk); 373 + if (ret) { 374 + _leave(" = %d [no keys]", ret); 375 + return ret; 376 + } 377 + 378 + op = afs_alloc_operation(wbk->key, vnode->volume); 379 + if (IS_ERR(op)) { 380 + afs_put_wb_key(wbk); 433 381 return -ENOMEM; 382 + } 434 383 435 - spin_lock(&vnode->wb_lock); 436 - p = vnode->wb_keys.next; 384 + afs_op_set_vnode(op, 0, vnode); 385 + op->file[0].dv_delta = 1; 386 + op->store.mapping = mapping; 387 + op->store.first = first; 388 + op->store.last = last; 389 + op->store.first_offset = offset; 390 + op->store.last_to = to; 391 + op->ops = &afs_store_data_operation; 437 392 438 - /* Iterate through the list looking for a valid key to use. */ 439 393 try_next_key: 440 - while (p != &vnode->wb_keys) { 441 - wbk = list_entry(p, struct afs_wb_key, vnode_link); 442 - _debug("wbk %u", key_serial(wbk->key)); 443 - ret2 = key_validate(wbk->key); 444 - if (ret2 == 0) 445 - goto found_key; 446 - if (ret == -ENOKEY) 447 - ret = ret2; 448 - p = p->next; 449 - } 394 + afs_begin_vnode_operation(op); 395 + afs_wait_for_operation(op); 450 396 451 - spin_unlock(&vnode->wb_lock); 452 - afs_put_wb_key(wbk); 453 - kfree(scb); 454 - _leave(" = %d [no keys]", ret); 455 - return ret; 456 - 457 - found_key: 458 - refcount_inc(&wbk->usage); 459 - spin_unlock(&vnode->wb_lock); 460 - 461 - _debug("USE WB KEY %u", key_serial(wbk->key)); 462 - 463 - ret = -ERESTARTSYS; 464 - if (afs_begin_vnode_operation(&fc, vnode, wbk->key, false)) { 465 - afs_dataversion_t data_version = vnode->status.data_version + 1; 466 - 467 - while (afs_select_fileserver(&fc)) { 468 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 469 - afs_fs_store_data(&fc, mapping, first, last, offset, to, scb); 470 - } 471 - 472 - afs_check_for_remote_deletion(&fc, vnode); 473 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 474 - &data_version, scb); 475 - if (fc.ac.error == 0) 476 - afs_pages_written_back(vnode, first, last); 477 - ret = afs_end_vnode_operation(&fc); 478 - } 479 - 480 - switch (ret) { 481 - case 0: 482 - afs_stat_v(vnode, n_stores); 483 - atomic_long_add((last * PAGE_SIZE + to) - 484 - (first * PAGE_SIZE + offset), 485 - &afs_v2net(vnode)->n_store_bytes); 486 - break; 397 + switch (op->error) { 487 398 case -EACCES: 488 399 case -EPERM: 489 400 case -ENOKEY: ··· 461 432 case -EKEYREJECTED: 462 433 case -EKEYREVOKED: 463 434 _debug("next"); 464 - spin_lock(&vnode->wb_lock); 465 - p = wbk->vnode_link.next; 466 - afs_put_wb_key(wbk); 467 - goto try_next_key; 435 + 436 + ret = afs_get_writeback_key(vnode, &wbk); 437 + if (ret == 0) { 438 + key_put(op->key); 439 + op->key = key_get(wbk->key); 440 + goto try_next_key; 441 + } 442 + break; 468 443 } 469 444 470 445 afs_put_wb_key(wbk); 471 - kfree(scb); 472 - _leave(" = %d", ret); 473 - return ret; 446 + _leave(" = %d", op->error); 447 + return afs_put_operation(op); 474 448 } 475 449 476 450 /*
+127 -173
fs/afs/xattr.c
··· 35 35 } 36 36 37 37 /* 38 + * Deal with the result of a successful fetch ACL operation. 39 + */ 40 + static void afs_acl_success(struct afs_operation *op) 41 + { 42 + afs_vnode_commit_status(op, &op->file[0]); 43 + } 44 + 45 + static void afs_acl_put(struct afs_operation *op) 46 + { 47 + kfree(op->acl); 48 + } 49 + 50 + static const struct afs_operation_ops afs_fetch_acl_operation = { 51 + .issue_afs_rpc = afs_fs_fetch_acl, 52 + .success = afs_acl_success, 53 + .put = afs_acl_put, 54 + }; 55 + 56 + /* 38 57 * Get a file's ACL. 39 58 */ 40 59 static int afs_xattr_get_acl(const struct xattr_handler *handler, ··· 61 42 struct inode *inode, const char *name, 62 43 void *buffer, size_t size) 63 44 { 64 - struct afs_fs_cursor fc; 65 - struct afs_status_cb *scb; 45 + struct afs_operation *op; 66 46 struct afs_vnode *vnode = AFS_FS_I(inode); 67 47 struct afs_acl *acl = NULL; 68 - struct key *key; 69 - int ret = -ENOMEM; 48 + int ret; 70 49 71 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS); 72 - if (!scb) 73 - goto error; 50 + op = afs_alloc_operation(NULL, vnode->volume); 51 + if (IS_ERR(op)) 52 + return -ENOMEM; 74 53 75 - key = afs_request_key(vnode->volume->cell); 76 - if (IS_ERR(key)) { 77 - ret = PTR_ERR(key); 78 - goto error_scb; 79 - } 54 + afs_op_set_vnode(op, 0, vnode); 55 + op->ops = &afs_fetch_acl_operation; 80 56 81 - ret = -ERESTARTSYS; 82 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 83 - afs_dataversion_t data_version = vnode->status.data_version; 84 - 85 - while (afs_select_fileserver(&fc)) { 86 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 87 - acl = afs_fs_fetch_acl(&fc, scb); 88 - } 89 - 90 - afs_check_for_remote_deletion(&fc, fc.vnode); 91 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 92 - &data_version, scb); 93 - ret = afs_end_vnode_operation(&fc); 94 - } 57 + afs_begin_vnode_operation(op); 58 + afs_wait_for_operation(op); 59 + acl = op->acl; 60 + op->acl = NULL; 61 + ret = afs_put_operation(op); 95 62 96 63 if (ret == 0) { 97 64 ret = acl->size; ··· 85 80 if (acl->size <= size) 86 81 memcpy(buffer, acl->data, acl->size); 87 82 else 88 - ret = -ERANGE; 83 + op->error = -ERANGE; 89 84 } 90 - kfree(acl); 91 85 } 92 86 93 - key_put(key); 94 - error_scb: 95 - kfree(scb); 96 - error: 87 + kfree(acl); 97 88 return ret; 98 89 } 90 + 91 + static bool afs_make_acl(struct afs_operation *op, 92 + const void *buffer, size_t size) 93 + { 94 + struct afs_acl *acl; 95 + 96 + acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); 97 + if (!acl) { 98 + afs_op_nomem(op); 99 + return false; 100 + } 101 + 102 + acl->size = size; 103 + memcpy(acl->data, buffer, size); 104 + op->acl = acl; 105 + return true; 106 + } 107 + 108 + static const struct afs_operation_ops afs_store_acl_operation = { 109 + .issue_afs_rpc = afs_fs_store_acl, 110 + .success = afs_acl_success, 111 + .put = afs_acl_put, 112 + }; 99 113 100 114 /* 101 115 * Set a file's AFS3 ACL. ··· 124 100 struct inode *inode, const char *name, 125 101 const void *buffer, size_t size, int flags) 126 102 { 127 - struct afs_fs_cursor fc; 128 - struct afs_status_cb *scb; 103 + struct afs_operation *op; 129 104 struct afs_vnode *vnode = AFS_FS_I(inode); 130 - struct afs_acl *acl = NULL; 131 - struct key *key; 132 - int ret = -ENOMEM; 133 105 134 106 if (flags == XATTR_CREATE) 135 107 return -EINVAL; 136 108 137 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS); 138 - if (!scb) 139 - goto error; 109 + op = afs_alloc_operation(NULL, vnode->volume); 110 + if (IS_ERR(op)) 111 + return -ENOMEM; 140 112 141 - acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); 142 - if (!acl) 143 - goto error_scb; 113 + afs_op_set_vnode(op, 0, vnode); 114 + if (!afs_make_acl(op, buffer, size)) 115 + return afs_put_operation(op); 144 116 145 - key = afs_request_key(vnode->volume->cell); 146 - if (IS_ERR(key)) { 147 - ret = PTR_ERR(key); 148 - goto error_acl; 149 - } 150 - 151 - acl->size = size; 152 - memcpy(acl->data, buffer, size); 153 - 154 - ret = -ERESTARTSYS; 155 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 156 - afs_dataversion_t data_version = vnode->status.data_version; 157 - 158 - while (afs_select_fileserver(&fc)) { 159 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 160 - afs_fs_store_acl(&fc, acl, scb); 161 - } 162 - 163 - afs_check_for_remote_deletion(&fc, fc.vnode); 164 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 165 - &data_version, scb); 166 - ret = afs_end_vnode_operation(&fc); 167 - } 168 - 169 - key_put(key); 170 - error_acl: 171 - kfree(acl); 172 - error_scb: 173 - kfree(scb); 174 - error: 175 - return ret; 117 + op->ops = &afs_store_acl_operation; 118 + return afs_do_sync_operation(op); 176 119 } 177 120 178 121 static const struct xattr_handler afs_xattr_afs_acl_handler = { 179 122 .name = "afs.acl", 180 123 .get = afs_xattr_get_acl, 181 124 .set = afs_xattr_set_acl, 125 + }; 126 + 127 + static void yfs_acl_put(struct afs_operation *op) 128 + { 129 + yfs_free_opaque_acl(op->yacl); 130 + } 131 + 132 + static const struct afs_operation_ops yfs_fetch_opaque_acl_operation = { 133 + .issue_yfs_rpc = yfs_fs_fetch_opaque_acl, 134 + .success = afs_acl_success, 135 + /* Don't free op->yacl in .put here */ 182 136 }; 183 137 184 138 /* ··· 167 165 struct inode *inode, const char *name, 168 166 void *buffer, size_t size) 169 167 { 170 - struct afs_fs_cursor fc; 171 - struct afs_status_cb *scb; 168 + struct afs_operation *op; 172 169 struct afs_vnode *vnode = AFS_FS_I(inode); 173 170 struct yfs_acl *yacl = NULL; 174 - struct key *key; 175 171 char buf[16], *data; 176 172 int which = 0, dsize, ret = -ENOMEM; 177 173 ··· 193 193 else if (which == 3) 194 194 yacl->flags |= YFS_ACL_WANT_VOL_ACL; 195 195 196 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS); 197 - if (!scb) 196 + op = afs_alloc_operation(NULL, vnode->volume); 197 + if (IS_ERR(op)) 198 198 goto error_yacl; 199 199 200 - key = afs_request_key(vnode->volume->cell); 201 - if (IS_ERR(key)) { 202 - ret = PTR_ERR(key); 203 - goto error_scb; 204 - } 200 + afs_op_set_vnode(op, 0, vnode); 201 + op->yacl = yacl; 202 + op->ops = &yfs_fetch_opaque_acl_operation; 205 203 206 - ret = -ERESTARTSYS; 207 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 208 - afs_dataversion_t data_version = vnode->status.data_version; 204 + afs_begin_vnode_operation(op); 205 + afs_wait_for_operation(op); 206 + ret = afs_put_operation(op); 209 207 210 - while (afs_select_fileserver(&fc)) { 211 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 212 - yfs_fs_fetch_opaque_acl(&fc, yacl, scb); 208 + if (ret == 0) { 209 + switch (which) { 210 + case 0: 211 + data = yacl->acl->data; 212 + dsize = yacl->acl->size; 213 + break; 214 + case 1: 215 + data = buf; 216 + dsize = scnprintf(buf, sizeof(buf), "%u", yacl->inherit_flag); 217 + break; 218 + case 2: 219 + data = buf; 220 + dsize = scnprintf(buf, sizeof(buf), "%u", yacl->num_cleaned); 221 + break; 222 + case 3: 223 + data = yacl->vol_acl->data; 224 + dsize = yacl->vol_acl->size; 225 + break; 226 + default: 227 + ret = -EOPNOTSUPP; 228 + goto error_yacl; 213 229 } 214 230 215 - afs_check_for_remote_deletion(&fc, fc.vnode); 216 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 217 - &data_version, scb); 218 - ret = afs_end_vnode_operation(&fc); 219 - } 220 - 221 - if (ret < 0) 222 - goto error_key; 223 - 224 - switch (which) { 225 - case 0: 226 - data = yacl->acl->data; 227 - dsize = yacl->acl->size; 228 - break; 229 - case 1: 230 - data = buf; 231 - dsize = scnprintf(buf, sizeof(buf), "%u", yacl->inherit_flag); 232 - break; 233 - case 2: 234 - data = buf; 235 - dsize = scnprintf(buf, sizeof(buf), "%u", yacl->num_cleaned); 236 - break; 237 - case 3: 238 - data = yacl->vol_acl->data; 239 - dsize = yacl->vol_acl->size; 240 - break; 241 - default: 242 - ret = -EOPNOTSUPP; 243 - goto error_key; 244 - } 245 - 246 - ret = dsize; 247 - if (size > 0) { 248 - if (dsize > size) { 249 - ret = -ERANGE; 250 - goto error_key; 231 + ret = dsize; 232 + if (size > 0) { 233 + if (dsize <= size) 234 + memcpy(buffer, data, dsize); 235 + else 236 + ret = -ERANGE; 251 237 } 252 - memcpy(buffer, data, dsize); 253 238 } 254 239 255 - error_key: 256 - key_put(key); 257 - error_scb: 258 - kfree(scb); 259 240 error_yacl: 260 241 yfs_free_opaque_acl(yacl); 261 242 error: 262 243 return ret; 263 244 } 245 + 246 + static const struct afs_operation_ops yfs_store_opaque_acl2_operation = { 247 + .issue_yfs_rpc = yfs_fs_store_opaque_acl2, 248 + .success = afs_acl_success, 249 + .put = yfs_acl_put, 250 + }; 264 251 265 252 /* 266 253 * Set a file's YFS ACL. ··· 257 270 struct inode *inode, const char *name, 258 271 const void *buffer, size_t size, int flags) 259 272 { 260 - struct afs_fs_cursor fc; 261 - struct afs_status_cb *scb; 273 + struct afs_operation *op; 262 274 struct afs_vnode *vnode = AFS_FS_I(inode); 263 - struct afs_acl *acl = NULL; 264 - struct key *key; 265 - int ret = -ENOMEM; 266 275 267 276 if (flags == XATTR_CREATE || 268 277 strcmp(name, "acl") != 0) 269 278 return -EINVAL; 270 279 271 - scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS); 272 - if (!scb) 273 - goto error; 280 + op = afs_alloc_operation(NULL, vnode->volume); 281 + if (IS_ERR(op)) 282 + return -ENOMEM; 274 283 275 - acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); 276 - if (!acl) 277 - goto error_scb; 284 + afs_op_set_vnode(op, 0, vnode); 285 + if (!afs_make_acl(op, buffer, size)) 286 + return afs_put_operation(op); 278 287 279 - acl->size = size; 280 - memcpy(acl->data, buffer, size); 281 - 282 - key = afs_request_key(vnode->volume->cell); 283 - if (IS_ERR(key)) { 284 - ret = PTR_ERR(key); 285 - goto error_acl; 286 - } 287 - 288 - ret = -ERESTARTSYS; 289 - if (afs_begin_vnode_operation(&fc, vnode, key, true)) { 290 - afs_dataversion_t data_version = vnode->status.data_version; 291 - 292 - while (afs_select_fileserver(&fc)) { 293 - fc.cb_break = afs_calc_vnode_cb_break(vnode); 294 - yfs_fs_store_opaque_acl2(&fc, acl, scb); 295 - } 296 - 297 - afs_check_for_remote_deletion(&fc, fc.vnode); 298 - afs_vnode_commit_status(&fc, vnode, fc.cb_break, 299 - &data_version, scb); 300 - ret = afs_end_vnode_operation(&fc); 301 - } 302 - 303 - error_acl: 304 - kfree(acl); 305 - key_put(key); 306 - error_scb: 307 - kfree(scb); 308 - error: 309 - return ret; 288 + op->ops = &yfs_store_opaque_acl2_operation; 289 + return afs_do_sync_operation(op); 310 290 } 311 291 312 292 static const struct xattr_handler afs_xattr_yfs_handler = {
+374 -538
fs/afs/yfsclient.c
··· 17 17 18 18 static const struct afs_fid afs_zero_fid; 19 19 20 - static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi) 21 - { 22 - call->cbi = afs_get_cb_interest(cbi); 23 - } 24 - 25 20 #define xdr_size(x) (sizeof(*x) / sizeof(__be32)) 26 21 27 22 static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid) ··· 72 77 } 73 78 74 79 return bp + len / sizeof(__be32); 80 + } 81 + 82 + static __be32 *xdr_encode_name(__be32 *bp, const struct qstr *p) 83 + { 84 + return xdr_encode_string(bp, p->name, p->len); 75 85 } 76 86 77 87 static s64 linux_to_yfs_time(const struct timespec64 *t) ··· 179 179 /* 180 180 * Decode a YFSFetchStatus block 181 181 */ 182 - static int xdr_decode_YFSFetchStatus(const __be32 **_bp, 183 - struct afs_call *call, 184 - struct afs_status_cb *scb) 182 + static void xdr_decode_YFSFetchStatus(const __be32 **_bp, 183 + struct afs_call *call, 184 + struct afs_status_cb *scb) 185 185 { 186 186 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp; 187 187 struct afs_file_status *status = &scb->status; 188 188 u32 type; 189 - int ret; 190 189 191 190 status->abort_code = ntohl(xdr->abort_code); 192 191 if (status->abort_code != 0) { 193 192 if (status->abort_code == VNOVNODE) 194 193 status->nlink = 0; 195 194 scb->have_error = true; 196 - goto good; 195 + goto advance; 197 196 } 198 197 199 198 type = ntohl(xdr->type); ··· 220 221 status->size = xdr_to_u64(xdr->size); 221 222 status->data_version = xdr_to_u64(xdr->data_version); 222 223 scb->have_status = true; 223 - good: 224 - ret = 0; 225 224 advance: 226 225 *_bp += xdr_size(xdr); 227 - return ret; 226 + return; 228 227 229 228 bad: 230 229 xdr_dump_bad(*_bp); 231 - ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); 230 + afs_protocol_error(call, afs_eproto_bad_status); 232 231 goto advance; 233 232 } 234 233 ··· 336 339 */ 337 340 static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call) 338 341 { 342 + struct afs_operation *op = call->op; 339 343 const __be32 *bp; 340 344 int ret; 341 345 ··· 346 348 347 349 /* unmarshall the reply once we've received all of it */ 348 350 bp = call->buffer; 349 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 350 - if (ret < 0) 351 - return ret; 352 - xdr_decode_YFSCallBack(&bp, call, call->out_scb); 353 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 351 + xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb); 352 + xdr_decode_YFSCallBack(&bp, call, &op->file[0].scb); 353 + xdr_decode_YFSVolSync(&bp, &op->volsync); 354 354 355 355 _leave(" = 0 [done]"); 356 356 return 0; ··· 360 364 */ 361 365 static int yfs_deliver_status_and_volsync(struct afs_call *call) 362 366 { 367 + struct afs_operation *op = call->op; 363 368 const __be32 *bp; 364 369 int ret; 365 370 ··· 369 372 return ret; 370 373 371 374 bp = call->buffer; 372 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 373 - if (ret < 0) 374 - return ret; 375 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 375 + xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb); 376 + xdr_decode_YFSVolSync(&bp, &op->volsync); 376 377 377 378 _leave(" = 0 [done]"); 378 379 return 0; ··· 389 394 /* 390 395 * Fetch the status information for a file. 391 396 */ 392 - int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb, 393 - struct afs_volsync *volsync) 397 + void yfs_fs_fetch_file_status(struct afs_operation *op) 394 398 { 395 - struct afs_vnode *vnode = fc->vnode; 399 + struct afs_vnode_param *vp = &op->file[0]; 396 400 struct afs_call *call; 397 - struct afs_net *net = afs_v2net(vnode); 398 401 __be32 *bp; 399 402 400 403 _enter(",%x,{%llx:%llu},,", 401 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 404 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 402 405 403 - call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode, 406 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus_vnode, 404 407 sizeof(__be32) * 2 + 405 408 sizeof(struct yfs_xdr_YFSFid), 406 409 sizeof(struct yfs_xdr_YFSFetchStatus) + 407 410 sizeof(struct yfs_xdr_YFSCallBack) + 408 411 sizeof(struct yfs_xdr_YFSVolSync)); 409 - if (!call) { 410 - fc->ac.error = -ENOMEM; 411 - return -ENOMEM; 412 - } 413 - 414 - call->key = fc->key; 415 - call->out_scb = scb; 416 - call->out_volsync = volsync; 412 + if (!call) 413 + return afs_op_nomem(op); 417 414 418 415 /* marshall the parameters */ 419 416 bp = call->request; 420 417 bp = xdr_encode_u32(bp, YFSFETCHSTATUS); 421 418 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 422 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 419 + bp = xdr_encode_YFSFid(bp, &vp->fid); 423 420 yfs_check_req(call, bp); 424 421 425 - afs_use_fs_server(call, fc->cbi); 426 - trace_afs_make_fs_call(call, &vnode->fid); 427 - afs_set_fc_call(call, fc); 428 - afs_make_call(&fc->ac, call, GFP_NOFS); 429 - return afs_wait_for_call_to_complete(call, &fc->ac); 422 + trace_afs_make_fs_call(call, &vp->fid); 423 + afs_make_op_call(op, call, GFP_NOFS); 430 424 } 431 425 432 426 /* ··· 423 439 */ 424 440 static int yfs_deliver_fs_fetch_data64(struct afs_call *call) 425 441 { 426 - struct afs_read *req = call->read_request; 442 + struct afs_operation *op = call->op; 443 + struct afs_vnode_param *vp = &op->file[0]; 444 + struct afs_read *req = op->fetch.req; 427 445 const __be32 *bp; 428 446 unsigned int size; 429 447 int ret; ··· 520 534 return ret; 521 535 522 536 bp = call->buffer; 523 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 524 - if (ret < 0) 525 - return ret; 526 - xdr_decode_YFSCallBack(&bp, call, call->out_scb); 527 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 537 + xdr_decode_YFSFetchStatus(&bp, call, &vp->scb); 538 + xdr_decode_YFSCallBack(&bp, call, &vp->scb); 539 + xdr_decode_YFSVolSync(&bp, &op->volsync); 528 540 529 - req->data_version = call->out_scb->status.data_version; 530 - req->file_size = call->out_scb->status.size; 541 + req->data_version = vp->scb.status.data_version; 542 + req->file_size = vp->scb.status.size; 531 543 532 544 call->unmarshall++; 533 545 /* Fall through */ ··· 549 565 return 0; 550 566 } 551 567 552 - static void yfs_fetch_data_destructor(struct afs_call *call) 553 - { 554 - afs_put_read(call->read_request); 555 - afs_flat_call_destructor(call); 556 - } 557 - 558 568 /* 559 569 * YFS.FetchData64 operation type 560 570 */ ··· 556 578 .name = "YFS.FetchData64", 557 579 .op = yfs_FS_FetchData64, 558 580 .deliver = yfs_deliver_fs_fetch_data64, 559 - .destructor = yfs_fetch_data_destructor, 581 + .destructor = afs_flat_call_destructor, 560 582 }; 561 583 562 584 /* 563 585 * Fetch data from a file. 564 586 */ 565 - int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb, 566 - struct afs_read *req) 587 + void yfs_fs_fetch_data(struct afs_operation *op) 567 588 { 568 - struct afs_vnode *vnode = fc->vnode; 589 + struct afs_vnode_param *vp = &op->file[0]; 590 + struct afs_read *req = op->fetch.req; 569 591 struct afs_call *call; 570 - struct afs_net *net = afs_v2net(vnode); 571 592 __be32 *bp; 572 593 573 594 _enter(",%x,{%llx:%llu},%llx,%llx", 574 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode, 595 + key_serial(op->key), vp->fid.vid, vp->fid.vnode, 575 596 req->pos, req->len); 576 597 577 - call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64, 598 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchData64, 578 599 sizeof(__be32) * 2 + 579 600 sizeof(struct yfs_xdr_YFSFid) + 580 601 sizeof(struct yfs_xdr_u64) * 2, ··· 581 604 sizeof(struct yfs_xdr_YFSCallBack) + 582 605 sizeof(struct yfs_xdr_YFSVolSync)); 583 606 if (!call) 584 - return -ENOMEM; 585 - 586 - call->key = fc->key; 587 - call->out_scb = scb; 588 - call->out_volsync = NULL; 589 - call->read_request = afs_get_read(req); 607 + return afs_op_nomem(op); 590 608 591 609 /* marshall the parameters */ 592 610 bp = call->request; 593 611 bp = xdr_encode_u32(bp, YFSFETCHDATA64); 594 612 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 595 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 613 + bp = xdr_encode_YFSFid(bp, &vp->fid); 596 614 bp = xdr_encode_u64(bp, req->pos); 597 615 bp = xdr_encode_u64(bp, req->len); 598 616 yfs_check_req(call, bp); 599 617 600 - afs_use_fs_server(call, fc->cbi); 601 - trace_afs_make_fs_call(call, &vnode->fid); 602 - afs_set_fc_call(call, fc); 603 - afs_make_call(&fc->ac, call, GFP_NOFS); 604 - return afs_wait_for_call_to_complete(call, &fc->ac); 618 + trace_afs_make_fs_call(call, &vp->fid); 619 + afs_make_op_call(op, call, GFP_NOFS); 605 620 } 606 621 607 622 /* ··· 601 632 */ 602 633 static int yfs_deliver_fs_create_vnode(struct afs_call *call) 603 634 { 635 + struct afs_operation *op = call->op; 636 + struct afs_vnode_param *dvp = &op->file[0]; 637 + struct afs_vnode_param *vp = &op->file[1]; 604 638 const __be32 *bp; 605 639 int ret; 606 640 ··· 615 643 616 644 /* unmarshall the reply once we've received all of it */ 617 645 bp = call->buffer; 618 - xdr_decode_YFSFid(&bp, call->out_fid); 619 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 620 - if (ret < 0) 621 - return ret; 622 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); 623 - if (ret < 0) 624 - return ret; 625 - xdr_decode_YFSCallBack(&bp, call, call->out_scb); 626 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 646 + xdr_decode_YFSFid(&bp, &op->file[1].fid); 647 + xdr_decode_YFSFetchStatus(&bp, call, &vp->scb); 648 + xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb); 649 + xdr_decode_YFSCallBack(&bp, call, &vp->scb); 650 + xdr_decode_YFSVolSync(&bp, &op->volsync); 627 651 628 652 _leave(" = 0 [done]"); 629 653 return 0; ··· 638 670 /* 639 671 * Create a file. 640 672 */ 641 - int yfs_fs_create_file(struct afs_fs_cursor *fc, 642 - const char *name, 643 - umode_t mode, 644 - struct afs_status_cb *dvnode_scb, 645 - struct afs_fid *newfid, 646 - struct afs_status_cb *new_scb) 673 + void yfs_fs_create_file(struct afs_operation *op) 647 674 { 648 - struct afs_vnode *dvnode = fc->vnode; 675 + const struct qstr *name = &op->dentry->d_name; 676 + struct afs_vnode_param *dvp = &op->file[0]; 649 677 struct afs_call *call; 650 - struct afs_net *net = afs_v2net(dvnode); 651 - size_t namesz, reqsz, rplsz; 678 + size_t reqsz, rplsz; 652 679 __be32 *bp; 653 680 654 681 _enter(""); 655 682 656 - namesz = strlen(name); 657 683 reqsz = (sizeof(__be32) + 658 684 sizeof(__be32) + 659 685 sizeof(struct yfs_xdr_YFSFid) + 660 - xdr_strlen(namesz) + 686 + xdr_strlen(name->len) + 661 687 sizeof(struct yfs_xdr_YFSStoreStatus) + 662 688 sizeof(__be32)); 663 689 rplsz = (sizeof(struct yfs_xdr_YFSFid) + ··· 660 698 sizeof(struct yfs_xdr_YFSCallBack) + 661 699 sizeof(struct yfs_xdr_YFSVolSync)); 662 700 663 - call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz); 701 + call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, reqsz, rplsz); 664 702 if (!call) 665 - return -ENOMEM; 666 - 667 - call->key = fc->key; 668 - call->out_dir_scb = dvnode_scb; 669 - call->out_fid = newfid; 670 - call->out_scb = new_scb; 703 + return afs_op_nomem(op); 671 704 672 705 /* marshall the parameters */ 673 706 bp = call->request; 674 707 bp = xdr_encode_u32(bp, YFSCREATEFILE); 675 708 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 676 - bp = xdr_encode_YFSFid(bp, &dvnode->fid); 677 - bp = xdr_encode_string(bp, name, namesz); 678 - bp = xdr_encode_YFSStoreStatus_mode(bp, mode); 709 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 710 + bp = xdr_encode_name(bp, name); 711 + bp = xdr_encode_YFSStoreStatus_mode(bp, op->create.mode); 679 712 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */ 680 713 yfs_check_req(call, bp); 681 714 682 - afs_use_fs_server(call, fc->cbi); 683 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 684 - afs_set_fc_call(call, fc); 685 - afs_make_call(&fc->ac, call, GFP_NOFS); 686 - return afs_wait_for_call_to_complete(call, &fc->ac); 715 + trace_afs_make_fs_call1(call, &dvp->fid, name); 716 + afs_make_op_call(op, call, GFP_NOFS); 687 717 } 688 718 689 719 static const struct afs_call_type yfs_RXFSMakeDir = { ··· 688 734 /* 689 735 * Make a directory. 690 736 */ 691 - int yfs_fs_make_dir(struct afs_fs_cursor *fc, 692 - const char *name, 693 - umode_t mode, 694 - struct afs_status_cb *dvnode_scb, 695 - struct afs_fid *newfid, 696 - struct afs_status_cb *new_scb) 737 + void yfs_fs_make_dir(struct afs_operation *op) 697 738 { 698 - struct afs_vnode *dvnode = fc->vnode; 739 + const struct qstr *name = &op->dentry->d_name; 740 + struct afs_vnode_param *dvp = &op->file[0]; 699 741 struct afs_call *call; 700 - struct afs_net *net = afs_v2net(dvnode); 701 - size_t namesz, reqsz, rplsz; 742 + size_t reqsz, rplsz; 702 743 __be32 *bp; 703 744 704 745 _enter(""); 705 746 706 - namesz = strlen(name); 707 747 reqsz = (sizeof(__be32) + 708 748 sizeof(struct yfs_xdr_RPCFlags) + 709 749 sizeof(struct yfs_xdr_YFSFid) + 710 - xdr_strlen(namesz) + 750 + xdr_strlen(name->len) + 711 751 sizeof(struct yfs_xdr_YFSStoreStatus)); 712 752 rplsz = (sizeof(struct yfs_xdr_YFSFid) + 713 753 sizeof(struct yfs_xdr_YFSFetchStatus) + ··· 709 761 sizeof(struct yfs_xdr_YFSCallBack) + 710 762 sizeof(struct yfs_xdr_YFSVolSync)); 711 763 712 - call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz); 764 + call = afs_alloc_flat_call(op->net, &yfs_RXFSMakeDir, reqsz, rplsz); 713 765 if (!call) 714 - return -ENOMEM; 715 - 716 - call->key = fc->key; 717 - call->out_dir_scb = dvnode_scb; 718 - call->out_fid = newfid; 719 - call->out_scb = new_scb; 766 + return afs_op_nomem(op); 720 767 721 768 /* marshall the parameters */ 722 769 bp = call->request; 723 770 bp = xdr_encode_u32(bp, YFSMAKEDIR); 724 771 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 725 - bp = xdr_encode_YFSFid(bp, &dvnode->fid); 726 - bp = xdr_encode_string(bp, name, namesz); 727 - bp = xdr_encode_YFSStoreStatus_mode(bp, mode); 772 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 773 + bp = xdr_encode_name(bp, name); 774 + bp = xdr_encode_YFSStoreStatus_mode(bp, op->create.mode); 728 775 yfs_check_req(call, bp); 729 776 730 - afs_use_fs_server(call, fc->cbi); 731 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 732 - afs_set_fc_call(call, fc); 733 - afs_make_call(&fc->ac, call, GFP_NOFS); 734 - return afs_wait_for_call_to_complete(call, &fc->ac); 777 + trace_afs_make_fs_call1(call, &dvp->fid, name); 778 + afs_make_op_call(op, call, GFP_NOFS); 735 779 } 736 780 737 781 /* ··· 731 791 */ 732 792 static int yfs_deliver_fs_remove_file2(struct afs_call *call) 733 793 { 794 + struct afs_operation *op = call->op; 795 + struct afs_vnode_param *dvp = &op->file[0]; 796 + struct afs_vnode_param *vp = &op->file[1]; 734 797 struct afs_fid fid; 735 798 const __be32 *bp; 736 799 int ret; ··· 745 802 return ret; 746 803 747 804 bp = call->buffer; 748 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); 749 - if (ret < 0) 750 - return ret; 751 - 805 + xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb); 752 806 xdr_decode_YFSFid(&bp, &fid); 753 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 754 - if (ret < 0) 755 - return ret; 807 + xdr_decode_YFSFetchStatus(&bp, call, &vp->scb); 756 808 /* Was deleted if vnode->status.abort_code == VNOVNODE. */ 757 809 758 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 810 + xdr_decode_YFSVolSync(&bp, &op->volsync); 759 811 return 0; 812 + } 813 + 814 + static void yfs_done_fs_remove_file2(struct afs_call *call) 815 + { 816 + if (call->error == -ECONNABORTED && 817 + call->abort_code == RX_INVALID_OPERATION) { 818 + set_bit(AFS_SERVER_FL_NO_RM2, &call->server->flags); 819 + call->op->flags |= AFS_OPERATION_DOWNGRADE; 820 + } 760 821 } 761 822 762 823 /* ··· 770 823 .name = "YFS.RemoveFile2", 771 824 .op = yfs_FS_RemoveFile2, 772 825 .deliver = yfs_deliver_fs_remove_file2, 826 + .done = yfs_done_fs_remove_file2, 773 827 .destructor = afs_flat_call_destructor, 774 828 }; 775 829 776 830 /* 777 831 * Remove a file and retrieve new file status. 778 832 */ 779 - int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 780 - const char *name, struct afs_status_cb *dvnode_scb, 781 - struct afs_status_cb *vnode_scb) 833 + void yfs_fs_remove_file2(struct afs_operation *op) 782 834 { 783 - struct afs_vnode *dvnode = fc->vnode; 835 + struct afs_vnode_param *dvp = &op->file[0]; 836 + const struct qstr *name = &op->dentry->d_name; 784 837 struct afs_call *call; 785 - struct afs_net *net = afs_v2net(dvnode); 786 - size_t namesz; 787 838 __be32 *bp; 788 839 789 840 _enter(""); 790 841 791 - namesz = strlen(name); 792 - 793 - call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2, 842 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile2, 794 843 sizeof(__be32) + 795 844 sizeof(struct yfs_xdr_RPCFlags) + 796 845 sizeof(struct yfs_xdr_YFSFid) + 797 - xdr_strlen(namesz), 846 + xdr_strlen(name->len), 798 847 sizeof(struct yfs_xdr_YFSFetchStatus) + 799 848 sizeof(struct yfs_xdr_YFSFid) + 800 849 sizeof(struct yfs_xdr_YFSFetchStatus) + 801 850 sizeof(struct yfs_xdr_YFSVolSync)); 802 851 if (!call) 803 - return -ENOMEM; 804 - 805 - call->key = fc->key; 806 - call->out_dir_scb = dvnode_scb; 807 - call->out_scb = vnode_scb; 852 + return afs_op_nomem(op); 808 853 809 854 /* marshall the parameters */ 810 855 bp = call->request; 811 856 bp = xdr_encode_u32(bp, YFSREMOVEFILE2); 812 857 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 813 - bp = xdr_encode_YFSFid(bp, &dvnode->fid); 814 - bp = xdr_encode_string(bp, name, namesz); 858 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 859 + bp = xdr_encode_name(bp, name); 815 860 yfs_check_req(call, bp); 816 861 817 - afs_use_fs_server(call, fc->cbi); 818 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 819 - afs_set_fc_call(call, fc); 820 - afs_make_call(&fc->ac, call, GFP_NOFS); 821 - return afs_wait_for_call_to_complete(call, &fc->ac); 862 + trace_afs_make_fs_call1(call, &dvp->fid, name); 863 + afs_make_op_call(op, call, GFP_NOFS); 822 864 } 823 865 824 866 /* ··· 815 879 */ 816 880 static int yfs_deliver_fs_remove(struct afs_call *call) 817 881 { 882 + struct afs_operation *op = call->op; 883 + struct afs_vnode_param *dvp = &op->file[0]; 818 884 const __be32 *bp; 819 885 int ret; 820 886 ··· 827 889 return ret; 828 890 829 891 bp = call->buffer; 830 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); 831 - if (ret < 0) 832 - return ret; 833 - 834 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 892 + xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb); 893 + xdr_decode_YFSVolSync(&bp, &op->volsync); 835 894 return 0; 836 895 } 837 896 ··· 842 907 .destructor = afs_flat_call_destructor, 843 908 }; 844 909 910 + /* 911 + * Remove a file. 912 + */ 913 + void yfs_fs_remove_file(struct afs_operation *op) 914 + { 915 + const struct qstr *name = &op->dentry->d_name; 916 + struct afs_vnode_param *dvp = &op->file[0]; 917 + struct afs_call *call; 918 + __be32 *bp; 919 + 920 + _enter(""); 921 + 922 + if (!test_bit(AFS_SERVER_FL_NO_RM2, &op->server->flags)) 923 + return yfs_fs_remove_file2(op); 924 + 925 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile, 926 + sizeof(__be32) + 927 + sizeof(struct yfs_xdr_RPCFlags) + 928 + sizeof(struct yfs_xdr_YFSFid) + 929 + xdr_strlen(name->len), 930 + sizeof(struct yfs_xdr_YFSFetchStatus) + 931 + sizeof(struct yfs_xdr_YFSVolSync)); 932 + if (!call) 933 + return afs_op_nomem(op); 934 + 935 + /* marshall the parameters */ 936 + bp = call->request; 937 + bp = xdr_encode_u32(bp, YFSREMOVEFILE); 938 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 939 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 940 + bp = xdr_encode_name(bp, name); 941 + yfs_check_req(call, bp); 942 + 943 + trace_afs_make_fs_call1(call, &dvp->fid, name); 944 + afs_make_op_call(op, call, GFP_NOFS); 945 + } 946 + 845 947 static const struct afs_call_type yfs_RXYFSRemoveDir = { 846 948 .name = "YFS.RemoveDir", 847 949 .op = yfs_FS_RemoveDir, ··· 887 915 }; 888 916 889 917 /* 890 - * remove a file or directory 918 + * Remove a directory. 891 919 */ 892 - int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 893 - const char *name, bool isdir, 894 - struct afs_status_cb *dvnode_scb) 920 + void yfs_fs_remove_dir(struct afs_operation *op) 895 921 { 896 - struct afs_vnode *dvnode = fc->vnode; 922 + const struct qstr *name = &op->dentry->d_name; 923 + struct afs_vnode_param *dvp = &op->file[0]; 897 924 struct afs_call *call; 898 - struct afs_net *net = afs_v2net(dvnode); 899 - size_t namesz; 900 925 __be32 *bp; 901 926 902 927 _enter(""); 903 928 904 - namesz = strlen(name); 905 - call = afs_alloc_flat_call( 906 - net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile, 907 - sizeof(__be32) + 908 - sizeof(struct yfs_xdr_RPCFlags) + 909 - sizeof(struct yfs_xdr_YFSFid) + 910 - xdr_strlen(namesz), 911 - sizeof(struct yfs_xdr_YFSFetchStatus) + 912 - sizeof(struct yfs_xdr_YFSVolSync)); 929 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveDir, 930 + sizeof(__be32) + 931 + sizeof(struct yfs_xdr_RPCFlags) + 932 + sizeof(struct yfs_xdr_YFSFid) + 933 + xdr_strlen(name->len), 934 + sizeof(struct yfs_xdr_YFSFetchStatus) + 935 + sizeof(struct yfs_xdr_YFSVolSync)); 913 936 if (!call) 914 - return -ENOMEM; 915 - 916 - call->key = fc->key; 917 - call->out_dir_scb = dvnode_scb; 937 + return afs_op_nomem(op); 918 938 919 939 /* marshall the parameters */ 920 940 bp = call->request; 921 - bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE); 941 + bp = xdr_encode_u32(bp, YFSREMOVEDIR); 922 942 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 923 - bp = xdr_encode_YFSFid(bp, &dvnode->fid); 924 - bp = xdr_encode_string(bp, name, namesz); 943 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 944 + bp = xdr_encode_name(bp, name); 925 945 yfs_check_req(call, bp); 926 946 927 - afs_use_fs_server(call, fc->cbi); 928 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 929 - afs_set_fc_call(call, fc); 930 - afs_make_call(&fc->ac, call, GFP_NOFS); 931 - return afs_wait_for_call_to_complete(call, &fc->ac); 947 + trace_afs_make_fs_call1(call, &dvp->fid, name); 948 + afs_make_op_call(op, call, GFP_NOFS); 932 949 } 933 950 934 951 /* ··· 925 964 */ 926 965 static int yfs_deliver_fs_link(struct afs_call *call) 927 966 { 967 + struct afs_operation *op = call->op; 968 + struct afs_vnode_param *dvp = &op->file[0]; 969 + struct afs_vnode_param *vp = &op->file[1]; 928 970 const __be32 *bp; 929 971 int ret; 930 972 ··· 938 974 return ret; 939 975 940 976 bp = call->buffer; 941 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 942 - if (ret < 0) 943 - return ret; 944 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); 945 - if (ret < 0) 946 - return ret; 947 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 977 + xdr_decode_YFSFetchStatus(&bp, call, &vp->scb); 978 + xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb); 979 + xdr_decode_YFSVolSync(&bp, &op->volsync); 948 980 _leave(" = 0 [done]"); 949 981 return 0; 950 982 } ··· 958 998 /* 959 999 * Make a hard link. 960 1000 */ 961 - int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 962 - const char *name, 963 - struct afs_status_cb *dvnode_scb, 964 - struct afs_status_cb *vnode_scb) 1001 + void yfs_fs_link(struct afs_operation *op) 965 1002 { 966 - struct afs_vnode *dvnode = fc->vnode; 1003 + const struct qstr *name = &op->dentry->d_name; 1004 + struct afs_vnode_param *dvp = &op->file[0]; 1005 + struct afs_vnode_param *vp = &op->file[1]; 967 1006 struct afs_call *call; 968 - struct afs_net *net = afs_v2net(vnode); 969 - size_t namesz; 970 1007 __be32 *bp; 971 1008 972 1009 _enter(""); 973 1010 974 - namesz = strlen(name); 975 - call = afs_alloc_flat_call(net, &yfs_RXYFSLink, 1011 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSLink, 976 1012 sizeof(__be32) + 977 1013 sizeof(struct yfs_xdr_RPCFlags) + 978 1014 sizeof(struct yfs_xdr_YFSFid) + 979 - xdr_strlen(namesz) + 1015 + xdr_strlen(name->len) + 980 1016 sizeof(struct yfs_xdr_YFSFid), 981 1017 sizeof(struct yfs_xdr_YFSFetchStatus) + 982 1018 sizeof(struct yfs_xdr_YFSFetchStatus) + 983 1019 sizeof(struct yfs_xdr_YFSVolSync)); 984 1020 if (!call) 985 - return -ENOMEM; 986 - 987 - call->key = fc->key; 988 - call->out_dir_scb = dvnode_scb; 989 - call->out_scb = vnode_scb; 1021 + return afs_op_nomem(op); 990 1022 991 1023 /* marshall the parameters */ 992 1024 bp = call->request; 993 1025 bp = xdr_encode_u32(bp, YFSLINK); 994 1026 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 995 - bp = xdr_encode_YFSFid(bp, &dvnode->fid); 996 - bp = xdr_encode_string(bp, name, namesz); 997 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 1027 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 1028 + bp = xdr_encode_name(bp, name); 1029 + bp = xdr_encode_YFSFid(bp, &vp->fid); 998 1030 yfs_check_req(call, bp); 999 1031 1000 - afs_use_fs_server(call, fc->cbi); 1001 - trace_afs_make_fs_call1(call, &vnode->fid, name); 1002 - afs_set_fc_call(call, fc); 1003 - afs_make_call(&fc->ac, call, GFP_NOFS); 1004 - return afs_wait_for_call_to_complete(call, &fc->ac); 1032 + trace_afs_make_fs_call1(call, &vp->fid, name); 1033 + afs_make_op_call(op, call, GFP_NOFS); 1005 1034 } 1006 1035 1007 1036 /* ··· 998 1049 */ 999 1050 static int yfs_deliver_fs_symlink(struct afs_call *call) 1000 1051 { 1052 + struct afs_operation *op = call->op; 1053 + struct afs_vnode_param *dvp = &op->file[0]; 1054 + struct afs_vnode_param *vp = &op->file[1]; 1001 1055 const __be32 *bp; 1002 1056 int ret; 1003 1057 ··· 1012 1060 1013 1061 /* unmarshall the reply once we've received all of it */ 1014 1062 bp = call->buffer; 1015 - xdr_decode_YFSFid(&bp, call->out_fid); 1016 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 1017 - if (ret < 0) 1018 - return ret; 1019 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); 1020 - if (ret < 0) 1021 - return ret; 1022 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 1063 + xdr_decode_YFSFid(&bp, &vp->fid); 1064 + xdr_decode_YFSFetchStatus(&bp, call, &vp->scb); 1065 + xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb); 1066 + xdr_decode_YFSVolSync(&bp, &op->volsync); 1023 1067 1024 1068 _leave(" = 0 [done]"); 1025 1069 return 0; ··· 1034 1086 /* 1035 1087 * Create a symbolic link. 1036 1088 */ 1037 - int yfs_fs_symlink(struct afs_fs_cursor *fc, 1038 - const char *name, 1039 - const char *contents, 1040 - struct afs_status_cb *dvnode_scb, 1041 - struct afs_fid *newfid, 1042 - struct afs_status_cb *vnode_scb) 1089 + void yfs_fs_symlink(struct afs_operation *op) 1043 1090 { 1044 - struct afs_vnode *dvnode = fc->vnode; 1091 + const struct qstr *name = &op->dentry->d_name; 1092 + struct afs_vnode_param *dvp = &op->file[0]; 1045 1093 struct afs_call *call; 1046 - struct afs_net *net = afs_v2net(dvnode); 1047 - size_t namesz, contents_sz; 1094 + size_t contents_sz; 1048 1095 __be32 *bp; 1049 1096 1050 1097 _enter(""); 1051 1098 1052 - namesz = strlen(name); 1053 - contents_sz = strlen(contents); 1054 - call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink, 1099 + contents_sz = strlen(op->create.symlink); 1100 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSSymlink, 1055 1101 sizeof(__be32) + 1056 1102 sizeof(struct yfs_xdr_RPCFlags) + 1057 1103 sizeof(struct yfs_xdr_YFSFid) + 1058 - xdr_strlen(namesz) + 1104 + xdr_strlen(name->len) + 1059 1105 xdr_strlen(contents_sz) + 1060 1106 sizeof(struct yfs_xdr_YFSStoreStatus), 1061 1107 sizeof(struct yfs_xdr_YFSFid) + ··· 1057 1115 sizeof(struct yfs_xdr_YFSFetchStatus) + 1058 1116 sizeof(struct yfs_xdr_YFSVolSync)); 1059 1117 if (!call) 1060 - return -ENOMEM; 1061 - 1062 - call->key = fc->key; 1063 - call->out_dir_scb = dvnode_scb; 1064 - call->out_fid = newfid; 1065 - call->out_scb = vnode_scb; 1118 + return afs_op_nomem(op); 1066 1119 1067 1120 /* marshall the parameters */ 1068 1121 bp = call->request; 1069 1122 bp = xdr_encode_u32(bp, YFSSYMLINK); 1070 1123 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1071 - bp = xdr_encode_YFSFid(bp, &dvnode->fid); 1072 - bp = xdr_encode_string(bp, name, namesz); 1073 - bp = xdr_encode_string(bp, contents, contents_sz); 1124 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 1125 + bp = xdr_encode_name(bp, name); 1126 + bp = xdr_encode_string(bp, op->create.symlink, contents_sz); 1074 1127 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO); 1075 1128 yfs_check_req(call, bp); 1076 1129 1077 - afs_use_fs_server(call, fc->cbi); 1078 - trace_afs_make_fs_call1(call, &dvnode->fid, name); 1079 - afs_set_fc_call(call, fc); 1080 - afs_make_call(&fc->ac, call, GFP_NOFS); 1081 - return afs_wait_for_call_to_complete(call, &fc->ac); 1130 + trace_afs_make_fs_call1(call, &dvp->fid, name); 1131 + afs_make_op_call(op, call, GFP_NOFS); 1082 1132 } 1083 1133 1084 1134 /* ··· 1078 1144 */ 1079 1145 static int yfs_deliver_fs_rename(struct afs_call *call) 1080 1146 { 1147 + struct afs_operation *op = call->op; 1148 + struct afs_vnode_param *orig_dvp = &op->file[0]; 1149 + struct afs_vnode_param *new_dvp = &op->file[1]; 1081 1150 const __be32 *bp; 1082 1151 int ret; 1083 1152 ··· 1091 1154 return ret; 1092 1155 1093 1156 bp = call->buffer; 1094 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); 1095 - if (ret < 0) 1096 - return ret; 1097 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 1098 - if (ret < 0) 1099 - return ret; 1100 - 1101 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 1157 + /* If the two dirs are the same, we have two copies of the same status 1158 + * report, so we just decode it twice. 1159 + */ 1160 + xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb); 1161 + xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb); 1162 + xdr_decode_YFSVolSync(&bp, &op->volsync); 1102 1163 _leave(" = 0 [done]"); 1103 1164 return 0; 1104 1165 } ··· 1114 1179 /* 1115 1180 * Rename a file or directory. 1116 1181 */ 1117 - int yfs_fs_rename(struct afs_fs_cursor *fc, 1118 - const char *orig_name, 1119 - struct afs_vnode *new_dvnode, 1120 - const char *new_name, 1121 - struct afs_status_cb *orig_dvnode_scb, 1122 - struct afs_status_cb *new_dvnode_scb) 1182 + void yfs_fs_rename(struct afs_operation *op) 1123 1183 { 1124 - struct afs_vnode *orig_dvnode = fc->vnode; 1184 + struct afs_vnode_param *orig_dvp = &op->file[0]; 1185 + struct afs_vnode_param *new_dvp = &op->file[1]; 1186 + const struct qstr *orig_name = &op->dentry->d_name; 1187 + const struct qstr *new_name = &op->dentry_2->d_name; 1125 1188 struct afs_call *call; 1126 - struct afs_net *net = afs_v2net(orig_dvnode); 1127 - size_t o_namesz, n_namesz; 1128 1189 __be32 *bp; 1129 1190 1130 1191 _enter(""); 1131 1192 1132 - o_namesz = strlen(orig_name); 1133 - n_namesz = strlen(new_name); 1134 - call = afs_alloc_flat_call(net, &yfs_RXYFSRename, 1193 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename, 1135 1194 sizeof(__be32) + 1136 1195 sizeof(struct yfs_xdr_RPCFlags) + 1137 1196 sizeof(struct yfs_xdr_YFSFid) + 1138 - xdr_strlen(o_namesz) + 1197 + xdr_strlen(orig_name->len) + 1139 1198 sizeof(struct yfs_xdr_YFSFid) + 1140 - xdr_strlen(n_namesz), 1199 + xdr_strlen(new_name->len), 1141 1200 sizeof(struct yfs_xdr_YFSFetchStatus) + 1142 1201 sizeof(struct yfs_xdr_YFSFetchStatus) + 1143 1202 sizeof(struct yfs_xdr_YFSVolSync)); 1144 1203 if (!call) 1145 - return -ENOMEM; 1146 - 1147 - call->key = fc->key; 1148 - call->out_dir_scb = orig_dvnode_scb; 1149 - call->out_scb = new_dvnode_scb; 1204 + return afs_op_nomem(op); 1150 1205 1151 1206 /* marshall the parameters */ 1152 1207 bp = call->request; 1153 1208 bp = xdr_encode_u32(bp, YFSRENAME); 1154 1209 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1155 - bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid); 1156 - bp = xdr_encode_string(bp, orig_name, o_namesz); 1157 - bp = xdr_encode_YFSFid(bp, &new_dvnode->fid); 1158 - bp = xdr_encode_string(bp, new_name, n_namesz); 1210 + bp = xdr_encode_YFSFid(bp, &orig_dvp->fid); 1211 + bp = xdr_encode_name(bp, orig_name); 1212 + bp = xdr_encode_YFSFid(bp, &new_dvp->fid); 1213 + bp = xdr_encode_name(bp, new_name); 1159 1214 yfs_check_req(call, bp); 1160 1215 1161 - afs_use_fs_server(call, fc->cbi); 1162 - trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name); 1163 - afs_set_fc_call(call, fc); 1164 - afs_make_call(&fc->ac, call, GFP_NOFS); 1165 - return afs_wait_for_call_to_complete(call, &fc->ac); 1216 + trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name); 1217 + afs_make_op_call(op, call, GFP_NOFS); 1166 1218 } 1167 1219 1168 1220 /* ··· 1165 1243 /* 1166 1244 * Store a set of pages to a large file. 1167 1245 */ 1168 - int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, 1169 - pgoff_t first, pgoff_t last, 1170 - unsigned offset, unsigned to, 1171 - struct afs_status_cb *scb) 1246 + void yfs_fs_store_data(struct afs_operation *op) 1172 1247 { 1173 - struct afs_vnode *vnode = fc->vnode; 1248 + struct afs_vnode_param *vp = &op->file[0]; 1174 1249 struct afs_call *call; 1175 - struct afs_net *net = afs_v2net(vnode); 1176 1250 loff_t size, pos, i_size; 1177 1251 __be32 *bp; 1178 1252 1179 1253 _enter(",%x,{%llx:%llu},,", 1180 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1254 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1181 1255 1182 - size = (loff_t)to - (loff_t)offset; 1183 - if (first != last) 1184 - size += (loff_t)(last - first) << PAGE_SHIFT; 1185 - pos = (loff_t)first << PAGE_SHIFT; 1186 - pos += offset; 1256 + size = (loff_t)op->store.last_to - (loff_t)op->store.first_offset; 1257 + if (op->store.first != op->store.last) 1258 + size += (loff_t)(op->store.last - op->store.first) << PAGE_SHIFT; 1259 + pos = (loff_t)op->store.first << PAGE_SHIFT; 1260 + pos += op->store.first_offset; 1187 1261 1188 - i_size = i_size_read(&vnode->vfs_inode); 1262 + i_size = i_size_read(&vp->vnode->vfs_inode); 1189 1263 if (pos + size > i_size) 1190 1264 i_size = size + pos; 1191 1265 ··· 1189 1271 (unsigned long long)size, (unsigned long long)pos, 1190 1272 (unsigned long long)i_size); 1191 1273 1192 - call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64, 1274 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64, 1193 1275 sizeof(__be32) + 1194 1276 sizeof(__be32) + 1195 1277 sizeof(struct yfs_xdr_YFSFid) + ··· 1198 1280 sizeof(struct yfs_xdr_YFSFetchStatus) + 1199 1281 sizeof(struct yfs_xdr_YFSVolSync)); 1200 1282 if (!call) 1201 - return -ENOMEM; 1283 + return afs_op_nomem(op); 1202 1284 1203 - call->key = fc->key; 1204 - call->mapping = mapping; 1205 - call->first = first; 1206 - call->last = last; 1207 - call->first_offset = offset; 1208 - call->last_to = to; 1285 + call->key = op->key; 1209 1286 call->send_pages = true; 1210 - call->out_scb = scb; 1211 1287 1212 1288 /* marshall the parameters */ 1213 1289 bp = call->request; 1214 1290 bp = xdr_encode_u32(bp, YFSSTOREDATA64); 1215 1291 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1216 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 1217 - bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime); 1292 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1293 + bp = xdr_encode_YFSStoreStatus_mtime(bp, &op->mtime); 1218 1294 bp = xdr_encode_u64(bp, pos); 1219 1295 bp = xdr_encode_u64(bp, size); 1220 1296 bp = xdr_encode_u64(bp, i_size); 1221 1297 yfs_check_req(call, bp); 1222 1298 1223 - afs_use_fs_server(call, fc->cbi); 1224 - trace_afs_make_fs_call(call, &vnode->fid); 1225 - afs_set_fc_call(call, fc); 1226 - afs_make_call(&fc->ac, call, GFP_NOFS); 1227 - return afs_wait_for_call_to_complete(call, &fc->ac); 1299 + trace_afs_make_fs_call(call, &vp->fid); 1300 + afs_make_op_call(op, call, GFP_NOFS); 1228 1301 } 1229 1302 1230 1303 /* ··· 1239 1330 * Set the attributes on a file, using YFS.StoreData64 rather than 1240 1331 * YFS.StoreStatus so as to alter the file size also. 1241 1332 */ 1242 - static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr, 1243 - struct afs_status_cb *scb) 1333 + static void yfs_fs_setattr_size(struct afs_operation *op) 1244 1334 { 1245 - struct afs_vnode *vnode = fc->vnode; 1335 + struct afs_vnode_param *vp = &op->file[0]; 1246 1336 struct afs_call *call; 1247 - struct afs_net *net = afs_v2net(vnode); 1337 + struct iattr *attr = op->setattr.attr; 1248 1338 __be32 *bp; 1249 1339 1250 1340 _enter(",%x,{%llx:%llu},,", 1251 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1341 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1252 1342 1253 - call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status, 1343 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64_as_Status, 1254 1344 sizeof(__be32) * 2 + 1255 1345 sizeof(struct yfs_xdr_YFSFid) + 1256 1346 sizeof(struct yfs_xdr_YFSStoreStatus) + ··· 1257 1349 sizeof(struct yfs_xdr_YFSFetchStatus) + 1258 1350 sizeof(struct yfs_xdr_YFSVolSync)); 1259 1351 if (!call) 1260 - return -ENOMEM; 1261 - 1262 - call->key = fc->key; 1263 - call->out_scb = scb; 1352 + return afs_op_nomem(op); 1264 1353 1265 1354 /* marshall the parameters */ 1266 1355 bp = call->request; 1267 1356 bp = xdr_encode_u32(bp, YFSSTOREDATA64); 1268 1357 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1269 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 1358 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1270 1359 bp = xdr_encode_YFS_StoreStatus(bp, attr); 1271 1360 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */ 1272 1361 bp = xdr_encode_u64(bp, 0); /* size of write */ 1273 1362 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */ 1274 1363 yfs_check_req(call, bp); 1275 1364 1276 - afs_use_fs_server(call, fc->cbi); 1277 - trace_afs_make_fs_call(call, &vnode->fid); 1278 - afs_set_fc_call(call, fc); 1279 - afs_make_call(&fc->ac, call, GFP_NOFS); 1280 - return afs_wait_for_call_to_complete(call, &fc->ac); 1365 + trace_afs_make_fs_call(call, &vp->fid); 1366 + afs_make_op_call(op, call, GFP_NOFS); 1281 1367 } 1282 1368 1283 1369 /* 1284 1370 * Set the attributes on a file, using YFS.StoreData64 if there's a change in 1285 1371 * file size, and YFS.StoreStatus otherwise. 1286 1372 */ 1287 - int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr, 1288 - struct afs_status_cb *scb) 1373 + void yfs_fs_setattr(struct afs_operation *op) 1289 1374 { 1290 - struct afs_vnode *vnode = fc->vnode; 1375 + struct afs_vnode_param *vp = &op->file[0]; 1291 1376 struct afs_call *call; 1292 - struct afs_net *net = afs_v2net(vnode); 1377 + struct iattr *attr = op->setattr.attr; 1293 1378 __be32 *bp; 1294 1379 1295 1380 if (attr->ia_valid & ATTR_SIZE) 1296 - return yfs_fs_setattr_size(fc, attr, scb); 1381 + return yfs_fs_setattr_size(op); 1297 1382 1298 1383 _enter(",%x,{%llx:%llu},,", 1299 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1384 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1300 1385 1301 - call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus, 1386 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreStatus, 1302 1387 sizeof(__be32) * 2 + 1303 1388 sizeof(struct yfs_xdr_YFSFid) + 1304 1389 sizeof(struct yfs_xdr_YFSStoreStatus), 1305 1390 sizeof(struct yfs_xdr_YFSFetchStatus) + 1306 1391 sizeof(struct yfs_xdr_YFSVolSync)); 1307 1392 if (!call) 1308 - return -ENOMEM; 1309 - 1310 - call->key = fc->key; 1311 - call->out_scb = scb; 1393 + return afs_op_nomem(op); 1312 1394 1313 1395 /* marshall the parameters */ 1314 1396 bp = call->request; 1315 1397 bp = xdr_encode_u32(bp, YFSSTORESTATUS); 1316 1398 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1317 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 1399 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1318 1400 bp = xdr_encode_YFS_StoreStatus(bp, attr); 1319 1401 yfs_check_req(call, bp); 1320 1402 1321 - afs_use_fs_server(call, fc->cbi); 1322 - trace_afs_make_fs_call(call, &vnode->fid); 1323 - afs_set_fc_call(call, fc); 1324 - afs_make_call(&fc->ac, call, GFP_NOFS); 1325 - return afs_wait_for_call_to_complete(call, &fc->ac); 1403 + trace_afs_make_fs_call(call, &vp->fid); 1404 + afs_make_op_call(op, call, GFP_NOFS); 1326 1405 } 1327 1406 1328 1407 /* ··· 1317 1422 */ 1318 1423 static int yfs_deliver_fs_get_volume_status(struct afs_call *call) 1319 1424 { 1425 + struct afs_operation *op = call->op; 1320 1426 const __be32 *bp; 1321 1427 char *p; 1322 1428 u32 size; ··· 1339 1443 return ret; 1340 1444 1341 1445 bp = call->buffer; 1342 - xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus); 1446 + xdr_decode_YFSFetchVolumeStatus(&bp, &op->volstatus.vs); 1343 1447 call->unmarshall++; 1344 1448 afs_extract_to_tmp(call); 1345 1449 /* Fall through */ ··· 1353 1457 call->count = ntohl(call->tmp); 1354 1458 _debug("volname length: %u", call->count); 1355 1459 if (call->count >= AFSNAMEMAX) 1356 - return afs_protocol_error(call, -EBADMSG, 1357 - afs_eproto_volname_len); 1460 + return afs_protocol_error(call, afs_eproto_volname_len); 1358 1461 size = (call->count + 3) & ~3; /* It's padded */ 1359 1462 afs_extract_to_buf(call, size); 1360 1463 call->unmarshall++; ··· 1382 1487 call->count = ntohl(call->tmp); 1383 1488 _debug("offline msg length: %u", call->count); 1384 1489 if (call->count >= AFSNAMEMAX) 1385 - return afs_protocol_error(call, -EBADMSG, 1386 - afs_eproto_offline_msg_len); 1490 + return afs_protocol_error(call, afs_eproto_offline_msg_len); 1387 1491 size = (call->count + 3) & ~3; /* It's padded */ 1388 1492 afs_extract_to_buf(call, size); 1389 1493 call->unmarshall++; ··· 1412 1518 call->count = ntohl(call->tmp); 1413 1519 _debug("motd length: %u", call->count); 1414 1520 if (call->count >= AFSNAMEMAX) 1415 - return afs_protocol_error(call, -EBADMSG, 1416 - afs_eproto_motd_len); 1521 + return afs_protocol_error(call, afs_eproto_motd_len); 1417 1522 size = (call->count + 3) & ~3; /* It's padded */ 1418 1523 afs_extract_to_buf(call, size); 1419 1524 call->unmarshall++; ··· 1453 1560 /* 1454 1561 * fetch the status of a volume 1455 1562 */ 1456 - int yfs_fs_get_volume_status(struct afs_fs_cursor *fc, 1457 - struct afs_volume_status *vs) 1563 + void yfs_fs_get_volume_status(struct afs_operation *op) 1458 1564 { 1459 - struct afs_vnode *vnode = fc->vnode; 1565 + struct afs_vnode_param *vp = &op->file[0]; 1460 1566 struct afs_call *call; 1461 - struct afs_net *net = afs_v2net(vnode); 1462 1567 __be32 *bp; 1463 1568 1464 1569 _enter(""); 1465 1570 1466 - call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus, 1571 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSGetVolumeStatus, 1467 1572 sizeof(__be32) * 2 + 1468 1573 sizeof(struct yfs_xdr_u64), 1469 1574 max_t(size_t, ··· 1469 1578 sizeof(__be32), 1470 1579 AFSOPAQUEMAX + 1)); 1471 1580 if (!call) 1472 - return -ENOMEM; 1473 - 1474 - call->key = fc->key; 1475 - call->out_volstatus = vs; 1581 + return afs_op_nomem(op); 1476 1582 1477 1583 /* marshall the parameters */ 1478 1584 bp = call->request; 1479 1585 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS); 1480 1586 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1481 - bp = xdr_encode_u64(bp, vnode->fid.vid); 1587 + bp = xdr_encode_u64(bp, vp->fid.vid); 1482 1588 yfs_check_req(call, bp); 1483 1589 1484 - afs_use_fs_server(call, fc->cbi); 1485 - trace_afs_make_fs_call(call, &vnode->fid); 1486 - afs_set_fc_call(call, fc); 1487 - afs_make_call(&fc->ac, call, GFP_NOFS); 1488 - return afs_wait_for_call_to_complete(call, &fc->ac); 1590 + trace_afs_make_fs_call(call, &vp->fid); 1591 + afs_make_op_call(op, call, GFP_NOFS); 1489 1592 } 1490 1593 1491 1594 /* ··· 1517 1632 /* 1518 1633 * Set a lock on a file 1519 1634 */ 1520 - int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type, 1521 - struct afs_status_cb *scb) 1635 + void yfs_fs_set_lock(struct afs_operation *op) 1522 1636 { 1523 - struct afs_vnode *vnode = fc->vnode; 1637 + struct afs_vnode_param *vp = &op->file[0]; 1524 1638 struct afs_call *call; 1525 - struct afs_net *net = afs_v2net(vnode); 1526 1639 __be32 *bp; 1527 1640 1528 1641 _enter(""); 1529 1642 1530 - call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock, 1643 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSSetLock, 1531 1644 sizeof(__be32) * 2 + 1532 1645 sizeof(struct yfs_xdr_YFSFid) + 1533 1646 sizeof(__be32), 1534 1647 sizeof(struct yfs_xdr_YFSFetchStatus) + 1535 1648 sizeof(struct yfs_xdr_YFSVolSync)); 1536 1649 if (!call) 1537 - return -ENOMEM; 1538 - 1539 - call->key = fc->key; 1540 - call->lvnode = vnode; 1541 - call->out_scb = scb; 1650 + return afs_op_nomem(op); 1542 1651 1543 1652 /* marshall the parameters */ 1544 1653 bp = call->request; 1545 1654 bp = xdr_encode_u32(bp, YFSSETLOCK); 1546 1655 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1547 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 1548 - bp = xdr_encode_u32(bp, type); 1656 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1657 + bp = xdr_encode_u32(bp, op->lock.type); 1549 1658 yfs_check_req(call, bp); 1550 1659 1551 - afs_use_fs_server(call, fc->cbi); 1552 - trace_afs_make_fs_calli(call, &vnode->fid, type); 1553 - afs_set_fc_call(call, fc); 1554 - afs_make_call(&fc->ac, call, GFP_NOFS); 1555 - return afs_wait_for_call_to_complete(call, &fc->ac); 1660 + trace_afs_make_fs_calli(call, &vp->fid, op->lock.type); 1661 + afs_make_op_call(op, call, GFP_NOFS); 1556 1662 } 1557 1663 1558 1664 /* 1559 1665 * extend a lock on a file 1560 1666 */ 1561 - int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb) 1667 + void yfs_fs_extend_lock(struct afs_operation *op) 1562 1668 { 1563 - struct afs_vnode *vnode = fc->vnode; 1669 + struct afs_vnode_param *vp = &op->file[0]; 1564 1670 struct afs_call *call; 1565 - struct afs_net *net = afs_v2net(vnode); 1566 1671 __be32 *bp; 1567 1672 1568 1673 _enter(""); 1569 1674 1570 - call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock, 1675 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSExtendLock, 1571 1676 sizeof(__be32) * 2 + 1572 1677 sizeof(struct yfs_xdr_YFSFid), 1573 1678 sizeof(struct yfs_xdr_YFSFetchStatus) + 1574 1679 sizeof(struct yfs_xdr_YFSVolSync)); 1575 1680 if (!call) 1576 - return -ENOMEM; 1577 - 1578 - call->key = fc->key; 1579 - call->lvnode = vnode; 1580 - call->out_scb = scb; 1681 + return afs_op_nomem(op); 1581 1682 1582 1683 /* marshall the parameters */ 1583 1684 bp = call->request; 1584 1685 bp = xdr_encode_u32(bp, YFSEXTENDLOCK); 1585 1686 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1586 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 1687 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1587 1688 yfs_check_req(call, bp); 1588 1689 1589 - afs_use_fs_server(call, fc->cbi); 1590 - trace_afs_make_fs_call(call, &vnode->fid); 1591 - afs_set_fc_call(call, fc); 1592 - afs_make_call(&fc->ac, call, GFP_NOFS); 1593 - return afs_wait_for_call_to_complete(call, &fc->ac); 1690 + trace_afs_make_fs_call(call, &vp->fid); 1691 + afs_make_op_call(op, call, GFP_NOFS); 1594 1692 } 1595 1693 1596 1694 /* 1597 1695 * release a lock on a file 1598 1696 */ 1599 - int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb) 1697 + void yfs_fs_release_lock(struct afs_operation *op) 1600 1698 { 1601 - struct afs_vnode *vnode = fc->vnode; 1699 + struct afs_vnode_param *vp = &op->file[0]; 1602 1700 struct afs_call *call; 1603 - struct afs_net *net = afs_v2net(vnode); 1604 1701 __be32 *bp; 1605 1702 1606 1703 _enter(""); 1607 1704 1608 - call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock, 1705 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSReleaseLock, 1609 1706 sizeof(__be32) * 2 + 1610 1707 sizeof(struct yfs_xdr_YFSFid), 1611 1708 sizeof(struct yfs_xdr_YFSFetchStatus) + 1612 1709 sizeof(struct yfs_xdr_YFSVolSync)); 1613 1710 if (!call) 1614 - return -ENOMEM; 1615 - 1616 - call->key = fc->key; 1617 - call->lvnode = vnode; 1618 - call->out_scb = scb; 1711 + return afs_op_nomem(op); 1619 1712 1620 1713 /* marshall the parameters */ 1621 1714 bp = call->request; 1622 1715 bp = xdr_encode_u32(bp, YFSRELEASELOCK); 1623 1716 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1624 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 1717 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1625 1718 yfs_check_req(call, bp); 1626 1719 1627 - afs_use_fs_server(call, fc->cbi); 1628 - trace_afs_make_fs_call(call, &vnode->fid); 1629 - afs_set_fc_call(call, fc); 1630 - afs_make_call(&fc->ac, call, GFP_NOFS); 1631 - return afs_wait_for_call_to_complete(call, &fc->ac); 1720 + trace_afs_make_fs_call(call, &vp->fid); 1721 + afs_make_op_call(op, call, GFP_NOFS); 1632 1722 } 1633 1723 1634 1724 /* ··· 1619 1759 /* 1620 1760 * Fetch the status information for a fid without needing a vnode handle. 1621 1761 */ 1622 - int yfs_fs_fetch_status(struct afs_fs_cursor *fc, 1623 - struct afs_net *net, 1624 - struct afs_fid *fid, 1625 - struct afs_status_cb *scb, 1626 - struct afs_volsync *volsync) 1762 + void yfs_fs_fetch_status(struct afs_operation *op) 1627 1763 { 1764 + struct afs_vnode_param *vp = &op->file[0]; 1628 1765 struct afs_call *call; 1629 1766 __be32 *bp; 1630 1767 1631 1768 _enter(",%x,{%llx:%llu},,", 1632 - key_serial(fc->key), fid->vid, fid->vnode); 1769 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1633 1770 1634 - call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus, 1771 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus, 1635 1772 sizeof(__be32) * 2 + 1636 1773 sizeof(struct yfs_xdr_YFSFid), 1637 1774 sizeof(struct yfs_xdr_YFSFetchStatus) + 1638 1775 sizeof(struct yfs_xdr_YFSCallBack) + 1639 1776 sizeof(struct yfs_xdr_YFSVolSync)); 1640 - if (!call) { 1641 - fc->ac.error = -ENOMEM; 1642 - return -ENOMEM; 1643 - } 1644 - 1645 - call->key = fc->key; 1646 - call->out_scb = scb; 1647 - call->out_volsync = volsync; 1777 + if (!call) 1778 + return afs_op_nomem(op); 1648 1779 1649 1780 /* marshall the parameters */ 1650 1781 bp = call->request; 1651 1782 bp = xdr_encode_u32(bp, YFSFETCHSTATUS); 1652 1783 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1653 - bp = xdr_encode_YFSFid(bp, fid); 1784 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1654 1785 yfs_check_req(call, bp); 1655 1786 1656 - afs_use_fs_server(call, fc->cbi); 1657 - trace_afs_make_fs_call(call, fid); 1658 - afs_set_fc_call(call, fc); 1659 - afs_make_call(&fc->ac, call, GFP_NOFS); 1660 - return afs_wait_for_call_to_complete(call, &fc->ac); 1787 + trace_afs_make_fs_call(call, &vp->fid); 1788 + afs_make_op_call(op, call, GFP_NOFS); 1661 1789 } 1662 1790 1663 1791 /* ··· 1653 1805 */ 1654 1806 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) 1655 1807 { 1808 + struct afs_operation *op = call->op; 1656 1809 struct afs_status_cb *scb; 1657 1810 const __be32 *bp; 1658 1811 u32 tmp; ··· 1675 1826 return ret; 1676 1827 1677 1828 tmp = ntohl(call->tmp); 1678 - _debug("status count: %u/%u", tmp, call->count2); 1679 - if (tmp != call->count2) 1680 - return afs_protocol_error(call, -EBADMSG, 1681 - afs_eproto_ibulkst_count); 1829 + _debug("status count: %u/%u", tmp, op->nr_files); 1830 + if (tmp != op->nr_files) 1831 + return afs_protocol_error(call, afs_eproto_ibulkst_count); 1682 1832 1683 1833 call->count = 0; 1684 1834 call->unmarshall++; ··· 1691 1843 if (ret < 0) 1692 1844 return ret; 1693 1845 1846 + switch (call->count) { 1847 + case 0: 1848 + scb = &op->file[0].scb; 1849 + break; 1850 + case 1: 1851 + scb = &op->file[1].scb; 1852 + break; 1853 + default: 1854 + scb = &op->more_files[call->count - 2].scb; 1855 + break; 1856 + } 1857 + 1694 1858 bp = call->buffer; 1695 - scb = &call->out_scb[call->count]; 1696 - ret = xdr_decode_YFSFetchStatus(&bp, call, scb); 1697 - if (ret < 0) 1698 - return ret; 1859 + xdr_decode_YFSFetchStatus(&bp, call, scb); 1699 1860 1700 1861 call->count++; 1701 - if (call->count < call->count2) 1862 + if (call->count < op->nr_files) 1702 1863 goto more_counts; 1703 1864 1704 1865 call->count = 0; ··· 1724 1867 1725 1868 tmp = ntohl(call->tmp); 1726 1869 _debug("CB count: %u", tmp); 1727 - if (tmp != call->count2) 1728 - return afs_protocol_error(call, -EBADMSG, 1729 - afs_eproto_ibulkst_cb_count); 1870 + if (tmp != op->nr_files) 1871 + return afs_protocol_error(call, afs_eproto_ibulkst_cb_count); 1730 1872 call->count = 0; 1731 1873 call->unmarshall++; 1732 1874 more_cbs: ··· 1739 1883 return ret; 1740 1884 1741 1885 _debug("unmarshall CB array"); 1886 + switch (call->count) { 1887 + case 0: 1888 + scb = &op->file[0].scb; 1889 + break; 1890 + case 1: 1891 + scb = &op->file[1].scb; 1892 + break; 1893 + default: 1894 + scb = &op->more_files[call->count - 2].scb; 1895 + break; 1896 + } 1897 + 1742 1898 bp = call->buffer; 1743 - scb = &call->out_scb[call->count]; 1744 1899 xdr_decode_YFSCallBack(&bp, call, scb); 1745 1900 call->count++; 1746 - if (call->count < call->count2) 1901 + if (call->count < op->nr_files) 1747 1902 goto more_cbs; 1748 1903 1749 1904 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync)); ··· 1767 1900 return ret; 1768 1901 1769 1902 bp = call->buffer; 1770 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 1903 + xdr_decode_YFSVolSync(&bp, &op->volsync); 1771 1904 1772 1905 call->unmarshall++; 1773 1906 /* Fall through */ ··· 1793 1926 /* 1794 1927 * Fetch the status information for up to 1024 files 1795 1928 */ 1796 - int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc, 1797 - struct afs_net *net, 1798 - struct afs_fid *fids, 1799 - struct afs_status_cb *statuses, 1800 - unsigned int nr_fids, 1801 - struct afs_volsync *volsync) 1929 + void yfs_fs_inline_bulk_status(struct afs_operation *op) 1802 1930 { 1931 + struct afs_vnode_param *dvp = &op->file[0]; 1932 + struct afs_vnode_param *vp = &op->file[1]; 1803 1933 struct afs_call *call; 1804 1934 __be32 *bp; 1805 1935 int i; 1806 1936 1807 1937 _enter(",%x,{%llx:%llu},%u", 1808 - key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids); 1938 + key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files); 1809 1939 1810 - call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus, 1940 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSInlineBulkStatus, 1811 1941 sizeof(__be32) + 1812 1942 sizeof(__be32) + 1813 1943 sizeof(__be32) + 1814 - sizeof(struct yfs_xdr_YFSFid) * nr_fids, 1944 + sizeof(struct yfs_xdr_YFSFid) * op->nr_files, 1815 1945 sizeof(struct yfs_xdr_YFSFetchStatus)); 1816 - if (!call) { 1817 - fc->ac.error = -ENOMEM; 1818 - return -ENOMEM; 1819 - } 1820 - 1821 - call->key = fc->key; 1822 - call->out_scb = statuses; 1823 - call->out_volsync = volsync; 1824 - call->count2 = nr_fids; 1946 + if (!call) 1947 + return afs_op_nomem(op); 1825 1948 1826 1949 /* marshall the parameters */ 1827 1950 bp = call->request; 1828 1951 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS); 1829 1952 bp = xdr_encode_u32(bp, 0); /* RPCFlags */ 1830 - bp = xdr_encode_u32(bp, nr_fids); 1831 - for (i = 0; i < nr_fids; i++) 1832 - bp = xdr_encode_YFSFid(bp, &fids[i]); 1953 + bp = xdr_encode_u32(bp, op->nr_files); 1954 + bp = xdr_encode_YFSFid(bp, &dvp->fid); 1955 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1956 + for (i = 0; i < op->nr_files - 2; i++) 1957 + bp = xdr_encode_YFSFid(bp, &op->more_files[i].fid); 1833 1958 yfs_check_req(call, bp); 1834 1959 1835 - afs_use_fs_server(call, fc->cbi); 1836 - trace_afs_make_fs_call(call, &fids[0]); 1837 - afs_set_fc_call(call, fc); 1838 - afs_make_call(&fc->ac, call, GFP_NOFS); 1839 - return afs_wait_for_call_to_complete(call, &fc->ac); 1960 + trace_afs_make_fs_call(call, &vp->fid); 1961 + afs_make_op_call(op, call, GFP_NOFS); 1840 1962 } 1841 1963 1842 1964 /* ··· 1833 1977 */ 1834 1978 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call) 1835 1979 { 1836 - struct yfs_acl *yacl = call->out_yacl; 1980 + struct afs_operation *op = call->op; 1981 + struct afs_vnode_param *vp = &op->file[0]; 1982 + struct yfs_acl *yacl = op->yacl; 1837 1983 struct afs_acl *acl; 1838 1984 const __be32 *bp; 1839 1985 unsigned int size; ··· 1925 2067 bp = call->buffer; 1926 2068 yacl->inherit_flag = ntohl(*bp++); 1927 2069 yacl->num_cleaned = ntohl(*bp++); 1928 - ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); 1929 - if (ret < 0) 1930 - return ret; 1931 - xdr_decode_YFSVolSync(&bp, call->out_volsync); 2070 + xdr_decode_YFSFetchStatus(&bp, call, &vp->scb); 2071 + xdr_decode_YFSVolSync(&bp, &op->volsync); 1932 2072 1933 2073 call->unmarshall++; 1934 2074 /* Fall through */ ··· 1961 2105 /* 1962 2106 * Fetch the YFS advanced ACLs for a file. 1963 2107 */ 1964 - struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc, 1965 - struct yfs_acl *yacl, 1966 - struct afs_status_cb *scb) 2108 + void yfs_fs_fetch_opaque_acl(struct afs_operation *op) 1967 2109 { 1968 - struct afs_vnode *vnode = fc->vnode; 2110 + struct afs_vnode_param *vp = &op->file[0]; 1969 2111 struct afs_call *call; 1970 - struct afs_net *net = afs_v2net(vnode); 1971 2112 __be32 *bp; 1972 2113 1973 2114 _enter(",%x,{%llx:%llu},,", 1974 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 2115 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 1975 2116 1976 - call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL, 2117 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchOpaqueACL, 1977 2118 sizeof(__be32) * 2 + 1978 2119 sizeof(struct yfs_xdr_YFSFid), 1979 2120 sizeof(__be32) * 2 + 1980 2121 sizeof(struct yfs_xdr_YFSFetchStatus) + 1981 2122 sizeof(struct yfs_xdr_YFSVolSync)); 1982 - if (!call) { 1983 - fc->ac.error = -ENOMEM; 1984 - return ERR_PTR(-ENOMEM); 1985 - } 1986 - 1987 - call->key = fc->key; 1988 - call->out_yacl = yacl; 1989 - call->out_scb = scb; 1990 - call->out_volsync = NULL; 2123 + if (!call) 2124 + return afs_op_nomem(op); 1991 2125 1992 2126 /* marshall the parameters */ 1993 2127 bp = call->request; 1994 2128 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL); 1995 2129 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1996 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 2130 + bp = xdr_encode_YFSFid(bp, &vp->fid); 1997 2131 yfs_check_req(call, bp); 1998 2132 1999 - afs_use_fs_server(call, fc->cbi); 2000 - trace_afs_make_fs_call(call, &vnode->fid); 2001 - afs_make_call(&fc->ac, call, GFP_KERNEL); 2002 - return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac); 2133 + trace_afs_make_fs_call(call, &vp->fid); 2134 + afs_make_op_call(op, call, GFP_KERNEL); 2003 2135 } 2004 2136 2005 2137 /* ··· 2003 2159 /* 2004 2160 * Fetch the YFS ACL for a file. 2005 2161 */ 2006 - int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl, 2007 - struct afs_status_cb *scb) 2162 + void yfs_fs_store_opaque_acl2(struct afs_operation *op) 2008 2163 { 2009 - struct afs_vnode *vnode = fc->vnode; 2164 + struct afs_vnode_param *vp = &op->file[0]; 2010 2165 struct afs_call *call; 2011 - struct afs_net *net = afs_v2net(vnode); 2166 + struct afs_acl *acl = op->acl; 2012 2167 size_t size; 2013 2168 __be32 *bp; 2014 2169 2015 2170 _enter(",%x,{%llx:%llu},,", 2016 - key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 2171 + key_serial(op->key), vp->fid.vid, vp->fid.vnode); 2017 2172 2018 2173 size = round_up(acl->size, 4); 2019 - call = afs_alloc_flat_call(net, &yfs_RXYFSStoreOpaqueACL2, 2174 + call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreOpaqueACL2, 2020 2175 sizeof(__be32) * 2 + 2021 2176 sizeof(struct yfs_xdr_YFSFid) + 2022 2177 sizeof(__be32) + size, 2023 2178 sizeof(struct yfs_xdr_YFSFetchStatus) + 2024 2179 sizeof(struct yfs_xdr_YFSVolSync)); 2025 - if (!call) { 2026 - fc->ac.error = -ENOMEM; 2027 - return -ENOMEM; 2028 - } 2029 - 2030 - call->key = fc->key; 2031 - call->out_scb = scb; 2032 - call->out_volsync = NULL; 2180 + if (!call) 2181 + return afs_op_nomem(op); 2033 2182 2034 2183 /* marshall the parameters */ 2035 2184 bp = call->request; 2036 2185 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2); 2037 2186 bp = xdr_encode_u32(bp, 0); /* RPC flags */ 2038 - bp = xdr_encode_YFSFid(bp, &vnode->fid); 2187 + bp = xdr_encode_YFSFid(bp, &vp->fid); 2039 2188 bp = xdr_encode_u32(bp, acl->size); 2040 2189 memcpy(bp, acl->data, acl->size); 2041 2190 if (acl->size != size) 2042 2191 memset((void *)bp + acl->size, 0, size - acl->size); 2043 2192 yfs_check_req(call, bp); 2044 2193 2045 - trace_afs_make_fs_call(call, &vnode->fid); 2046 - afs_make_call(&fc->ac, call, GFP_KERNEL); 2047 - return afs_wait_for_call_to_complete(call, &fc->ac); 2194 + trace_afs_make_fs_call(call, &vp->fid); 2195 + afs_make_op_call(op, call, GFP_KERNEL); 2048 2196 }
+22 -22
fs/ext4/inode.c
··· 4865 4865 return 0; 4866 4866 } 4867 4867 4868 - struct other_inode { 4869 - unsigned long orig_ino; 4870 - struct ext4_inode *raw_inode; 4871 - }; 4872 - 4873 - static int other_inode_match(struct inode * inode, unsigned long ino, 4874 - void *data) 4868 + static void __ext4_update_other_inode_time(struct super_block *sb, 4869 + unsigned long orig_ino, 4870 + unsigned long ino, 4871 + struct ext4_inode *raw_inode) 4875 4872 { 4876 - struct other_inode *oi = (struct other_inode *) data; 4873 + struct inode *inode; 4877 4874 4878 - if ((inode->i_ino != ino) || 4879 - (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW | 4875 + inode = find_inode_by_ino_rcu(sb, ino); 4876 + if (!inode) 4877 + return; 4878 + 4879 + if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW | 4880 4880 I_DIRTY_INODE)) || 4881 4881 ((inode->i_state & I_DIRTY_TIME) == 0)) 4882 - return 0; 4882 + return; 4883 + 4883 4884 spin_lock(&inode->i_lock); 4884 4885 if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW | 4885 4886 I_DIRTY_INODE)) == 0) && ··· 4891 4890 spin_unlock(&inode->i_lock); 4892 4891 4893 4892 spin_lock(&ei->i_raw_lock); 4894 - EXT4_INODE_SET_XTIME(i_ctime, inode, oi->raw_inode); 4895 - EXT4_INODE_SET_XTIME(i_mtime, inode, oi->raw_inode); 4896 - EXT4_INODE_SET_XTIME(i_atime, inode, oi->raw_inode); 4897 - ext4_inode_csum_set(inode, oi->raw_inode, ei); 4893 + EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode); 4894 + EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); 4895 + EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); 4896 + ext4_inode_csum_set(inode, raw_inode, ei); 4898 4897 spin_unlock(&ei->i_raw_lock); 4899 - trace_ext4_other_inode_update_time(inode, oi->orig_ino); 4900 - return -1; 4898 + trace_ext4_other_inode_update_time(inode, orig_ino); 4899 + return; 4901 4900 } 4902 4901 spin_unlock(&inode->i_lock); 4903 - return -1; 4904 4902 } 4905 4903 4906 4904 /* ··· 4909 4909 static void ext4_update_other_inodes_time(struct super_block *sb, 4910 4910 unsigned long orig_ino, char *buf) 4911 4911 { 4912 - struct other_inode oi; 4913 4912 unsigned long ino; 4914 4913 int i, inodes_per_block = EXT4_SB(sb)->s_inodes_per_block; 4915 4914 int inode_size = EXT4_INODE_SIZE(sb); 4916 4915 4917 - oi.orig_ino = orig_ino; 4918 4916 /* 4919 4917 * Calculate the first inode in the inode table block. Inode 4920 4918 * numbers are one-based. That is, the first inode in a block 4921 4919 * (assuming 4k blocks and 256 byte inodes) is (n*16 + 1). 4922 4920 */ 4923 4921 ino = ((orig_ino - 1) & ~(inodes_per_block - 1)) + 1; 4922 + rcu_read_lock(); 4924 4923 for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) { 4925 4924 if (ino == orig_ino) 4926 4925 continue; 4927 - oi.raw_inode = (struct ext4_inode *) buf; 4928 - (void) find_inode_nowait(sb, ino, other_inode_match, &oi); 4926 + __ext4_update_other_inode_time(sb, orig_ino, ino, 4927 + (struct ext4_inode *)buf); 4929 4928 } 4929 + rcu_read_unlock(); 4930 4930 } 4931 4931 4932 4932 /*
+96 -16
fs/inode.c
··· 497 497 498 498 spin_lock(&inode_hash_lock); 499 499 spin_lock(&inode->i_lock); 500 - hlist_add_head(&inode->i_hash, b); 500 + hlist_add_head_rcu(&inode->i_hash, b); 501 501 spin_unlock(&inode->i_lock); 502 502 spin_unlock(&inode_hash_lock); 503 503 } ··· 513 513 { 514 514 spin_lock(&inode_hash_lock); 515 515 spin_lock(&inode->i_lock); 516 - hlist_del_init(&inode->i_hash); 516 + hlist_del_init_rcu(&inode->i_hash); 517 517 spin_unlock(&inode->i_lock); 518 518 spin_unlock(&inode_hash_lock); 519 519 } ··· 1107 1107 */ 1108 1108 spin_lock(&inode->i_lock); 1109 1109 inode->i_state |= I_NEW; 1110 - hlist_add_head(&inode->i_hash, head); 1110 + hlist_add_head_rcu(&inode->i_hash, head); 1111 1111 spin_unlock(&inode->i_lock); 1112 1112 if (!creating) 1113 1113 inode_sb_list_add(inode); ··· 1201 1201 inode->i_ino = ino; 1202 1202 spin_lock(&inode->i_lock); 1203 1203 inode->i_state = I_NEW; 1204 - hlist_add_head(&inode->i_hash, head); 1204 + hlist_add_head_rcu(&inode->i_hash, head); 1205 1205 spin_unlock(&inode->i_lock); 1206 1206 inode_sb_list_add(inode); 1207 1207 spin_unlock(&inode_hash_lock); ··· 1244 1244 struct hlist_head *b = inode_hashtable + hash(sb, ino); 1245 1245 struct inode *inode; 1246 1246 1247 - spin_lock(&inode_hash_lock); 1248 - hlist_for_each_entry(inode, b, i_hash) { 1249 - if (inode->i_ino == ino && inode->i_sb == sb) { 1250 - spin_unlock(&inode_hash_lock); 1247 + hlist_for_each_entry_rcu(inode, b, i_hash) { 1248 + if (inode->i_ino == ino && inode->i_sb == sb) 1251 1249 return 0; 1252 - } 1253 1250 } 1254 - spin_unlock(&inode_hash_lock); 1255 - 1256 1251 return 1; 1257 1252 } 1258 1253 ··· 1276 1281 static unsigned int counter; 1277 1282 ino_t res; 1278 1283 1284 + rcu_read_lock(); 1279 1285 spin_lock(&iunique_lock); 1280 1286 do { 1281 1287 if (counter <= max_reserved) ··· 1284 1288 res = counter++; 1285 1289 } while (!test_inode_iunique(sb, res)); 1286 1290 spin_unlock(&iunique_lock); 1291 + rcu_read_unlock(); 1287 1292 1288 1293 return res; 1289 1294 } ··· 1453 1456 } 1454 1457 EXPORT_SYMBOL(find_inode_nowait); 1455 1458 1459 + /** 1460 + * find_inode_rcu - find an inode in the inode cache 1461 + * @sb: Super block of file system to search 1462 + * @hashval: Key to hash 1463 + * @test: Function to test match on an inode 1464 + * @data: Data for test function 1465 + * 1466 + * Search for the inode specified by @hashval and @data in the inode cache, 1467 + * where the helper function @test will return 0 if the inode does not match 1468 + * and 1 if it does. The @test function must be responsible for taking the 1469 + * i_lock spin_lock and checking i_state for an inode being freed or being 1470 + * initialized. 1471 + * 1472 + * If successful, this will return the inode for which the @test function 1473 + * returned 1 and NULL otherwise. 1474 + * 1475 + * The @test function is not permitted to take a ref on any inode presented. 1476 + * It is also not permitted to sleep. 1477 + * 1478 + * The caller must hold the RCU read lock. 1479 + */ 1480 + struct inode *find_inode_rcu(struct super_block *sb, unsigned long hashval, 1481 + int (*test)(struct inode *, void *), void *data) 1482 + { 1483 + struct hlist_head *head = inode_hashtable + hash(sb, hashval); 1484 + struct inode *inode; 1485 + 1486 + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), 1487 + "suspicious find_inode_rcu() usage"); 1488 + 1489 + hlist_for_each_entry_rcu(inode, head, i_hash) { 1490 + if (inode->i_sb == sb && 1491 + !(READ_ONCE(inode->i_state) & (I_FREEING | I_WILL_FREE)) && 1492 + test(inode, data)) 1493 + return inode; 1494 + } 1495 + return NULL; 1496 + } 1497 + EXPORT_SYMBOL(find_inode_rcu); 1498 + 1499 + /** 1500 + * find_inode_by_rcu - Find an inode in the inode cache 1501 + * @sb: Super block of file system to search 1502 + * @ino: The inode number to match 1503 + * 1504 + * Search for the inode specified by @hashval and @data in the inode cache, 1505 + * where the helper function @test will return 0 if the inode does not match 1506 + * and 1 if it does. The @test function must be responsible for taking the 1507 + * i_lock spin_lock and checking i_state for an inode being freed or being 1508 + * initialized. 1509 + * 1510 + * If successful, this will return the inode for which the @test function 1511 + * returned 1 and NULL otherwise. 1512 + * 1513 + * The @test function is not permitted to take a ref on any inode presented. 1514 + * It is also not permitted to sleep. 1515 + * 1516 + * The caller must hold the RCU read lock. 1517 + */ 1518 + struct inode *find_inode_by_ino_rcu(struct super_block *sb, 1519 + unsigned long ino) 1520 + { 1521 + struct hlist_head *head = inode_hashtable + hash(sb, ino); 1522 + struct inode *inode; 1523 + 1524 + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), 1525 + "suspicious find_inode_by_ino_rcu() usage"); 1526 + 1527 + hlist_for_each_entry_rcu(inode, head, i_hash) { 1528 + if (inode->i_ino == ino && 1529 + inode->i_sb == sb && 1530 + !(READ_ONCE(inode->i_state) & (I_FREEING | I_WILL_FREE))) 1531 + return inode; 1532 + } 1533 + return NULL; 1534 + } 1535 + EXPORT_SYMBOL(find_inode_by_ino_rcu); 1536 + 1456 1537 int insert_inode_locked(struct inode *inode) 1457 1538 { 1458 1539 struct super_block *sb = inode->i_sb; ··· 1555 1480 if (likely(!old)) { 1556 1481 spin_lock(&inode->i_lock); 1557 1482 inode->i_state |= I_NEW | I_CREATING; 1558 - hlist_add_head(&inode->i_hash, head); 1483 + hlist_add_head_rcu(&inode->i_hash, head); 1559 1484 spin_unlock(&inode->i_lock); 1560 1485 spin_unlock(&inode_hash_lock); 1561 1486 return 0; ··· 1615 1540 { 1616 1541 struct super_block *sb = inode->i_sb; 1617 1542 const struct super_operations *op = inode->i_sb->s_op; 1543 + unsigned long state; 1618 1544 int drop; 1619 1545 1620 1546 WARN_ON(inode->i_state & I_NEW); ··· 1631 1555 return; 1632 1556 } 1633 1557 1558 + state = inode->i_state; 1634 1559 if (!drop) { 1635 - inode->i_state |= I_WILL_FREE; 1560 + WRITE_ONCE(inode->i_state, state | I_WILL_FREE); 1636 1561 spin_unlock(&inode->i_lock); 1562 + 1637 1563 write_inode_now(inode, 1); 1564 + 1638 1565 spin_lock(&inode->i_lock); 1639 - WARN_ON(inode->i_state & I_NEW); 1640 - inode->i_state &= ~I_WILL_FREE; 1566 + state = inode->i_state; 1567 + WARN_ON(state & I_NEW); 1568 + state &= ~I_WILL_FREE; 1641 1569 } 1642 1570 1643 - inode->i_state |= I_FREEING; 1571 + WRITE_ONCE(inode->i_state, state | I_FREEING); 1644 1572 if (!list_empty(&inode->i_lru)) 1645 1573 inode_lru_list_del(inode); 1646 1574 spin_unlock(&inode->i_lock);
+3
include/linux/fs.h
··· 3081 3081 int (*match)(struct inode *, 3082 3082 unsigned long, void *), 3083 3083 void *data); 3084 + extern struct inode *find_inode_rcu(struct super_block *, unsigned long, 3085 + int (*)(struct inode *, void *), void *); 3086 + extern struct inode *find_inode_by_ino_rcu(struct super_block *, unsigned long); 3084 3087 extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *); 3085 3088 extern int insert_inode_locked(struct inode *); 3086 3089 #ifdef CONFIG_DEBUG_LOCK_ALLOC
+88 -23
include/trace/events/afs.h
··· 33 33 afs_server_trace_destroy, 34 34 afs_server_trace_free, 35 35 afs_server_trace_gc, 36 + afs_server_trace_get_by_addr, 36 37 afs_server_trace_get_by_uuid, 37 38 afs_server_trace_get_caps, 38 39 afs_server_trace_get_install, 39 40 afs_server_trace_get_new_cbi, 41 + afs_server_trace_get_probe, 40 42 afs_server_trace_give_up_cb, 41 43 afs_server_trace_put_call, 42 44 afs_server_trace_put_cbi, 43 45 afs_server_trace_put_find_rsq, 46 + afs_server_trace_put_probe, 44 47 afs_server_trace_put_slist, 45 48 afs_server_trace_put_slist_isort, 46 49 afs_server_trace_put_uuid_rsq, 47 50 afs_server_trace_update, 51 + }; 52 + 53 + enum afs_volume_trace { 54 + afs_volume_trace_alloc, 55 + afs_volume_trace_free, 56 + afs_volume_trace_get_alloc_sbi, 57 + afs_volume_trace_get_cell_insert, 58 + afs_volume_trace_get_new_op, 59 + afs_volume_trace_get_query_alias, 60 + afs_volume_trace_put_cell_dup, 61 + afs_volume_trace_put_cell_root, 62 + afs_volume_trace_put_destroy_sbi, 63 + afs_volume_trace_put_free_fc, 64 + afs_volume_trace_put_put_op, 65 + afs_volume_trace_put_query_alias, 66 + afs_volume_trace_put_validate_fc, 67 + afs_volume_trace_remove, 48 68 }; 49 69 50 70 enum afs_fs_operation { ··· 128 108 afs_VL_GetEntryByNameU = 527, /* AFS Get Vol Entry By Name operation ID */ 129 109 afs_VL_GetAddrsU = 533, /* AFS Get FS server addresses */ 130 110 afs_YFSVL_GetEndpoints = 64002, /* YFS Get FS & Vol server addresses */ 111 + afs_YFSVL_GetCellName = 64014, /* YFS Get actual cell name */ 131 112 afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */ 132 113 }; 133 114 ··· 161 140 afs_eproto_bad_status, 162 141 afs_eproto_cb_count, 163 142 afs_eproto_cb_fid_count, 143 + afs_eproto_cellname_len, 164 144 afs_eproto_file_type, 165 145 afs_eproto_ibulkst_cb_count, 166 146 afs_eproto_ibulkst_count, ··· 263 241 EM(afs_server_trace_destroy, "DESTROY ") \ 264 242 EM(afs_server_trace_free, "FREE ") \ 265 243 EM(afs_server_trace_gc, "GC ") \ 244 + EM(afs_server_trace_get_by_addr, "GET addr ") \ 266 245 EM(afs_server_trace_get_by_uuid, "GET uuid ") \ 267 246 EM(afs_server_trace_get_caps, "GET caps ") \ 268 247 EM(afs_server_trace_get_install, "GET inst ") \ 269 248 EM(afs_server_trace_get_new_cbi, "GET cbi ") \ 249 + EM(afs_server_trace_get_probe, "GET probe") \ 270 250 EM(afs_server_trace_give_up_cb, "giveup-cb") \ 271 251 EM(afs_server_trace_put_call, "PUT call ") \ 272 252 EM(afs_server_trace_put_cbi, "PUT cbi ") \ 273 253 EM(afs_server_trace_put_find_rsq, "PUT f-rsq") \ 254 + EM(afs_server_trace_put_probe, "PUT probe") \ 274 255 EM(afs_server_trace_put_slist, "PUT slist") \ 275 256 EM(afs_server_trace_put_slist_isort, "PUT isort") \ 276 257 EM(afs_server_trace_put_uuid_rsq, "PUT u-req") \ 277 258 E_(afs_server_trace_update, "UPDATE") 259 + 260 + #define afs_volume_traces \ 261 + EM(afs_volume_trace_alloc, "ALLOC ") \ 262 + EM(afs_volume_trace_free, "FREE ") \ 263 + EM(afs_volume_trace_get_alloc_sbi, "GET sbi-alloc ") \ 264 + EM(afs_volume_trace_get_cell_insert, "GET cell-insrt") \ 265 + EM(afs_volume_trace_get_new_op, "GET op-new ") \ 266 + EM(afs_volume_trace_get_query_alias, "GET cell-alias") \ 267 + EM(afs_volume_trace_put_cell_dup, "PUT cell-dup ") \ 268 + EM(afs_volume_trace_put_cell_root, "PUT cell-root ") \ 269 + EM(afs_volume_trace_put_destroy_sbi, "PUT sbi-destry") \ 270 + EM(afs_volume_trace_put_free_fc, "PUT fc-free ") \ 271 + EM(afs_volume_trace_put_put_op, "PUT op-put ") \ 272 + EM(afs_volume_trace_put_query_alias, "PUT cell-alias") \ 273 + EM(afs_volume_trace_put_validate_fc, "PUT fc-validat") \ 274 + E_(afs_volume_trace_remove, "REMOVE ") 278 275 279 276 #define afs_fs_operations \ 280 277 EM(afs_FS_FetchData, "FS.FetchData") \ ··· 351 310 EM(afs_VL_GetEntryByNameU, "VL.GetEntryByNameU") \ 352 311 EM(afs_VL_GetAddrsU, "VL.GetAddrsU") \ 353 312 EM(afs_YFSVL_GetEndpoints, "YFSVL.GetEndpoints") \ 313 + EM(afs_YFSVL_GetCellName, "YFSVL.GetCellName") \ 354 314 E_(afs_VL_GetCapabilities, "VL.GetCapabilities") 355 315 356 316 #define afs_edit_dir_ops \ ··· 381 339 EM(afs_eproto_bad_status, "BadStatus") \ 382 340 EM(afs_eproto_cb_count, "CbCount") \ 383 341 EM(afs_eproto_cb_fid_count, "CbFidCount") \ 342 + EM(afs_eproto_cellname_len, "CellNameLen") \ 384 343 EM(afs_eproto_file_type, "FileTYpe") \ 385 344 EM(afs_eproto_ibulkst_cb_count, "IBS.CbCount") \ 386 345 EM(afs_eproto_ibulkst_count, "IBS.FidCount") \ ··· 679 636 680 637 TRACE_EVENT(afs_make_fs_call1, 681 638 TP_PROTO(struct afs_call *call, const struct afs_fid *fid, 682 - const char *name), 639 + const struct qstr *name), 683 640 684 641 TP_ARGS(call, fid, name), 685 642 ··· 691 648 ), 692 649 693 650 TP_fast_assign( 694 - int __len = strlen(name); 695 - __len = min(__len, 23); 651 + unsigned int __len = min_t(unsigned int, name->len, 23); 696 652 __entry->call = call->debug_id; 697 653 __entry->op = call->operation_ID; 698 654 if (fid) { ··· 701 659 __entry->fid.vnode = 0; 702 660 __entry->fid.unique = 0; 703 661 } 704 - memcpy(__entry->name, name, __len); 662 + memcpy(__entry->name, name->name, __len); 705 663 __entry->name[__len] = 0; 706 664 ), 707 665 ··· 716 674 717 675 TRACE_EVENT(afs_make_fs_call2, 718 676 TP_PROTO(struct afs_call *call, const struct afs_fid *fid, 719 - const char *name, const char *name2), 677 + const struct qstr *name, const struct qstr *name2), 720 678 721 679 TP_ARGS(call, fid, name, name2), 722 680 ··· 729 687 ), 730 688 731 689 TP_fast_assign( 732 - int __len = strlen(name); 733 - int __len2 = strlen(name2); 734 - __len = min(__len, 23); 735 - __len2 = min(__len2, 23); 690 + unsigned int __len = min_t(unsigned int, name->len, 23); 691 + unsigned int __len2 = min_t(unsigned int, name2->len, 23); 736 692 __entry->call = call->debug_id; 737 693 __entry->op = call->operation_ID; 738 694 if (fid) { ··· 740 700 __entry->fid.vnode = 0; 741 701 __entry->fid.unique = 0; 742 702 } 743 - memcpy(__entry->name, name, __len); 703 + memcpy(__entry->name, name->name, __len); 744 704 __entry->name[__len] = 0; 745 - memcpy(__entry->name2, name2, __len2); 705 + memcpy(__entry->name2, name2->name, __len2); 746 706 __entry->name2[__len2] = 0; 747 707 ), 748 708 ··· 1028 988 ); 1029 989 1030 990 TRACE_EVENT(afs_protocol_error, 1031 - TP_PROTO(struct afs_call *call, int error, enum afs_eproto_cause cause), 991 + TP_PROTO(struct afs_call *call, enum afs_eproto_cause cause), 1032 992 1033 - TP_ARGS(call, error, cause), 993 + TP_ARGS(call, cause), 1034 994 1035 995 TP_STRUCT__entry( 1036 996 __field(unsigned int, call ) 1037 - __field(int, error ) 1038 997 __field(enum afs_eproto_cause, cause ) 1039 998 ), 1040 999 1041 1000 TP_fast_assign( 1042 1001 __entry->call = call ? call->debug_id : 0; 1043 - __entry->error = error; 1044 1002 __entry->cause = cause; 1045 1003 ), 1046 1004 1047 - TP_printk("c=%08x r=%d %s", 1048 - __entry->call, __entry->error, 1005 + TP_printk("c=%08x %s", 1006 + __entry->call, 1049 1007 __print_symbolic(__entry->cause, afs_eproto_causes)) 1050 1008 ); 1051 1009 ··· 1309 1271 ); 1310 1272 1311 1273 TRACE_EVENT(afs_server, 1312 - TP_PROTO(struct afs_server *server, int usage, enum afs_server_trace reason), 1274 + TP_PROTO(struct afs_server *server, int ref, int active, 1275 + enum afs_server_trace reason), 1313 1276 1314 - TP_ARGS(server, usage, reason), 1277 + TP_ARGS(server, ref, active, reason), 1315 1278 1316 1279 TP_STRUCT__entry( 1317 1280 __field(unsigned int, server ) 1318 - __field(int, usage ) 1281 + __field(int, ref ) 1282 + __field(int, active ) 1319 1283 __field(int, reason ) 1320 1284 ), 1321 1285 1322 1286 TP_fast_assign( 1323 1287 __entry->server = server->debug_id; 1324 - __entry->usage = usage; 1288 + __entry->ref = ref; 1289 + __entry->active = active; 1325 1290 __entry->reason = reason; 1326 1291 ), 1327 1292 1328 - TP_printk("s=%08x %s u=%d", 1293 + TP_printk("s=%08x %s u=%d a=%d", 1329 1294 __entry->server, 1330 1295 __print_symbolic(__entry->reason, afs_server_traces), 1331 - __entry->usage) 1296 + __entry->ref, 1297 + __entry->active) 1298 + ); 1299 + 1300 + TRACE_EVENT(afs_volume, 1301 + TP_PROTO(afs_volid_t vid, int ref, enum afs_volume_trace reason), 1302 + 1303 + TP_ARGS(vid, ref, reason), 1304 + 1305 + TP_STRUCT__entry( 1306 + __field(afs_volid_t, vid ) 1307 + __field(int, ref ) 1308 + __field(enum afs_volume_trace, reason ) 1309 + ), 1310 + 1311 + TP_fast_assign( 1312 + __entry->vid = vid; 1313 + __entry->ref = ref; 1314 + __entry->reason = reason; 1315 + ), 1316 + 1317 + TP_printk("V=%llx %s u=%d", 1318 + __entry->vid, 1319 + __print_symbolic(__entry->reason, afs_volume_traces), 1320 + __entry->ref) 1332 1321 ); 1333 1322 1334 1323 #endif /* _TRACE_AFS_H */
+3
net/rxrpc/peer_event.c
··· 271 271 break; 272 272 273 273 case SO_EE_ORIGIN_ICMP6: 274 + if (err == EACCES) 275 + err = EHOSTUNREACH; 276 + /* Fall through */ 274 277 default: 275 278 _proto("Rx Received error report { orig=%u }", ee->ee_origin); 276 279 break;
+3 -3
net/rxrpc/proc.c
··· 68 68 "Proto Local " 69 69 " Remote " 70 70 " SvID ConnID CallID End Use State Abort " 71 - " UserID TxSeq TW RxSeq RW RxSerial RxTimo\n"); 71 + " DebugId TxSeq TW RxSeq RW RxSerial RxTimo\n"); 72 72 return 0; 73 73 } 74 74 ··· 100 100 rx_hard_ack = READ_ONCE(call->rx_hard_ack); 101 101 seq_printf(seq, 102 102 "UDP %-47.47s %-47.47s %4x %08x %08x %s %3u" 103 - " %-8.8s %08x %lx %08x %02x %08x %02x %08x %06lx\n", 103 + " %-8.8s %08x %08x %08x %02x %08x %02x %08x %06lx\n", 104 104 lbuff, 105 105 rbuff, 106 106 call->service_id, ··· 110 110 atomic_read(&call->usage), 111 111 rxrpc_call_states[call->state], 112 112 call->abort_code, 113 - call->user_call_ID, 113 + call->debug_id, 114 114 tx_hard_ack, READ_ONCE(call->tx_top) - tx_hard_ack, 115 115 rx_hard_ack, READ_ONCE(call->rx_top) - rx_hard_ack, 116 116 call->rx_serial,