History

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 ...

Linus Torvalds committed 6 years ago

Commit 9daa0a22 parents 0b166a5 8409f6738 files · +4437 −3923Browse files

Unified · Split

38 files
  1. fs/afs/Makefile +2 −0
  2. fs/afs/afs.h +1 −2
  3. fs/afs/afs_vl.h +1 −0
  4. fs/afs/callback.c +96 −249
  5. fs/afs/cell.c +8 −2
  6. fs/afs/cmservice.c +11 −56
  7. fs/afs/dir.c +580 −673
  8. fs/afs/dir_silly.c +99 −91
  9. fs/afs/dynroot.c +93 −0
  10. fs/afs/file.c +32 −30
  11. fs/afs/flock.c +53 −61
  12. fs/afs/fs_operation.c +239 −0
  13. fs/afs/fs_probe.c +266 −73
  14. fs/afs/fsclient.c +511 −794
  15. fs/afs/inode.c +224 −267
  16. fs/afs/internal.h +299 −224
  17. fs/afs/main.c +5 −1
  18. fs/afs/proc.c +23 −19
  19. fs/afs/protocol_yfs.h +1 −1
  20. fs/afs/rotate.c +162 −285
  21. fs/afs/rxrpc.c +26 −19
  22. fs/afs/security.c +3 −5
  23. fs/afs/server.c +197 −102
  24. fs/afs/server_list.c +8 −32
  25. fs/afs/super.c +59 −48
  26. fs/afs/vl_alias.c +382 −0
  27. fs/afs/vl_rotate.c +4 −0
  28. fs/afs/vlclient.c +126 −20
  29. fs/afs/volume.c +119 −35
  30. fs/afs/write.c +90 −58
  31. fs/afs/xattr.c +127 −173
  32. fs/afs/yfsclient.c +375 −539
  33. fs/ext4/inode.c +22 −22
  34. fs/inode.c +96 −16
  35. include/linux/fs.h +3 −0
  36. include/trace/events/afs.h +88 −23
  37. net/rxrpc/peer_event.c +3 −0
  38. net/rxrpc/proc.c +3 −3
fs/afs/Makefile+2−0
@@ -18,6 +18,7 @@ kafs-y := \ · 17 unmodified lines
18 file.o \18 file.o \
19 flock.o \19 flock.o \
20 fsclient.o \20 fsclient.o \
21 fs_operation.o \
21 fs_probe.o \22 fs_probe.o \
22 inode.o \23 inode.o \
23 main.o \24 main.o \
@@ -30,6 +31,7 @@ kafs-y := \ · 6 unmodified lines
30 server_list.o \31 server_list.o \
31 super.o \32 super.o \
32 vlclient.o \33 vlclient.o \
34 vl_alias.o \
33 vl_list.o \35 vl_list.o \
34 vl_probe.o \36 vl_probe.o \
35 vl_rotate.o \37 vl_rotate.o \
fs/afs/afs.h+1−2
@@ -10,7 +10,7 @@ · 9 unmodified lines
10 10
11#include <linux/in.h>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#define AFS_MAXVOLNAME 64 /* Maximum length of a volume name */14#define AFS_MAXVOLNAME 64 /* Maximum length of a volume name */
15#define AFS_MAXNSERVERS 8 /* Maximum servers in a basic volume record */15#define AFS_MAXNSERVERS 8 /* Maximum servers in a basic volume record */
16#define AFS_NMAXNSERVERS 13 /* Maximum servers in a N/U-class volume record */16#define AFS_NMAXNSERVERS 13 /* Maximum servers in a N/U-class volume record */
@@ -146,7 +146,6 @@ struct afs_file_status { · 129 unmodified lines
146struct afs_status_cb {146struct afs_status_cb {
147 struct afs_file_status status;147 struct afs_file_status status;
148 struct afs_callback callback;148 struct afs_callback callback;
149 unsigned int cb_break; /* Pre-op callback break counter */
150 bool have_status; /* True if status record was retrieved */149 bool have_status; /* True if status record was retrieved */
151 bool have_cb; /* True if cb record was retrieved */150 bool have_cb; /* True if cb record was retrieved */
152 bool have_error; /* True if status.abort_code indicates an error */151 bool have_error; /* True if status.abort_code indicates an error */
fs/afs/afs_vl.h+1−0
@@ -22,6 +22,7 @@ enum AFSVL_Operations { · 21 unmodified lines
22 VLGETENTRYBYNAMEU = 527, /* AFS Get VLDB entry by name (UUID-variant) */22 VLGETENTRYBYNAMEU = 527, /* AFS Get VLDB entry by name (UUID-variant) */
23 VLGETADDRSU = 533, /* AFS Get addrs for fileserver */23 VLGETADDRSU = 533, /* AFS Get addrs for fileserver */
24 YVLGETENDPOINTS = 64002, /* YFS Get endpoints for file/volume server */24 YVLGETENDPOINTS = 64002, /* YFS Get endpoints for file/volume server */
25 YVLGETCELLNAME = 64014, /* YFS Get actual cell name */
25 VLGETCAPABILITIES = 65537, /* AFS Get server capabilities */26 VLGETCAPABILITIES = 65537, /* AFS Get server capabilities */
26};27};
27 28
fs/afs/callback.c+96−249
@@ -21,192 +21,17 @@ · 20 unmodified lines
21#include "internal.h"21#include "internal.h"
22 22
23/*23/*
24 * Create volume and callback interests on a server.24 * Allow the fileserver to request callback state (re-)initialisation.
25 */25 * Unfortunately, UUIDs are not guaranteed unique.
26static 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;
73found_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 */
88int 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
96again:
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 */
179void 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
206 */26 */
207void afs_init_callback_state(struct afs_server *server)27void 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/*
@@ -237,70 +62,110 @@ void afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason · 24 unmodified lines
237 write_sequnlock(&vnode->cb_lock);62 write_sequnlock(&vnode->cb_lock);
238}63}
239 64
65/*
66 * Look up a volume by volume ID under RCU conditions.
67 */
68static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell,
69 afs_volid_t vid)
70{
71 struct afs_volume *volume = NULL;
72 struct rb_node *p;
73 int seq = 0;
74
75 do {
76 /* Unfortunately, rbtree walking doesn't give reliable results
77 * under just the RCU read lock, so we have to check for
78 * changes.
79 */
80 read_seqbegin_or_lock(&cell->volume_lock, &seq);
81
82 p = rcu_dereference_raw(cell->volumes.rb_node);
83 while (p) {
84 volume = rb_entry(p, struct afs_volume, cell_node);
85
86 if (volume->vid < vid)
87 p = rcu_dereference_raw(p->rb_left);
88 else if (volume->vid > vid)
89 p = rcu_dereference_raw(p->rb_right);
90 else
91 break;
92 volume = NULL;
93 }
94
95 } while (need_seqretry(&cell->volume_lock, seq));
96
97 done_seqretry(&cell->volume_lock, seq);
98 return volume;
99}
100
240/*101/*
241 * allow the fileserver to explicitly break one callback102 * allow the fileserver to explicitly break one callback
242 * - happens when103 * - happens when
243 * - the backing file is changed104 * - the backing file is changed
244 * - a lock is released105 * - a lock is released
245 */106 */
246static void afs_break_one_callback(struct afs_server *server,107static void afs_break_one_callback(struct afs_volume *volume,
247 struct afs_fid *fid)108 struct afs_fid *fid)
248{109{
249 struct afs_vol_interest *vi;110 struct super_block *sb;
250 struct afs_cb_interest *cbi;
251 struct afs_iget_data data;
252 struct afs_vnode *vnode;111 struct afs_vnode *vnode;
253 struct inode *inode;112 struct inode *inode;
254 113
255 read_lock(&server->cb_break_lock);114 if (fid->vnode == 0 && fid->unique == 0) {
256 hlist_for_each_entry(vi, &server->cb_volumes, srv_link) {115 /* The callback break applies to an entire volume. */
257 if (vi->vid < fid->vid)116 write_lock(&volume->cb_v_break_lock);
258 continue;117 volume->cb_v_break++;
259 if (vi->vid > fid->vid) {118 trace_afs_cb_break(fid, volume->cb_v_break,
260 vi = NULL;119 afs_cb_break_for_volume_callback, false);
261 break;120 write_unlock(&volume->cb_v_break_lock);
262 }121 return;
263 //atomic_inc(&vi->usage);
264 break;
265 }122 }
266 123
267 /* TODO: Find all matching volumes if we couldn't match the server and124 /* See if we can find a matching inode - even an I_NEW inode needs to
268 * break them anyway.125 * be marked as it can have its callback broken before we finish
126 * setting up the local inode.
269 */127 */
270 if (!vi)128 sb = rcu_dereference(volume->sb);
271 goto out;129 if (!sb)
130 return;
131
132 inode = find_inode_rcu(sb, fid->vnode, afs_ilookup5_test_by_fid, fid);
133 if (inode) {
134 vnode = AFS_FS_I(inode);
135 afs_break_callback(vnode, afs_cb_break_for_callback);
136 } else {
137 trace_afs_cb_miss(fid, afs_cb_break_for_callback);
138 }
139}
140
141static void afs_break_some_callbacks(struct afs_server *server,
142 struct afs_callback_break *cbb,
143 size_t *_count)
144{
145 struct afs_callback_break *residue = cbb;
146 struct afs_volume *volume;
147 afs_volid_t vid = cbb->fid.vid;
148 size_t i;
272 149
273 /* Step through all interested superblocks. There may be more than one150 volume = afs_lookup_volume_rcu(server->cell, vid);
274 * because of cell aliasing.151
152 /* TODO: Find all matching volumes if we couldn't match the server and
153 * break them anyway.
275 */154 */
276 hlist_for_each_entry(cbi, &vi->cb_interests, cb_vlink) {
277 if (fid->vnode == 0 && fid->unique == 0) {
278 /* The callback break applies to an entire volume. */
279 struct afs_super_info *as = AFS_FS_S(cbi->sb);
280 struct afs_volume *volume = as->volume;
281 155
282 write_lock(&volume->cb_v_break_lock);156 for (i = *_count; i > 0; cbb++, i--) {
283 volume->cb_v_break++;157 if (cbb->fid.vid == vid) {
284 trace_afs_cb_break(fid, volume->cb_v_break,158 _debug("- Fid { vl=%08llx n=%llu u=%u }",
285 afs_cb_break_for_volume_callback, false);159 cbb->fid.vid,
286 write_unlock(&volume->cb_v_break_lock);160 cbb->fid.vnode,
161 cbb->fid.unique);
162 --*_count;
163 if (volume)
164 afs_break_one_callback(volume, &cbb->fid);
287 } else {165 } else {
288 data.volume = NULL;166 *residue++ = *cbb;
289 data.fid = *fid;
290 inode = ilookup5_nowait(cbi->sb, fid->vnode,
291 afs_iget5_test, &data);
292 if (inode) {
293 vnode = AFS_FS_I(inode);
294 afs_break_callback(vnode, afs_cb_break_for_callback);
295 iput(inode);
296 } else {
297 trace_afs_cb_miss(fid, afs_cb_break_for_callback);
298 }
299 }167 }
300 }168 }
301
302out:
303 read_unlock(&server->cb_break_lock);
304}169}
305 170
306/*171/*
@@ -313,29 +178,11 @@ void afs_break_callbacks(struct afs_server *server, size_t count, · 6 unmodified lines
313 178
314 ASSERT(server != NULL);179 ASSERT(server != NULL);
315 180
316 /* TODO: Sort the callback break list by volume ID */181 rcu_read_lock();
317 182
318 for (; count > 0; callbacks++, count--) {183 while (count > 0)
319 _debug("- Fid { vl=%08llx n=%llu u=%u }",184 afs_break_some_callbacks(server, callbacks, &count);
320 callbacks->fid.vid,
321 callbacks->fid.vnode,
322 callbacks->fid.unique);
323 afs_break_one_callback(server, &callbacks->fid);
324 }
325 185
326 _leave("");186 rcu_read_unlock();
327 return;187 return;
328}188}
329
330/*
331 * Clear the callback interests in a server list.
332 */
333void afs_clear_callback_interests(struct afs_net *net, struct afs_server_list *slist)
334{
335 int i;
336
337 for (i = 0; i < slist->nr_servers; i++) {
338 afs_put_cb_interest(net, slist->servers[i].cb_interest);
339 slist->servers[i].cb_interest = NULL;
340 }
341}
fs/afs/cell.c+8−2
@@ -161,9 +161,13 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, · 160 unmodified lines
161 161
162 atomic_set(&cell->usage, 2);162 atomic_set(&cell->usage, 2);
163 INIT_WORK(&cell->manager, afs_manage_cell);163 INIT_WORK(&cell->manager, afs_manage_cell);
164 INIT_LIST_HEAD(&cell->proc_volumes);164 cell->volumes = RB_ROOT;
165 rwlock_init(&cell->proc_lock);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 rwlock_init(&cell->vl_servers_lock);169 rwlock_init(&cell->vl_servers_lock);
170 cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS);
167 171
168 /* Provide a VL server list, filling it in if we were given a list of172 /* Provide a VL server list, filling it in if we were given a list of
169 * addresses to use.173 * addresses to use.
@@ -481,7 +485,9 @@ static void afs_cell_destroy(struct rcu_head *rcu) · 311 unmodified lines
481 485
482 ASSERTCMP(atomic_read(&cell->usage), ==, 0);486 ASSERTCMP(atomic_read(&cell->usage), ==, 0);
483 487
488 afs_put_volume(cell->net, cell->root_volume, afs_volume_trace_put_cell_root);
484 afs_put_vlserverlist(cell->net, rcu_access_pointer(cell->vl_servers));489 afs_put_vlserverlist(cell->net, rcu_access_pointer(cell->vl_servers));
490 afs_put_cell(cell->net, cell->alias_of);
485 key_put(cell->anonymous_key);491 key_put(cell->anonymous_key);
486 kfree(cell);492 kfree(cell);
487 493
fs/afs/cmservice.c+11−56
@@ -118,8 +118,6 @@ bool afs_cm_incoming_call(struct afs_call *call) · 117 unmodified lines
118{118{
119 _enter("{%u, CB.OP %u}", call->service_id, call->operation_ID);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 switch (call->operation_ID) {121 switch (call->operation_ID) {
124 case CBCallBack:122 case CBCallBack:
125 call->type = &afs_SRXCBCallBack;123 call->type = &afs_SRXCBCallBack;
@@ -149,49 +147,6 @@ bool afs_cm_incoming_call(struct afs_call *call) · 23 unmodified lines
149 }147 }
150}148}
151 149
152/*
153 * Record a probe to the cache manager from a server.
154 */
155static int afs_record_cm_probe(struct afs_call *call, struct afs_server *server)
156{
157 _enter("");
158
159 if (test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags) &&
160 !test_bit(AFS_SERVER_FL_PROBING, &server->flags)) {
161 if (server->cm_epoch == call->epoch)
162 return 0;
163
164 if (!server->probe.said_rebooted) {
165 pr_notice("kAFS: FS rebooted %pU\n", &server->uuid);
166 server->probe.said_rebooted = true;
167 }
168 }
169
170 spin_lock(&server->probe_lock);
171
172 if (!test_and_set_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) {
173 server->cm_epoch = call->epoch;
174 server->probe.cm_epoch = call->epoch;
175 goto out;
176 }
177
178 if (server->probe.cm_probed &&
179 call->epoch != server->probe.cm_epoch &&
180 !server->probe.said_inconsistent) {
181 pr_notice("kAFS: FS endpoints inconsistent %pU\n",
182 &server->uuid);
183 server->probe.said_inconsistent = true;
184 }
185
186 if (!server->probe.cm_probed || call->epoch == server->cm_epoch)
187 server->probe.cm_epoch = server->cm_epoch;
188
189out:
190 server->probe.cm_probed = true;
191 spin_unlock(&server->probe_lock);
192 return 0;
193}
194
195/*150/*
196 * Find the server record by peer address and record a probe to the cache151 * Find the server record by peer address and record a probe to the cache
197 * manager from a server.152 * manager from a server.
@@ -210,7 +165,7 @@ static int afs_find_cm_server_by_peer(struct afs_call *call) · 12 unmodified lines
210 }165 }
211 166
212 call->server = server;167 call->server = server;
213 return afs_record_cm_probe(call, server);168 return 0;
214}169}
215 170
216/*171/*
@@ -231,7 +186,7 @@ static int afs_find_cm_server_by_uuid(struct afs_call *call, · 14 unmodified lines
231 }186 }
232 187
233 call->server = server;188 call->server = server;
234 return afs_record_cm_probe(call, server);189 return 0;
235}190}
236 191
237/*192/*
@@ -268,7 +223,9 @@ static void SRXAFSCB_CallBack(struct work_struct *work) · 30 unmodified lines
268 * to maintain cache coherency.223 * to maintain cache coherency.
269 */224 */
270 if (call->server) {225 if (call->server) {
271 trace_afs_server(call->server, atomic_read(&call->server->usage),226 trace_afs_server(call->server,
227 atomic_read(&call->server->ref),
228 atomic_read(&call->server->active),
272 afs_server_trace_callback);229 afs_server_trace_callback);
273 afs_break_callbacks(call->server, call->count, call->request);230 afs_break_callbacks(call->server, call->count, call->request);
274 }231 }
@@ -305,8 +262,7 @@ static int afs_deliver_cb_callback(struct afs_call *call) · 30 unmodified lines
305 call->count = ntohl(call->tmp);262 call->count = ntohl(call->tmp);
306 _debug("FID count: %u", call->count);263 _debug("FID count: %u", call->count);
307 if (call->count > AFSCBMAX)264 if (call->count > AFSCBMAX)
308 return afs_protocol_error(call, -EBADMSG,265 return afs_protocol_error(call, afs_eproto_cb_fid_count);
309 afs_eproto_cb_fid_count);
310 266
311 call->buffer = kmalloc(array3_size(call->count, 3, 4),267 call->buffer = kmalloc(array3_size(call->count, 3, 4),
312 GFP_KERNEL);268 GFP_KERNEL);
@@ -351,8 +307,7 @@ static int afs_deliver_cb_callback(struct afs_call *call) · 38 unmodified lines
351 call->count2 = ntohl(call->tmp);307 call->count2 = ntohl(call->tmp);
352 _debug("CB count: %u", call->count2);308 _debug("CB count: %u", call->count2);
353 if (call->count2 != call->count && call->count2 != 0)309 if (call->count2 != call->count && call->count2 != 0)
354 return afs_protocol_error(call, -EBADMSG,310 return afs_protocol_error(call, afs_eproto_cb_count);
355 afs_eproto_cb_count);
356 call->iter = &call->def_iter;311 call->iter = &call->def_iter;
357 iov_iter_discard(&call->def_iter, READ, call->count2 * 3 * 4);312 iov_iter_discard(&call->def_iter, READ, call->count2 * 3 * 4);
358 call->unmarshall++;313 call->unmarshall++;
@@ -509,7 +464,8 @@ static int afs_deliver_cb_probe(struct afs_call *call) · 150 unmodified lines
509}464}
510 465
511/*466/*
512 * allow the fileserver to quickly find out if the fileserver has been rebooted467 * Allow the fileserver to quickly find out if the cache manager has been
468 * rebooted.
513 */469 */
514static void SRXAFSCB_ProbeUuid(struct work_struct *work)470static void SRXAFSCB_ProbeUuid(struct work_struct *work)
515{471{
@@ -581,7 +537,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call) · 65 unmodified lines
581 537
582 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))538 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
583 return afs_io_error(call, afs_io_error_cm_reply);539 return afs_io_error(call, afs_io_error_cm_reply);
584 return afs_find_cm_server_by_uuid(call, call->request);540 return afs_find_cm_server_by_peer(call);
585}541}
586 542
587/*543/*
@@ -672,8 +628,7 @@ static int afs_deliver_yfs_cb_callback(struct afs_call *call) · 84 unmodified lines
672 call->count = ntohl(call->tmp);628 call->count = ntohl(call->tmp);
673 _debug("FID count: %u", call->count);629 _debug("FID count: %u", call->count);
674 if (call->count > YFSCBMAX)630 if (call->count > YFSCBMAX)
675 return afs_protocol_error(call, -EBADMSG,631 return afs_protocol_error(call, afs_eproto_cb_fid_count);
676 afs_eproto_cb_fid_count);
677 632
678 size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid));633 size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid));
679 call->buffer = kmalloc(size, GFP_KERNEL);634 call->buffer = kmalloc(size, GFP_KERNEL);
fs/afs/dir.c+580−673
@@ -99,8 +99,6 @@ struct afs_lookup_cookie { · 98 unmodified lines
99 bool found;99 bool found;
100 bool one_only;100 bool one_only;
101 unsigned short nr_fids;101 unsigned short nr_fids;
102 struct inode **inodes;
103 struct afs_status_cb *statuses;
104 struct afs_fid fids[50];102 struct afs_fid fids[50];
105};103};
106 104
@@ -618,8 +616,8 @@ static int afs_lookup_filldir(struct dir_context *ctx, const char *name, · 511 unmodified lines
618 }616 }
619 } else if (cookie->name.len == nlen &&617 } else if (cookie->name.len == nlen &&
620 memcmp(cookie->name.name, name, nlen) == 0) {618 memcmp(cookie->name.name, name, nlen) == 0) {
621 cookie->fids[0].vnode = ino;619 cookie->fids[1].vnode = ino;
622 cookie->fids[0].unique = dtype;620 cookie->fids[1].unique = dtype;
623 cookie->found = 1;621 cookie->found = 1;
624 if (cookie->one_only)622 if (cookie->one_only)
625 return -1;623 return -1;
@@ -630,6 +628,111 @@ static int afs_lookup_filldir(struct dir_context *ctx, const char *name, · 4 unmodified lines
630 return ret;628 return ret;
631}629}
632 630
631/*
632 * Deal with the result of a successful lookup operation. Turn all the files
633 * into inodes and save the first one - which is the one we actually want.
634 */
635static void afs_do_lookup_success(struct afs_operation *op)
636{
637 struct afs_vnode_param *vp;
638 struct afs_vnode *vnode;
639 struct inode *inode;
640 u32 abort_code;
641 int i;
642
643 _enter("");
644
645 for (i = 0; i < op->nr_files; i++) {
646 switch (i) {
647 case 0:
648 vp = &op->file[0];
649 abort_code = vp->scb.status.abort_code;
650 if (abort_code != 0) {
651 op->abort_code = abort_code;
652 op->error = afs_abort_to_error(abort_code);
653 }
654 break;
655
656 case 1:
657 vp = &op->file[1];
658 break;
659
660 default:
661 vp = &op->more_files[i - 2];
662 break;
663 }
664
665 if (!vp->scb.have_status && !vp->scb.have_error)
666 continue;
667
668 _debug("do [%u]", i);
669 if (vp->vnode) {
670 if (!test_bit(AFS_VNODE_UNSET, &vp->vnode->flags))
671 afs_vnode_commit_status(op, vp);
672 } else if (vp->scb.status.abort_code == 0) {
673 inode = afs_iget(op, vp);
674 if (!IS_ERR(inode)) {
675 vnode = AFS_FS_I(inode);
676 afs_cache_permit(vnode, op->key,
677 0 /* Assume vnode->cb_break is 0 */ +
678 op->cb_v_break,
679 &vp->scb);
680 vp->vnode = vnode;
681 vp->put_vnode = true;
682 }
683 } else {
684 _debug("- abort %d %llx:%llx.%x",
685 vp->scb.status.abort_code,
686 vp->fid.vid, vp->fid.vnode, vp->fid.unique);
687 }
688 }
689
690 _leave("");
691}
692
693static const struct afs_operation_ops afs_inline_bulk_status_operation = {
694 .issue_afs_rpc = afs_fs_inline_bulk_status,
695 .issue_yfs_rpc = yfs_fs_inline_bulk_status,
696 .success = afs_do_lookup_success,
697};
698
699static const struct afs_operation_ops afs_fetch_status_operation = {
700 .issue_afs_rpc = afs_fs_fetch_status,
701 .issue_yfs_rpc = yfs_fs_fetch_status,
702 .success = afs_do_lookup_success,
703};
704
705/*
706 * See if we know that the server we expect to use doesn't support
707 * FS.InlineBulkStatus.
708 */
709static bool afs_server_supports_ibulk(struct afs_vnode *dvnode)
710{
711 struct afs_server_list *slist;
712 struct afs_volume *volume = dvnode->volume;
713 struct afs_server *server;
714 bool ret = true;
715 int i;
716
717 if (!test_bit(AFS_VOLUME_MAYBE_NO_IBULK, &volume->flags))
718 return true;
719
720 rcu_read_lock();
721 slist = rcu_dereference(volume->servers);
722
723 for (i = 0; i < slist->nr_servers; i++) {
724 server = slist->servers[i].server;
725 if (server == dvnode->cb_server) {
726 if (test_bit(AFS_SERVER_FL_NO_IBULK, &server->flags))
727 ret = false;
728 break;
729 }
730 }
731
732 rcu_read_unlock();
733 return ret;
734}
735
633/*736/*
634 * Do a lookup in a directory. We make use of bulk lookup to query a slew of737 * Do a lookup in a directory. We make use of bulk lookup to query a slew of
635 * files in one go and create inodes for them. The inode of the file we were738 * files in one go and create inodes for them. The inode of the file we were
@@ -639,16 +742,13 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, · 3 unmodified lines
639 struct key *key)742 struct key *key)
640{743{
641 struct afs_lookup_cookie *cookie;744 struct afs_lookup_cookie *cookie;
642 struct afs_cb_interest *dcbi, *cbi = NULL;745 struct afs_vnode_param *vp;
643 struct afs_super_info *as = dir->i_sb->s_fs_info;746 struct afs_operation *op;
644 struct afs_status_cb *scb;
645 struct afs_iget_data iget_data;
646 struct afs_fs_cursor fc;
647 struct afs_server *server;
648 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode;747 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode;
649 struct inode *inode = NULL, *ti;748 struct inode *inode = NULL, *ti;
650 afs_dataversion_t data_version = READ_ONCE(dvnode->status.data_version);749 afs_dataversion_t data_version = READ_ONCE(dvnode->status.data_version);
651 int ret, i;750 long ret;
751 int i;
652 752
653 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);753 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
654 754
@@ -656,72 +756,74 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, · 1 unmodified line
656 if (!cookie)756 if (!cookie)
657 return ERR_PTR(-ENOMEM);757 return ERR_PTR(-ENOMEM);
658 758
759 for (i = 0; i < ARRAY_SIZE(cookie->fids); i++)
760 cookie->fids[i].vid = dvnode->fid.vid;
659 cookie->ctx.actor = afs_lookup_filldir;761 cookie->ctx.actor = afs_lookup_filldir;
660 cookie->name = dentry->d_name;762 cookie->name = dentry->d_name;
661 cookie->nr_fids = 1; /* slot 0 is saved for the fid we actually want */763 cookie->nr_fids = 2; /* slot 0 is saved for the fid we actually want
662 764 * and slot 1 for the directory */
663 read_seqlock_excl(&dvnode->cb_lock);
664 dcbi = rcu_dereference_protected(dvnode->cb_interest,
665 lockdep_is_held(&dvnode->cb_lock.lock));
666 if (dcbi) {
667 server = dcbi->server;
668 if (server &&
669 test_bit(AFS_SERVER_FL_NO_IBULK, &server->flags))
670 cookie->one_only = true;
671 }
672 read_sequnlock_excl(&dvnode->cb_lock);
673 765
674 for (i = 0; i < 50; i++)766 if (!afs_server_supports_ibulk(dvnode))
675 cookie->fids[i].vid = as->volume->vid;767 cookie->one_only = true;
676 768
677 /* search the directory */769 /* search the directory */
678 ret = afs_dir_iterate(dir, &cookie->ctx, key, &data_version);770 ret = afs_dir_iterate(dir, &cookie->ctx, key, &data_version);
679 if (ret < 0) {771 if (ret < 0)
680 inode = ERR_PTR(ret);
681 goto out;772 goto out;
682 }
683 773
684 dentry->d_fsdata = (void *)(unsigned long)data_version;774 dentry->d_fsdata = (void *)(unsigned long)data_version;
685 775
686 inode = ERR_PTR(-ENOENT);776 ret = -ENOENT;
687 if (!cookie->found)777 if (!cookie->found)
688 goto out;778 goto out;
689 779
690 /* Check to see if we already have an inode for the primary fid. */780 /* Check to see if we already have an inode for the primary fid. */
691 iget_data.fid = cookie->fids[0];781 inode = ilookup5(dir->i_sb, cookie->fids[1].vnode,
692 iget_data.volume = dvnode->volume;782 afs_ilookup5_test_by_fid, &cookie->fids[1]);
693 iget_data.cb_v_break = dvnode->volume->cb_v_break;
694 iget_data.cb_s_break = 0;
695 inode = ilookup5(dir->i_sb, cookie->fids[0].vnode,
696 afs_iget5_test, &iget_data);
697 if (inode)783 if (inode)
698 goto out;784 goto out; /* We do */
699 785
700 /* Need space for examining all the selected files */786 /* Okay, we didn't find it. We need to query the server - and whilst
701 inode = ERR_PTR(-ENOMEM);787 * we're doing that, we're going to attempt to look up a bunch of other
702 cookie->statuses = kvcalloc(cookie->nr_fids, sizeof(struct afs_status_cb),788 * vnodes also.
703 GFP_KERNEL);789 */
704 if (!cookie->statuses)790 op = afs_alloc_operation(NULL, dvnode->volume);
791 if (IS_ERR(op)) {
792 ret = PTR_ERR(op);
705 goto out;793 goto out;
794 }
706 795
707 cookie->inodes = kcalloc(cookie->nr_fids, sizeof(struct inode *),796 afs_op_set_vnode(op, 0, dvnode);
708 GFP_KERNEL);797 afs_op_set_fid(op, 1, &cookie->fids[1]);
709 if (!cookie->inodes)
710 goto out_s;
711 798
712 for (i = 1; i < cookie->nr_fids; i++) {799 op->nr_files = cookie->nr_fids;
713 scb = &cookie->statuses[i];800 _debug("nr_files %u", op->nr_files);
714 801
715 /* Find any inodes that already exist and get their802 /* Need space for examining all the selected files */
716 * callback counters.803 op->error = -ENOMEM;
717 */804 if (op->nr_files > 2) {
718 iget_data.fid = cookie->fids[i];805 op->more_files = kvcalloc(op->nr_files - 2,
719 ti = ilookup5_nowait(dir->i_sb, iget_data.fid.vnode,806 sizeof(struct afs_vnode_param),
720 afs_iget5_test, &iget_data);807 GFP_KERNEL);
721 if (!IS_ERR_OR_NULL(ti)) {808 if (!op->more_files)
722 vnode = AFS_FS_I(ti);809 goto out_op;
723 scb->cb_break = afs_calc_vnode_cb_break(vnode);810
724 cookie->inodes[i] = ti;811 for (i = 2; i < op->nr_files; i++) {
812 vp = &op->more_files[i - 2];
813 vp->fid = cookie->fids[i];
814
815 /* Find any inodes that already exist and get their
816 * callback counters.
817 */
818 ti = ilookup5_nowait(dir->i_sb, vp->fid.vnode,
819 afs_ilookup5_test_by_fid, &vp->fid);
820 if (!IS_ERR_OR_NULL(ti)) {
821 vnode = AFS_FS_I(ti);
822 vp->dv_before = vnode->status.data_version;
823 vp->cb_break_before = afs_calc_vnode_cb_break(vnode);
824 vp->vnode = vnode;
825 vp->put_vnode = true;
826 }
725 }827 }
726 }828 }
727 829
@@ -729,120 +831,40 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, · 1 unmodified line
729 * lookups contained therein are stored in the reply without aborting831 * lookups contained therein are stored in the reply without aborting
730 * the whole operation.832 * the whole operation.
731 */833 */
732 if (cookie->one_only)834 op->error = -ENOTSUPP;
733 goto no_inline_bulk_status;835 if (!cookie->one_only) {
734 836 op->ops = &afs_inline_bulk_status_operation;
735 inode = ERR_PTR(-ERESTARTSYS);837 afs_begin_vnode_operation(op);
736 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {838 afs_wait_for_operation(op);
737 while (afs_select_fileserver(&fc)) {
738 if (test_bit(AFS_SERVER_FL_NO_IBULK,
739 &fc.cbi->server->flags)) {
740 fc.ac.abort_code = RX_INVALID_OPERATION;
741 fc.ac.error = -ECONNABORTED;
742 break;
743 }
744 iget_data.cb_v_break = dvnode->volume->cb_v_break;
745 iget_data.cb_s_break = fc.cbi->server->cb_s_break;
746 afs_fs_inline_bulk_status(&fc,
747 afs_v2net(dvnode),
748 cookie->fids,
749 cookie->statuses,
750 cookie->nr_fids, NULL);
751 }
752
753 if (fc.ac.error == 0)
754 cbi = afs_get_cb_interest(fc.cbi);
755 if (fc.ac.abort_code == RX_INVALID_OPERATION)
756 set_bit(AFS_SERVER_FL_NO_IBULK, &fc.cbi->server->flags);
757 inode = ERR_PTR(afs_end_vnode_operation(&fc));
758 }839 }
759 840
760 if (!IS_ERR(inode))841 if (op->error == -ENOTSUPP) {
761 goto success;842 /* We could try FS.BulkStatus next, but this aborts the entire
762 if (fc.ac.abort_code != RX_INVALID_OPERATION)843 * op if any of the lookups fails - so, for the moment, revert
763 goto out_c;844 * to FS.FetchStatus for op->file[1].
764 845 */
765no_inline_bulk_status:846 op->fetch_status.which = 1;
766 /* We could try FS.BulkStatus next, but this aborts the entire op if847 op->ops = &afs_fetch_status_operation;
767 * any of the lookups fails - so, for the moment, revert to848 afs_begin_vnode_operation(op);
768 * FS.FetchStatus for just the primary fid.849 afs_wait_for_operation(op);
769 */
770 inode = ERR_PTR(-ERESTARTSYS);
771 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
772 while (afs_select_fileserver(&fc)) {
773 iget_data.cb_v_break = dvnode->volume->cb_v_break;
774 iget_data.cb_s_break = fc.cbi->server->cb_s_break;
775 scb = &cookie->statuses[0];
776 afs_fs_fetch_status(&fc,
777 afs_v2net(dvnode),
778 cookie->fids,
779 scb,
780 NULL);
781 }
782
783 if (fc.ac.error == 0)
784 cbi = afs_get_cb_interest(fc.cbi);
785 inode = ERR_PTR(afs_end_vnode_operation(&fc));
786 }850 }
851 inode = ERR_PTR(op->error);
787 852
788 if (IS_ERR(inode))853out_op:
789 goto out_c;854 if (op->error == 0) {
790 855 inode = &op->file[1].vnode->vfs_inode;
791success:856 op->file[1].vnode = NULL;
792 /* Turn all the files into inodes and save the first one - which is the
793 * one we actually want.
794 */
795 scb = &cookie->statuses[0];
796 if (scb->status.abort_code != 0)
797 inode = ERR_PTR(afs_abort_to_error(scb->status.abort_code));
798
799 for (i = 0; i < cookie->nr_fids; i++) {
800 struct afs_status_cb *scb = &cookie->statuses[i];
801
802 if (!scb->have_status && !scb->have_error)
803 continue;
804
805 if (cookie->inodes[i]) {
806 struct afs_vnode *iv = AFS_FS_I(cookie->inodes[i]);
807
808 if (test_bit(AFS_VNODE_UNSET, &iv->flags))
809 continue;
810
811 afs_vnode_commit_status(&fc, iv,
812 scb->cb_break, NULL, scb);
813 continue;
814 }
815
816 if (scb->status.abort_code != 0)
817 continue;
818
819 iget_data.fid = cookie->fids[i];
820 ti = afs_iget(dir->i_sb, key, &iget_data, scb, cbi, dvnode);
821 if (!IS_ERR(ti))
822 afs_cache_permit(AFS_FS_I(ti), key,
823 0 /* Assume vnode->cb_break is 0 */ +
824 iget_data.cb_v_break,
825 scb);
826 if (i == 0) {
827 inode = ti;
828 } else {
829 if (!IS_ERR(ti))
830 iput(ti);
831 }
832 }857 }
833 858
834out_c:859 if (op->file[0].scb.have_status)
835 afs_put_cb_interest(afs_v2net(dvnode), cbi);860 dentry->d_fsdata = (void *)(unsigned long)op->file[0].scb.status.data_version;
836 if (cookie->inodes) {861 else
837 for (i = 0; i < cookie->nr_fids; i++)862 dentry->d_fsdata = (void *)(unsigned long)op->file[0].dv_before;
838 iput(cookie->inodes[i]);863 ret = afs_put_operation(op);
839 kfree(cookie->inodes);
840 }
841out_s:
842 kvfree(cookie->statuses);
843out:864out:
844 kfree(cookie);865 kfree(cookie);
845 return inode;866 _leave("");
867 return inode ?: ERR_PTR(ret);
846}868}
847 869
848/*870/*
@@ -958,6 +980,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, · 109 unmodified lines
958 if (!IS_ERR_OR_NULL(inode))980 if (!IS_ERR_OR_NULL(inode))
959 fid = AFS_FS_I(inode)->fid;981 fid = AFS_FS_I(inode)->fid;
960 982
983 _debug("splice %px", dentry->d_inode);
961 d = d_splice_alias(inode, dentry);984 d = d_splice_alias(inode, dentry);
962 if (!IS_ERR_OR_NULL(d)) {985 if (!IS_ERR_OR_NULL(d)) {
963 d->d_fsdata = dentry->d_fsdata;986 d->d_fsdata = dentry->d_fsdata;
@@ -965,6 +988,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, · 1 unmodified line
965 } else {988 } else {
966 trace_afs_lookup(dvnode, &dentry->d_name, &fid);989 trace_afs_lookup(dvnode, &dentry->d_name, &fid);
967 }990 }
991 _leave("");
968 return d;992 return d;
969}993}
970 994
@@ -1215,130 +1239,97 @@ void afs_d_release(struct dentry *dentry) · 244 unmodified lines
1215/*1239/*
1216 * Create a new inode for create/mkdir/symlink1240 * Create a new inode for create/mkdir/symlink
1217 */1241 */
1218static void afs_vnode_new_inode(struct afs_fs_cursor *fc,1242static void afs_vnode_new_inode(struct afs_operation *op)
1219 struct dentry *new_dentry,
1220 struct afs_iget_data *new_data,
1221 struct afs_status_cb *new_scb)
1222{1243{
1244 struct afs_vnode_param *vp = &op->file[1];
1223 struct afs_vnode *vnode;1245 struct afs_vnode *vnode;
1224 struct inode *inode;1246 struct inode *inode;
1225 1247
1226 if (fc->ac.error < 0)1248 _enter("");
1227 return;1249
1250 ASSERTCMP(op->error, ==, 0);
1228 1251
1229 inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key,1252 inode = afs_iget(op, vp);
1230 new_data, new_scb, fc->cbi, fc->vnode);
1231 if (IS_ERR(inode)) {1253 if (IS_ERR(inode)) {
1232 /* ENOMEM or EINTR at a really inconvenient time - just abandon1254 /* ENOMEM or EINTR at a really inconvenient time - just abandon
1233 * the new directory on the server.1255 * the new directory on the server.
1234 */1256 */
1235 fc->ac.error = PTR_ERR(inode);1257 op->error = PTR_ERR(inode);
1236 return;1258 return;
1237 }1259 }
1238 1260
1239 vnode = AFS_FS_I(inode);1261 vnode = AFS_FS_I(inode);
1240 set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);1262 set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
1241 if (fc->ac.error == 0)1263 if (!op->error)
1242 afs_cache_permit(vnode, fc->key, vnode->cb_break, new_scb);1264 afs_cache_permit(vnode, op->key, vnode->cb_break, &vp->scb);
1243 d_instantiate(new_dentry, inode);1265 d_instantiate(op->dentry, inode);
1244}1266}
1245 1267
1246static void afs_prep_for_new_inode(struct afs_fs_cursor *fc,1268static void afs_create_success(struct afs_operation *op)
1247 struct afs_iget_data *iget_data)
1248{1269{
1249 iget_data->volume = fc->vnode->volume;1270 _enter("op=%08x", op->debug_id);
1250 iget_data->cb_v_break = fc->vnode->volume->cb_v_break;1271 afs_check_for_remote_deletion(op, op->file[0].vnode);
1251 iget_data->cb_s_break = fc->cbi->server->cb_s_break;1272 afs_vnode_commit_status(op, &op->file[0]);
1273 afs_update_dentry_version(op, &op->file[0], op->dentry);
1274 afs_vnode_new_inode(op);
1252}1275}
1253 1276
1254/*1277static void afs_create_edit_dir(struct afs_operation *op)
1255 * Note that a dentry got changed. We need to set d_fsdata to the data version1278{
1256 * number derived from the result of the operation. It doesn't matter if1279 struct afs_vnode_param *dvp = &op->file[0];
1257 * d_fsdata goes backwards as we'll just revalidate.1280 struct afs_vnode_param *vp = &op->file[1];
1258 */1281 struct afs_vnode *dvnode = dvp->vnode;
1259static void afs_update_dentry_version(struct afs_fs_cursor *fc,1282
1260 struct dentry *dentry,1283 _enter("op=%08x", op->debug_id);
1261 struct afs_status_cb *scb)1284
1285 down_write(&dvnode->validate_lock);
1286 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1287 dvnode->status.data_version == dvp->dv_before + dvp->dv_delta)
1288 afs_edit_dir_add(dvnode, &op->dentry->d_name, &vp->fid,
1289 op->create.reason);
1290 up_write(&dvnode->validate_lock);
1291}
1292
1293static void afs_create_put(struct afs_operation *op)
1262{1294{
1263 if (fc->ac.error == 0)1295 _enter("op=%08x", op->debug_id);
1264 dentry->d_fsdata =1296
1265 (void *)(unsigned long)scb->status.data_version;1297 if (op->error)
1298 d_drop(op->dentry);
1266}1299}
1267 1300
1301static const struct afs_operation_ops afs_mkdir_operation = {
1302 .issue_afs_rpc = afs_fs_make_dir,
1303 .issue_yfs_rpc = yfs_fs_make_dir,
1304 .success = afs_create_success,
1305 .edit_dir = afs_create_edit_dir,
1306 .put = afs_create_put,
1307};
1308
1268/*1309/*
1269 * create a directory on an AFS filesystem1310 * create a directory on an AFS filesystem
1270 */1311 */
1271static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)1312static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1272{1313{
1273 struct afs_iget_data iget_data;1314 struct afs_operation *op;
1274 struct afs_status_cb *scb;
1275 struct afs_fs_cursor fc;
1276 struct afs_vnode *dvnode = AFS_FS_I(dir);1315 struct afs_vnode *dvnode = AFS_FS_I(dir);
1277 struct key *key;
1278 afs_dataversion_t data_version;
1279 int ret;
1280
1281 mode |= S_IFDIR;
1282 1316
1283 _enter("{%llx:%llu},{%pd},%ho",1317 _enter("{%llx:%llu},{%pd},%ho",
1284 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);1318 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
1285 1319
1286 ret = -ENOMEM;1320 op = afs_alloc_operation(NULL, dvnode->volume);
1287 scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL);1321 if (IS_ERR(op)) {
1288 if (!scb)1322 d_drop(dentry);
1289 goto error;1323 return PTR_ERR(op);
1290
1291 key = afs_request_key(dvnode->volume->cell);
1292 if (IS_ERR(key)) {
1293 ret = PTR_ERR(key);
1294 goto error_scb;
1295 }1324 }
1296 1325
1297 ret = -ERESTARTSYS;1326 afs_op_set_vnode(op, 0, dvnode);
1298 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {1327 op->file[0].dv_delta = 1;
1299 data_version = dvnode->status.data_version + 1;1328 op->dentry = dentry;
1300 1329 op->create.mode = S_IFDIR | mode;
1301 while (afs_select_fileserver(&fc)) {1330 op->create.reason = afs_edit_dir_for_mkdir;
1302 fc.cb_break = afs_calc_vnode_cb_break(dvnode);1331 op->ops = &afs_mkdir_operation;
1303 afs_prep_for_new_inode(&fc, &iget_data);1332 return afs_do_sync_operation(op);
1304 afs_fs_create(&fc, dentry->d_name.name, mode,
1305 &scb[0], &iget_data.fid, &scb[1]);
1306 }
1307
1308 afs_check_for_remote_deletion(&fc, dvnode);
1309 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1310 &data_version, &scb[0]);
1311 afs_update_dentry_version(&fc, dentry, &scb[0]);
1312 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
1313 ret = afs_end_vnode_operation(&fc);
1314 if (ret < 0)
1315 goto error_key;
1316 } else {
1317 goto error_key;
1318 }
1319
1320 if (ret == 0) {
1321 down_write(&dvnode->validate_lock);
1322 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1323 dvnode->status.data_version == data_version)
1324 afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
1325 afs_edit_dir_for_create);
1326 up_write(&dvnode->validate_lock);
1327 }
1328
1329 key_put(key);
1330 kfree(scb);
1331 _leave(" = 0");
1332 return 0;
1333
1334error_key:
1335 key_put(key);
1336error_scb:
1337 kfree(scb);
1338error:
1339 d_drop(dentry);
1340 _leave(" = %d", ret);
1341 return ret;
1342}1333}
1343 1334
1344/*1335/*
@@ -1356,76 +1347,86 @@ static void afs_dir_remove_subdir(struct dentry *dentry) · 11 unmodified lines
1356 }1347 }
1357}1348}
1358 1349
1350static void afs_rmdir_success(struct afs_operation *op)
1351{
1352 _enter("op=%08x", op->debug_id);
1353 afs_check_for_remote_deletion(op, op->file[0].vnode);
1354 afs_vnode_commit_status(op, &op->file[0]);
1355 afs_update_dentry_version(op, &op->file[0], op->dentry);
1356}
1357
1358static void afs_rmdir_edit_dir(struct afs_operation *op)
1359{
1360 struct afs_vnode_param *dvp = &op->file[0];
1361 struct afs_vnode *dvnode = dvp->vnode;
1362
1363 _enter("op=%08x", op->debug_id);
1364 afs_dir_remove_subdir(op->dentry);
1365
1366 down_write(&dvnode->validate_lock);
1367 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1368 dvnode->status.data_version == dvp->dv_before + dvp->dv_delta)
1369 afs_edit_dir_remove(dvnode, &op->dentry->d_name,
1370 afs_edit_dir_for_rmdir);
1371 up_write(&dvnode->validate_lock);
1372}
1373
1374static void afs_rmdir_put(struct afs_operation *op)
1375{
1376 _enter("op=%08x", op->debug_id);
1377 if (op->file[1].vnode)
1378 up_write(&op->file[1].vnode->rmdir_lock);
1379}
1380
1381static const struct afs_operation_ops afs_rmdir_operation = {
1382 .issue_afs_rpc = afs_fs_remove_dir,
1383 .issue_yfs_rpc = yfs_fs_remove_dir,
1384 .success = afs_rmdir_success,
1385 .edit_dir = afs_rmdir_edit_dir,
1386 .put = afs_rmdir_put,
1387};
1388
1359/*1389/*
1360 * remove a directory from an AFS filesystem1390 * remove a directory from an AFS filesystem
1361 */1391 */
1362static int afs_rmdir(struct inode *dir, struct dentry *dentry)1392static int afs_rmdir(struct inode *dir, struct dentry *dentry)
1363{1393{
1364 struct afs_status_cb *scb;1394 struct afs_operation *op;
1365 struct afs_fs_cursor fc;
1366 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL;1395 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL;
1367 struct key *key;
1368 afs_dataversion_t data_version;
1369 int ret;1396 int ret;
1370 1397
1371 _enter("{%llx:%llu},{%pd}",1398 _enter("{%llx:%llu},{%pd}",
1372 dvnode->fid.vid, dvnode->fid.vnode, dentry);1399 dvnode->fid.vid, dvnode->fid.vnode, dentry);
1373 1400
1374 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);1401 op = afs_alloc_operation(NULL, dvnode->volume);
1375 if (!scb)1402 if (IS_ERR(op))
1376 return -ENOMEM;1403 return PTR_ERR(op);
1377 1404
1378 key = afs_request_key(dvnode->volume->cell);1405 afs_op_set_vnode(op, 0, dvnode);
1379 if (IS_ERR(key)) {1406 op->file[0].dv_delta = 1;
1380 ret = PTR_ERR(key);1407
1381 goto error;1408 op->dentry = dentry;
1382 }1409 op->ops = &afs_rmdir_operation;
1383 1410
1384 /* Try to make sure we have a callback promise on the victim. */1411 /* Try to make sure we have a callback promise on the victim. */
1385 if (d_really_is_positive(dentry)) {1412 if (d_really_is_positive(dentry)) {
1386 vnode = AFS_FS_I(d_inode(dentry));1413 vnode = AFS_FS_I(d_inode(dentry));
1387 ret = afs_validate(vnode, key);1414 ret = afs_validate(vnode, op->key);
1388 if (ret < 0)1415 if (ret < 0)
1389 goto error_key;1416 goto error;
1390 }1417 }
1391 1418
1392 if (vnode) {1419 if (vnode) {
1393 ret = down_write_killable(&vnode->rmdir_lock);1420 ret = down_write_killable(&vnode->rmdir_lock);
1394 if (ret < 0)1421 if (ret < 0)
1395 goto error_key;1422 goto error;
1423 op->file[1].vnode = vnode;
1396 }1424 }
1397 1425
1398 ret = -ERESTARTSYS;1426 return afs_do_sync_operation(op);
1399 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
1400 data_version = dvnode->status.data_version + 1;
1401
1402 while (afs_select_fileserver(&fc)) {
1403 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1404 afs_fs_remove(&fc, vnode, dentry->d_name.name, true, scb);
1405 }
1406
1407 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1408 &data_version, scb);
1409 afs_update_dentry_version(&fc, dentry, scb);
1410 ret = afs_end_vnode_operation(&fc);
1411 if (ret == 0) {
1412 afs_dir_remove_subdir(dentry);
1413 down_write(&dvnode->validate_lock);
1414 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1415 dvnode->status.data_version == data_version)
1416 afs_edit_dir_remove(dvnode, &dentry->d_name,
1417 afs_edit_dir_for_rmdir);
1418 up_write(&dvnode->validate_lock);
1419 }
1420 }
1421 1427
1422 if (vnode)
1423 up_write(&vnode->rmdir_lock);
1424error_key:
1425 key_put(key);
1426error:1428error:
1427 kfree(scb);1429 return afs_put_operation(op);
1428 return ret;
1429}1430}
1430 1431
1431/*1432/*
@@ -1438,52 +1439,90 @@ error: · 6 unmodified lines
1438 * However, if we didn't have a callback promise outstanding, or it was1439 * However, if we didn't have a callback promise outstanding, or it was
1439 * outstanding on a different server, then it won't break it either...1440 * outstanding on a different server, then it won't break it either...
1440 */1441 */
1441static int afs_dir_remove_link(struct afs_vnode *dvnode, struct dentry *dentry,1442static void afs_dir_remove_link(struct afs_operation *op)
1442 struct key *key)
1443{1443{
1444 int ret = 0;1444 struct afs_vnode *dvnode = op->file[0].vnode;
1445 struct afs_vnode *vnode = op->file[1].vnode;
1446 struct dentry *dentry = op->dentry;
1447 int ret;
1445 1448
1446 if (d_really_is_positive(dentry)) {1449 if (op->error != 0 ||
1447 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));1450 (op->file[1].scb.have_status && op->file[1].scb.have_error))
1451 return;
1452 if (d_really_is_positive(dentry))
1453 return;
1448 1454
1449 if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {1455 if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
1450 /* Already done */1456 /* Already done */
1451 } else if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {1457 } else if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {
1452 write_seqlock(&vnode->cb_lock);1458 write_seqlock(&vnode->cb_lock);
1453 drop_nlink(&vnode->vfs_inode);1459 drop_nlink(&vnode->vfs_inode);
1454 if (vnode->vfs_inode.i_nlink == 0) {1460 if (vnode->vfs_inode.i_nlink == 0) {
1455 set_bit(AFS_VNODE_DELETED, &vnode->flags);1461 set_bit(AFS_VNODE_DELETED, &vnode->flags);
1456 __afs_break_callback(vnode, afs_cb_break_for_unlink);1462 __afs_break_callback(vnode, afs_cb_break_for_unlink);
1457 }1463 }
1458 write_sequnlock(&vnode->cb_lock);1464 write_sequnlock(&vnode->cb_lock);
1459 ret = 0;1465 } else {
1460 } else {1466 afs_break_callback(vnode, afs_cb_break_for_unlink);
1461 afs_break_callback(vnode, afs_cb_break_for_unlink);
1462 1467
1463 if (test_bit(AFS_VNODE_DELETED, &vnode->flags))1468 if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
1464 kdebug("AFS_VNODE_DELETED");1469 _debug("AFS_VNODE_DELETED");
1465 1470
1466 ret = afs_validate(vnode, key);1471 ret = afs_validate(vnode, op->key);
1467 if (ret == -ESTALE)1472 if (ret != -ESTALE)
1468 ret = 0;1473 op->error = ret;
1469 }
1470 _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, ret);
1471 }1474 }
1472 1475
1473 return ret;1476 _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, op->error);
1477}
1478
1479static void afs_unlink_success(struct afs_operation *op)
1480{
1481 _enter("op=%08x", op->debug_id);
1482 afs_check_for_remote_deletion(op, op->file[0].vnode);
1483 afs_vnode_commit_status(op, &op->file[0]);
1484 afs_vnode_commit_status(op, &op->file[1]);
1485 afs_update_dentry_version(op, &op->file[0], op->dentry);
1486 afs_dir_remove_link(op);
1487}
1488
1489static void afs_unlink_edit_dir(struct afs_operation *op)
1490{
1491 struct afs_vnode_param *dvp = &op->file[0];
1492 struct afs_vnode *dvnode = dvp->vnode;
1493
1494 _enter("op=%08x", op->debug_id);
1495 down_write(&dvnode->validate_lock);
1496 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1497 dvnode->status.data_version == dvp->dv_before + dvp->dv_delta)
1498 afs_edit_dir_remove(dvnode, &op->dentry->d_name,
1499 afs_edit_dir_for_unlink);
1500 up_write(&dvnode->validate_lock);
1501}
1502
1503static void afs_unlink_put(struct afs_operation *op)
1504{
1505 _enter("op=%08x", op->debug_id);
1506 if (op->unlink.need_rehash && op->error < 0 && op->error != -ENOENT)
1507 d_rehash(op->dentry);
1474}1508}
1475 1509
1510static const struct afs_operation_ops afs_unlink_operation = {
1511 .issue_afs_rpc = afs_fs_remove_file,
1512 .issue_yfs_rpc = yfs_fs_remove_file,
1513 .success = afs_unlink_success,
1514 .edit_dir = afs_unlink_edit_dir,
1515 .put = afs_unlink_put,
1516};
1517
1476/*1518/*
1477 * Remove a file or symlink from an AFS filesystem.1519 * Remove a file or symlink from an AFS filesystem.
1478 */1520 */
1479static int afs_unlink(struct inode *dir, struct dentry *dentry)1521static int afs_unlink(struct inode *dir, struct dentry *dentry)
1480{1522{
1481 struct afs_fs_cursor fc;1523 struct afs_operation *op;
1482 struct afs_status_cb *scb;
1483 struct afs_vnode *dvnode = AFS_FS_I(dir);1524 struct afs_vnode *dvnode = AFS_FS_I(dir);
1484 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));1525 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
1485 struct key *key;
1486 bool need_rehash = false;
1487 int ret;1526 int ret;
1488 1527
1489 _enter("{%llx:%llu},{%pd}",1528 _enter("{%llx:%llu},{%pd}",
@@ -1492,269 +1531,176 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) · 2 unmodified lines
1492 if (dentry->d_name.len >= AFSNAMEMAX)1531 if (dentry->d_name.len >= AFSNAMEMAX)
1493 return -ENAMETOOLONG;1532 return -ENAMETOOLONG;
1494 1533
1495 ret = -ENOMEM;1534 op = afs_alloc_operation(NULL, dvnode->volume);
1496 scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL);1535 if (IS_ERR(op))
1497 if (!scb)1536 return PTR_ERR(op);
1498 goto error;
1499 1537
1500 key = afs_request_key(dvnode->volume->cell);1538 afs_op_set_vnode(op, 0, dvnode);
1501 if (IS_ERR(key)) {1539 op->file[0].dv_delta = 1;
1502 ret = PTR_ERR(key);
1503 goto error_scb;
1504 }
1505 1540
1506 /* Try to make sure we have a callback promise on the victim. */1541 /* Try to make sure we have a callback promise on the victim. */
1507 ret = afs_validate(vnode, key);1542 ret = afs_validate(vnode, op->key);
1508 if (ret < 0)1543 if (ret < 0) {
1509 goto error_key;1544 op->error = ret;
1545 goto error;
1546 }
1510 1547
1511 spin_lock(&dentry->d_lock);1548 spin_lock(&dentry->d_lock);
1512 if (d_count(dentry) > 1) {1549 if (d_count(dentry) > 1) {
1513 spin_unlock(&dentry->d_lock);1550 spin_unlock(&dentry->d_lock);
1514 /* Start asynchronous writeout of the inode */1551 /* Start asynchronous writeout of the inode */
1515 write_inode_now(d_inode(dentry), 0);1552 write_inode_now(d_inode(dentry), 0);
1516 ret = afs_sillyrename(dvnode, vnode, dentry, key);1553 op->error = afs_sillyrename(dvnode, vnode, dentry, op->key);
1517 goto error_key;1554 goto error;
1518 }1555 }
1519 if (!d_unhashed(dentry)) {1556 if (!d_unhashed(dentry)) {
1520 /* Prevent a race with RCU lookup. */1557 /* Prevent a race with RCU lookup. */
1521 __d_drop(dentry);1558 __d_drop(dentry);
1522 need_rehash = true;1559 op->unlink.need_rehash = true;
1523 }1560 }
1524 spin_unlock(&dentry->d_lock);1561 spin_unlock(&dentry->d_lock);
1525 1562
1526 ret = -ERESTARTSYS;1563 op->file[1].vnode = vnode;
1527 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {1564 op->dentry = dentry;
1528 afs_dataversion_t data_version = dvnode->status.data_version + 1;1565 op->ops = &afs_unlink_operation;
1529 afs_dataversion_t data_version_2 = vnode->status.data_version;1566 return afs_do_sync_operation(op);
1530
1531 while (afs_select_fileserver(&fc)) {
1532 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1533 fc.cb_break_2 = afs_calc_vnode_cb_break(vnode);
1534
1535 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) &&
1536 !test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) {
1537 yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name,
1538 &scb[0], &scb[1]);
1539 if (fc.ac.error != -ECONNABORTED ||
1540 fc.ac.abort_code != RXGEN_OPCODE)
1541 continue;
1542 set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags);
1543 }
1544
1545 afs_fs_remove(&fc, vnode, dentry->d_name.name, false, &scb[0]);
1546 }
1547 1567
1548 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1549 &data_version, &scb[0]);
1550 afs_vnode_commit_status(&fc, vnode, fc.cb_break_2,
1551 &data_version_2, &scb[1]);
1552 afs_update_dentry_version(&fc, dentry, &scb[0]);
1553 ret = afs_end_vnode_operation(&fc);
1554 if (ret == 0 && !(scb[1].have_status || scb[1].have_error))
1555 ret = afs_dir_remove_link(dvnode, dentry, key);
1556
1557 if (ret == 0) {
1558 down_write(&dvnode->validate_lock);
1559 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1560 dvnode->status.data_version == data_version)
1561 afs_edit_dir_remove(dvnode, &dentry->d_name,
1562 afs_edit_dir_for_unlink);
1563 up_write(&dvnode->validate_lock);
1564 }
1565 }
1566
1567 if (need_rehash && ret < 0 && ret != -ENOENT)
1568 d_rehash(dentry);
1569
1570error_key:
1571 key_put(key);
1572error_scb:
1573 kfree(scb);
1574error:1568error:
1575 _leave(" = %d", ret);1569 return afs_put_operation(op);
1576 return ret;
1577}1570}
1578 1571
1572static const struct afs_operation_ops afs_create_operation = {
1573 .issue_afs_rpc = afs_fs_create_file,
1574 .issue_yfs_rpc = yfs_fs_create_file,
1575 .success = afs_create_success,
1576 .edit_dir = afs_create_edit_dir,
1577 .put = afs_create_put,
1578};
1579
1579/*1580/*
1580 * create a regular file on an AFS filesystem1581 * create a regular file on an AFS filesystem
1581 */1582 */
1582static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,1583static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1583 bool excl)1584 bool excl)
1584{1585{
1585 struct afs_iget_data iget_data;1586 struct afs_operation *op;
1586 struct afs_fs_cursor fc;
1587 struct afs_status_cb *scb;
1588 struct afs_vnode *dvnode = AFS_FS_I(dir);1587 struct afs_vnode *dvnode = AFS_FS_I(dir);
1589 struct key *key;1588 int ret = -ENAMETOOLONG;
1590 afs_dataversion_t data_version;
1591 int ret;
1592
1593 mode |= S_IFREG;
1594 1589
1595 _enter("{%llx:%llu},{%pd},%ho,",1590 _enter("{%llx:%llu},{%pd},%ho",
1596 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);1591 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
1597 1592
1598 ret = -ENAMETOOLONG;
1599 if (dentry->d_name.len >= AFSNAMEMAX)1593 if (dentry->d_name.len >= AFSNAMEMAX)
1600 goto error;1594 goto error;
1601 1595
1602 key = afs_request_key(dvnode->volume->cell);1596 op = afs_alloc_operation(NULL, dvnode->volume);
1603 if (IS_ERR(key)) {1597 if (IS_ERR(op)) {
1604 ret = PTR_ERR(key);1598 ret = PTR_ERR(op);
1605 goto error;1599 goto error;
1606 }1600 }
1607 1601
1608 ret = -ENOMEM;1602 afs_op_set_vnode(op, 0, dvnode);
1609 scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL);1603 op->file[0].dv_delta = 1;
1610 if (!scb)
1611 goto error_scb;
1612 1604
1613 ret = -ERESTARTSYS;1605 op->dentry = dentry;
1614 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {1606 op->create.mode = S_IFREG | mode;
1615 data_version = dvnode->status.data_version + 1;1607 op->create.reason = afs_edit_dir_for_create;
1616 1608 op->ops = &afs_create_operation;
1617 while (afs_select_fileserver(&fc)) {1609 return afs_do_sync_operation(op);
1618 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1619 afs_prep_for_new_inode(&fc, &iget_data);
1620 afs_fs_create(&fc, dentry->d_name.name, mode,
1621 &scb[0], &iget_data.fid, &scb[1]);
1622 }
1623 1610
1624 afs_check_for_remote_deletion(&fc, dvnode);
1625 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1626 &data_version, &scb[0]);
1627 afs_update_dentry_version(&fc, dentry, &scb[0]);
1628 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
1629 ret = afs_end_vnode_operation(&fc);
1630 if (ret < 0)
1631 goto error_key;
1632 } else {
1633 goto error_key;
1634 }
1635
1636 down_write(&dvnode->validate_lock);
1637 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1638 dvnode->status.data_version == data_version)
1639 afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
1640 afs_edit_dir_for_create);
1641 up_write(&dvnode->validate_lock);
1642
1643 kfree(scb);
1644 key_put(key);
1645 _leave(" = 0");
1646 return 0;
1647
1648error_scb:
1649 kfree(scb);
1650error_key:
1651 key_put(key);
1652error:1611error:
1653 d_drop(dentry);1612 d_drop(dentry);
1654 _leave(" = %d", ret);1613 _leave(" = %d", ret);
1655 return ret;1614 return ret;
1656}1615}
1657 1616
1617static void afs_link_success(struct afs_operation *op)
1618{
1619 struct afs_vnode_param *dvp = &op->file[0];
1620 struct afs_vnode_param *vp = &op->file[1];
1621
1622 _enter("op=%08x", op->debug_id);
1623 afs_vnode_commit_status(op, dvp);
1624 afs_vnode_commit_status(op, vp);
1625 afs_update_dentry_version(op, dvp, op->dentry);
1626 if (op->dentry_2->d_parent == op->dentry->d_parent)
1627 afs_update_dentry_version(op, dvp, op->dentry_2);
1628 ihold(&vp->vnode->vfs_inode);
1629 d_instantiate(op->dentry, &vp->vnode->vfs_inode);
1630}
1631
1632static void afs_link_put(struct afs_operation *op)
1633{
1634 _enter("op=%08x", op->debug_id);
1635 if (op->error)
1636 d_drop(op->dentry);
1637}
1638
1639static const struct afs_operation_ops afs_link_operation = {
1640 .issue_afs_rpc = afs_fs_link,
1641 .issue_yfs_rpc = yfs_fs_link,
1642 .success = afs_link_success,
1643 .edit_dir = afs_create_edit_dir,
1644 .put = afs_link_put,
1645};
1646
1658/*1647/*
1659 * create a hard link between files in an AFS filesystem1648 * create a hard link between files in an AFS filesystem
1660 */1649 */
1661static int afs_link(struct dentry *from, struct inode *dir,1650static int afs_link(struct dentry *from, struct inode *dir,
1662 struct dentry *dentry)1651 struct dentry *dentry)
1663{1652{
1664 struct afs_fs_cursor fc;1653 struct afs_operation *op;
1665 struct afs_status_cb *scb;
1666 struct afs_vnode *dvnode = AFS_FS_I(dir);1654 struct afs_vnode *dvnode = AFS_FS_I(dir);
1667 struct afs_vnode *vnode = AFS_FS_I(d_inode(from));1655 struct afs_vnode *vnode = AFS_FS_I(d_inode(from));
1668 struct key *key;1656 int ret = -ENAMETOOLONG;
1669 afs_dataversion_t data_version;
1670 int ret;
1671 1657
1672 _enter("{%llx:%llu},{%llx:%llu},{%pd}",1658 _enter("{%llx:%llu},{%llx:%llu},{%pd}",
1673 vnode->fid.vid, vnode->fid.vnode,1659 vnode->fid.vid, vnode->fid.vnode,
1674 dvnode->fid.vid, dvnode->fid.vnode,1660 dvnode->fid.vid, dvnode->fid.vnode,
1675 dentry);1661 dentry);
1676 1662
1677 ret = -ENAMETOOLONG;
1678 if (dentry->d_name.len >= AFSNAMEMAX)1663 if (dentry->d_name.len >= AFSNAMEMAX)
1679 goto error;1664 goto error;
1680 1665
1681 ret = -ENOMEM;1666 op = afs_alloc_operation(NULL, dvnode->volume);
1682 scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL);1667 if (IS_ERR(op)) {
1683 if (!scb)1668 ret = PTR_ERR(op);
1684 goto error;1669 goto error;
1685
1686 key = afs_request_key(dvnode->volume->cell);
1687 if (IS_ERR(key)) {
1688 ret = PTR_ERR(key);
1689 goto error_scb;
1690 }
1691
1692 ret = -ERESTARTSYS;
1693 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
1694 data_version = dvnode->status.data_version + 1;
1695
1696 if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) {
1697 afs_end_vnode_operation(&fc);
1698 goto error_key;
1699 }
1700
1701 while (afs_select_fileserver(&fc)) {
1702 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1703 fc.cb_break_2 = afs_calc_vnode_cb_break(vnode);
1704 afs_fs_link(&fc, vnode, dentry->d_name.name,
1705 &scb[0], &scb[1]);
1706 }
1707
1708 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1709 &data_version, &scb[0]);
1710 afs_vnode_commit_status(&fc, vnode, fc.cb_break_2,
1711 NULL, &scb[1]);
1712 ihold(&vnode->vfs_inode);
1713 afs_update_dentry_version(&fc, dentry, &scb[0]);
1714 d_instantiate(dentry, &vnode->vfs_inode);
1715
1716 mutex_unlock(&vnode->io_lock);
1717 ret = afs_end_vnode_operation(&fc);
1718 if (ret < 0)
1719 goto error_key;
1720 } else {
1721 goto error_key;
1722 }1670 }
1723 1671
1724 down_write(&dvnode->validate_lock);1672 afs_op_set_vnode(op, 0, dvnode);
1725 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&1673 afs_op_set_vnode(op, 1, vnode);
1726 dvnode->status.data_version == data_version)1674 op->file[0].dv_delta = 1;
1727 afs_edit_dir_add(dvnode, &dentry->d_name, &vnode->fid,
1728 afs_edit_dir_for_link);
1729 up_write(&dvnode->validate_lock);
1730 1675
1731 key_put(key);1676 op->dentry = dentry;
1732 kfree(scb);1677 op->dentry_2 = from;
1733 _leave(" = 0");1678 op->ops = &afs_link_operation;
1734 return 0;1679 op->create.reason = afs_edit_dir_for_link;
1680 return afs_do_sync_operation(op);
1735 1681
1736error_key:
1737 key_put(key);
1738error_scb:
1739 kfree(scb);
1740error:1682error:
1741 d_drop(dentry);1683 d_drop(dentry);
1742 _leave(" = %d", ret);1684 _leave(" = %d", ret);
1743 return ret;1685 return ret;
1744}1686}
1745 1687
1688static const struct afs_operation_ops afs_symlink_operation = {
1689 .issue_afs_rpc = afs_fs_symlink,
1690 .issue_yfs_rpc = yfs_fs_symlink,
1691 .success = afs_create_success,
1692 .edit_dir = afs_create_edit_dir,
1693 .put = afs_create_put,
1694};
1695
1746/*1696/*
1747 * create a symlink in an AFS filesystem1697 * create a symlink in an AFS filesystem
1748 */1698 */
1749static int afs_symlink(struct inode *dir, struct dentry *dentry,1699static int afs_symlink(struct inode *dir, struct dentry *dentry,
1750 const char *content)1700 const char *content)
1751{1701{
1752 struct afs_iget_data iget_data;1702 struct afs_operation *op;
1753 struct afs_fs_cursor fc;
1754 struct afs_status_cb *scb;
1755 struct afs_vnode *dvnode = AFS_FS_I(dir);1703 struct afs_vnode *dvnode = AFS_FS_I(dir);
1756 struct key *key;
1757 afs_dataversion_t data_version;
1758 int ret;1704 int ret;
1759 1705
1760 _enter("{%llx:%llu},{%pd},%s",1706 _enter("{%llx:%llu},{%pd},%s",
@@ -1769,62 +1715,115 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry, · 8 unmodified lines
1769 if (strlen(content) >= AFSPATHMAX)1715 if (strlen(content) >= AFSPATHMAX)
1770 goto error;1716 goto error;
1771 1717
1772 ret = -ENOMEM;1718 op = afs_alloc_operation(NULL, dvnode->volume);
1773 scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL);1719 if (IS_ERR(op)) {
1774 if (!scb)1720 ret = PTR_ERR(op);
1775 goto error;1721 goto error;
1776
1777 key = afs_request_key(dvnode->volume->cell);
1778 if (IS_ERR(key)) {
1779 ret = PTR_ERR(key);
1780 goto error_scb;
1781 }1722 }
1782 1723
1783 ret = -ERESTARTSYS;1724 afs_op_set_vnode(op, 0, dvnode);
1784 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {1725 op->file[0].dv_delta = 1;
1785 data_version = dvnode->status.data_version + 1;
1786
1787 while (afs_select_fileserver(&fc)) {
1788 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1789 afs_prep_for_new_inode(&fc, &iget_data);
1790 afs_fs_symlink(&fc, dentry->d_name.name, content,
1791 &scb[0], &iget_data.fid, &scb[1]);
1792 }
1793 1726
1794 afs_check_for_remote_deletion(&fc, dvnode);1727 op->dentry = dentry;
1795 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,1728 op->ops = &afs_symlink_operation;
1796 &data_version, &scb[0]);1729 op->create.reason = afs_edit_dir_for_symlink;
1797 afs_update_dentry_version(&fc, dentry, &scb[0]);1730 op->create.symlink = content;
1798 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);1731 return afs_do_sync_operation(op);
1799 ret = afs_end_vnode_operation(&fc);
1800 if (ret < 0)
1801 goto error_key;
1802 } else {
1803 goto error_key;
1804 }
1805
1806 down_write(&dvnode->validate_lock);
1807 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
1808 dvnode->status.data_version == data_version)
1809 afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
1810 afs_edit_dir_for_symlink);
1811 up_write(&dvnode->validate_lock);
1812 1732
1813 key_put(key);
1814 kfree(scb);
1815 _leave(" = 0");
1816 return 0;
1817
1818error_key:
1819 key_put(key);
1820error_scb:
1821 kfree(scb);
1822error:1733error:
1823 d_drop(dentry);1734 d_drop(dentry);
1824 _leave(" = %d", ret);1735 _leave(" = %d", ret);
1825 return ret;1736 return ret;
1826}1737}
1827 1738
1739static void afs_rename_success(struct afs_operation *op)
1740{
1741 _enter("op=%08x", op->debug_id);
1742
1743 afs_vnode_commit_status(op, &op->file[0]);
1744 if (op->file[1].vnode != op->file[0].vnode)
1745 afs_vnode_commit_status(op, &op->file[1]);
1746}
1747
1748static void afs_rename_edit_dir(struct afs_operation *op)
1749{
1750 struct afs_vnode_param *orig_dvp = &op->file[0];
1751 struct afs_vnode_param *new_dvp = &op->file[1];
1752 struct afs_vnode *orig_dvnode = orig_dvp->vnode;
1753 struct afs_vnode *new_dvnode = new_dvp->vnode;
1754 struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry));
1755 struct dentry *old_dentry = op->dentry;
1756 struct dentry *new_dentry = op->dentry_2;
1757 struct inode *new_inode;
1758
1759 _enter("op=%08x", op->debug_id);
1760
1761 if (op->rename.rehash) {
1762 d_rehash(op->rename.rehash);
1763 op->rename.rehash = NULL;
1764 }
1765
1766 down_write(&orig_dvnode->validate_lock);
1767 if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) &&
1768 orig_dvnode->status.data_version == orig_dvp->dv_before + orig_dvp->dv_delta)
1769 afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name,
1770 afs_edit_dir_for_rename_0);
1771
1772 if (new_dvnode != orig_dvnode) {
1773 up_write(&orig_dvnode->validate_lock);
1774 down_write(&new_dvnode->validate_lock);
1775 }
1776
1777 if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) &&
1778 new_dvnode->status.data_version == new_dvp->dv_before + new_dvp->dv_delta) {
1779 if (!op->rename.new_negative)
1780 afs_edit_dir_remove(new_dvnode, &new_dentry->d_name,
1781 afs_edit_dir_for_rename_1);
1782
1783 afs_edit_dir_add(new_dvnode, &new_dentry->d_name,
1784 &vnode->fid, afs_edit_dir_for_rename_2);
1785 }
1786
1787 new_inode = d_inode(new_dentry);
1788 if (new_inode) {
1789 spin_lock(&new_inode->i_lock);
1790 if (new_inode->i_nlink > 0)
1791 drop_nlink(new_inode);
1792 spin_unlock(&new_inode->i_lock);
1793 }
1794
1795 /* Now we can update d_fsdata on the dentries to reflect their
1796 * new parent's data_version.
1797 *
1798 * Note that if we ever implement RENAME_EXCHANGE, we'll have
1799 * to update both dentries with opposing dir versions.
1800 */
1801 afs_update_dentry_version(op, new_dvp, op->dentry);
1802 afs_update_dentry_version(op, new_dvp, op->dentry_2);
1803
1804 d_move(old_dentry, new_dentry);
1805
1806 up_write(&new_dvnode->validate_lock);
1807}
1808
1809static void afs_rename_put(struct afs_operation *op)
1810{
1811 _enter("op=%08x", op->debug_id);
1812 if (op->rename.rehash)
1813 d_rehash(op->rename.rehash);
1814 dput(op->rename.tmp);
1815 if (op->error)
1816 d_rehash(op->dentry);
1817}
1818
1819static const struct afs_operation_ops afs_rename_operation = {
1820 .issue_afs_rpc = afs_fs_rename,
1821 .issue_yfs_rpc = yfs_fs_rename,
1822 .success = afs_rename_success,
1823 .edit_dir = afs_rename_edit_dir,
1824 .put = afs_rename_put,
1825};
1826
1828/*1827/*
1829 * rename a file in an AFS filesystem and/or move it between directories1828 * rename a file in an AFS filesystem and/or move it between directories
1830 */1829 */
@@ -1832,15 +1831,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 1 unmodified line
1832 struct inode *new_dir, struct dentry *new_dentry,1831 struct inode *new_dir, struct dentry *new_dentry,
1833 unsigned int flags)1832 unsigned int flags)
1834{1833{
1835 struct afs_fs_cursor fc;1834 struct afs_operation *op;
1836 struct afs_status_cb *scb;
1837 struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;1835 struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;
1838 struct dentry *tmp = NULL, *rehash = NULL;
1839 struct inode *new_inode;
1840 struct key *key;
1841 afs_dataversion_t orig_data_version;
1842 afs_dataversion_t new_data_version;
1843 bool new_negative = d_is_negative(new_dentry);
1844 int ret;1836 int ret;
1845 1837
1846 if (flags)1838 if (flags)
@@ -1860,16 +1852,19 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 13 unmodified lines
1860 new_dvnode->fid.vid, new_dvnode->fid.vnode,1852 new_dvnode->fid.vid, new_dvnode->fid.vnode,
1861 new_dentry);1853 new_dentry);
1862 1854
1863 ret = -ENOMEM;1855 op = afs_alloc_operation(NULL, orig_dvnode->volume);
1864 scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL);1856 if (IS_ERR(op))
1865 if (!scb)1857 return PTR_ERR(op);
1866 goto error;
1867 1858
1868 key = afs_request_key(orig_dvnode->volume->cell);1859 afs_op_set_vnode(op, 0, orig_dvnode);
1869 if (IS_ERR(key)) {1860 afs_op_set_vnode(op, 1, new_dvnode); /* May be same as orig_dvnode */
1870 ret = PTR_ERR(key);1861 op->file[0].dv_delta = 1;
1871 goto error_scb;1862 op->file[1].dv_delta = 1;
1872 }1863
1864 op->dentry = old_dentry;
1865 op->dentry_2 = new_dentry;
1866 op->rename.new_negative = d_is_negative(new_dentry);
1867 op->ops = &afs_rename_operation;
1873 1868
1874 /* For non-directories, check whether the target is busy and if so,1869 /* For non-directories, check whether the target is busy and if so,
1875 * make a copy of the dentry and then do a silly-rename. If the1870 * make a copy of the dentry and then do a silly-rename. If the
@@ -1882,26 +1877,26 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 6 unmodified lines
1882 */1877 */
1883 if (!d_unhashed(new_dentry)) {1878 if (!d_unhashed(new_dentry)) {
1884 d_drop(new_dentry);1879 d_drop(new_dentry);
1885 rehash = new_dentry;1880 op->rename.rehash = new_dentry;
1886 }1881 }
1887 1882
1888 if (d_count(new_dentry) > 2) {1883 if (d_count(new_dentry) > 2) {
1889 /* copy the target dentry's name */1884 /* copy the target dentry's name */
1890 ret = -ENOMEM;1885 ret = -ENOMEM;
1891 tmp = d_alloc(new_dentry->d_parent,1886 op->rename.tmp = d_alloc(new_dentry->d_parent,
1892 &new_dentry->d_name);1887 &new_dentry->d_name);
1893 if (!tmp)1888 if (!op->rename.tmp)
1894 goto error_rehash;1889 goto error;
1895 1890
1896 ret = afs_sillyrename(new_dvnode,1891 ret = afs_sillyrename(new_dvnode,
1897 AFS_FS_I(d_inode(new_dentry)),1892 AFS_FS_I(d_inode(new_dentry)),
1898 new_dentry, key);1893 new_dentry, op->key);
1899 if (ret)1894 if (ret)
1900 goto error_rehash;1895 goto error;
1901 1896
1902 new_dentry = tmp;1897 op->dentry_2 = op->rename.tmp;
1903 rehash = NULL;1898 op->rename.rehash = NULL;
1904 new_negative = true;1899 op->rename.new_negative = true;
1905 }1900 }
1906 }1901 }
1907 1902
@@ -1916,98 +1911,10 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 8 unmodified lines
1916 */1911 */
1917 d_drop(old_dentry);1912 d_drop(old_dentry);
1918 1913
1919 ret = -ERESTARTSYS;1914 return afs_do_sync_operation(op);
1920 if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) {
1921 orig_data_version = orig_dvnode->status.data_version + 1;
1922
1923 if (orig_dvnode != new_dvnode) {
1924 if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) {
1925 afs_end_vnode_operation(&fc);
1926 goto error_rehash_old;
1927 }
1928 new_data_version = new_dvnode->status.data_version + 1;
1929 } else {
1930 new_data_version = orig_data_version;
1931 }
1932
1933 while (afs_select_fileserver(&fc)) {
1934 fc.cb_break = afs_calc_vnode_cb_break(orig_dvnode);
1935 fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode);
1936 afs_fs_rename(&fc, old_dentry->d_name.name,
1937 new_dvnode, new_dentry->d_name.name,
1938 &scb[0], &scb[1]);
1939 }
1940 1915
1941 afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break,
1942 &orig_data_version, &scb[0]);
1943 if (new_dvnode != orig_dvnode) {
1944 afs_vnode_commit_status(&fc, new_dvnode, fc.cb_break_2,
1945 &new_data_version, &scb[1]);
1946 mutex_unlock(&new_dvnode->io_lock);
1947 }
1948 ret = afs_end_vnode_operation(&fc);
1949 if (ret < 0)
1950 goto error_rehash_old;
1951 }
1952
1953 if (ret == 0) {
1954 if (rehash)
1955 d_rehash(rehash);
1956 down_write(&orig_dvnode->validate_lock);
1957 if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) &&
1958 orig_dvnode->status.data_version == orig_data_version)
1959 afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name,
1960 afs_edit_dir_for_rename_0);
1961 if (orig_dvnode != new_dvnode) {
1962 up_write(&orig_dvnode->validate_lock);
1963
1964 down_write(&new_dvnode->validate_lock);
1965 }
1966 if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) &&
1967 orig_dvnode->status.data_version == new_data_version) {
1968 if (!new_negative)
1969 afs_edit_dir_remove(new_dvnode, &new_dentry->d_name,
1970 afs_edit_dir_for_rename_1);
1971
1972 afs_edit_dir_add(new_dvnode, &new_dentry->d_name,
1973 &vnode->fid, afs_edit_dir_for_rename_2);
1974 }
1975
1976 new_inode = d_inode(new_dentry);
1977 if (new_inode) {
1978 spin_lock(&new_inode->i_lock);
1979 if (new_inode->i_nlink > 0)
1980 drop_nlink(new_inode);
1981 spin_unlock(&new_inode->i_lock);
1982 }
1983
1984 /* Now we can update d_fsdata on the dentries to reflect their
1985 * new parent's data_version.
1986 *
1987 * Note that if we ever implement RENAME_EXCHANGE, we'll have
1988 * to update both dentries with opposing dir versions.
1989 */
1990 afs_update_dentry_version(&fc, old_dentry, &scb[1]);
1991 afs_update_dentry_version(&fc, new_dentry, &scb[1]);
1992 d_move(old_dentry, new_dentry);
1993 up_write(&new_dvnode->validate_lock);
1994 goto error_tmp;
1995 }
1996
1997error_rehash_old:
1998 d_rehash(new_dentry);
1999error_rehash:
2000 if (rehash)
2001 d_rehash(rehash);
2002error_tmp:
2003 if (tmp)
2004 dput(tmp);
2005 key_put(key);
2006error_scb:
2007 kfree(scb);
2008error:1916error:
2009 _leave(" = %d", ret);1917 return afs_put_operation(op);
2010 return ret;
2011}1918}
2012 1919
2013/*1920/*
fs/afs/dir_silly.c+99−91
@@ -12,6 +12,47 @@ · 11 unmodified lines
12#include <linux/fsnotify.h>12#include <linux/fsnotify.h>
13#include "internal.h"13#include "internal.h"
14 14
15static 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
22static 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
49static 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 * Actually perform the silly rename step.57 * Actually perform the silly rename step.
17 */58 */
@@ -19,56 +60,22 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode · 1 unmodified line
19 struct dentry *old, struct dentry *new,60 struct dentry *old, struct dentry *new,
20 struct key *key)61 struct key *key)
21{62{
22 struct afs_fs_cursor fc;63 struct afs_operation *op;
23 struct afs_status_cb *scb;
24 afs_dataversion_t dir_data_version;
25 int ret = -ERESTARTSYS;
26 64
27 _enter("%pd,%pd", old, new);65 _enter("%pd,%pd", old, new);
28 66
29 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);67 op = afs_alloc_operation(key, dvnode->volume);
30 if (!scb)68 if (IS_ERR(op))
31 return -ENOMEM;69 return PTR_ERR(op);
32 70
33 trace_afs_silly_rename(vnode, false);71 afs_op_set_vnode(op, 0, dvnode);
34 if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
35 dir_data_version = dvnode->status.data_version + 1;
36
37 while (afs_select_fileserver(&fc)) {
38 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
39 afs_fs_rename(&fc, old->d_name.name,
40 dvnode, new->d_name.name,
41 scb, scb);
42 }
43
44 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
45 &dir_data_version, scb);
46 ret = afs_end_vnode_operation(&fc);
47 }
48 72
49 if (ret == 0) {73 op->dentry = old;
50 spin_lock(&old->d_lock);74 op->dentry_2 = new;
51 old->d_flags |= DCACHE_NFSFS_RENAMED;75 op->ops = &afs_silly_rename_operation;
52 spin_unlock(&old->d_lock);
53 if (dvnode->silly_key != key) {
54 key_put(dvnode->silly_key);
55 dvnode->silly_key = key_get(key);
56 }
57
58 down_write(&dvnode->validate_lock);
59 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
60 dvnode->status.data_version == dir_data_version) {
61 afs_edit_dir_remove(dvnode, &old->d_name,
62 afs_edit_dir_for_silly_0);
63 afs_edit_dir_add(dvnode, &new->d_name,
64 &vnode->fid, afs_edit_dir_for_silly_1);
65 }
66 up_write(&dvnode->validate_lock);
67 }
68 76
69 kfree(scb);77 trace_afs_silly_rename(vnode, false);
70 _leave(" = %d", ret);78 return afs_do_sync_operation(op);
71 return ret;
72}79}
73 80
74/**81/**
@@ -139,65 +146,66 @@ out: · 64 unmodified lines
139 return ret;146 return ret;
140}147}
141 148
149static void afs_silly_unlink_success(struct afs_operation *op)
150{
151 struct afs_vnode *vnode = op->file[1].vnode;
152
153 _enter("op=%08x", op->debug_id);
154 afs_check_for_remote_deletion(op, op->file[0].vnode);
155 afs_vnode_commit_status(op, &op->file[0]);
156 afs_vnode_commit_status(op, &op->file[1]);
157 afs_update_dentry_version(op, &op->file[0], op->dentry);
158
159 drop_nlink(&vnode->vfs_inode);
160 if (vnode->vfs_inode.i_nlink == 0) {
161 set_bit(AFS_VNODE_DELETED, &vnode->flags);
162 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
163 }
164}
165
166static void afs_silly_unlink_edit_dir(struct afs_operation *op)
167{
168 struct afs_vnode_param *dvp = &op->file[0];
169 struct afs_vnode *dvnode = dvp->vnode;
170
171 _enter("op=%08x", op->debug_id);
172 down_write(&dvnode->validate_lock);
173 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
174 dvnode->status.data_version == dvp->dv_before + dvp->dv_delta)
175 afs_edit_dir_remove(dvnode, &op->dentry->d_name,
176 afs_edit_dir_for_unlink);
177 up_write(&dvnode->validate_lock);
178}
179
180static const struct afs_operation_ops afs_silly_unlink_operation = {
181 .issue_afs_rpc = afs_fs_remove_file,
182 .issue_yfs_rpc = yfs_fs_remove_file,
183 .success = afs_silly_unlink_success,
184 .edit_dir = afs_silly_unlink_edit_dir,
185};
186
142/*187/*
143 * Tell the server to remove a sillyrename file.188 * Tell the server to remove a sillyrename file.
144 */189 */
145static int afs_do_silly_unlink(struct afs_vnode *dvnode, struct afs_vnode *vnode,190static int afs_do_silly_unlink(struct afs_vnode *dvnode, struct afs_vnode *vnode,
146 struct dentry *dentry, struct key *key)191 struct dentry *dentry, struct key *key)
147{192{
148 struct afs_fs_cursor fc;193 struct afs_operation *op;
149 struct afs_status_cb *scb;
150 int ret = -ERESTARTSYS;
151 194
152 _enter("");195 _enter("");
153 196
154 scb = kcalloc(2, sizeof(struct afs_status_cb), GFP_KERNEL);197 op = afs_alloc_operation(NULL, dvnode->volume);
155 if (!scb)198 if (IS_ERR(op))
156 return -ENOMEM;199 return PTR_ERR(op);
157 200
158 trace_afs_silly_rename(vnode, true);201 afs_op_set_vnode(op, 0, dvnode);
159 if (afs_begin_vnode_operation(&fc, dvnode, key, false)) {202 afs_op_set_vnode(op, 1, vnode);
160 afs_dataversion_t dir_data_version = dvnode->status.data_version + 1;
161
162 while (afs_select_fileserver(&fc)) {
163 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
164
165 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) &&
166 !test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) {
167 yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name,
168 &scb[0], &scb[1]);
169 if (fc.ac.error != -ECONNABORTED ||
170 fc.ac.abort_code != RXGEN_OPCODE)
171 continue;
172 set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags);
173 }
174
175 afs_fs_remove(&fc, vnode, dentry->d_name.name, false, &scb[0]);
176 }
177 203
178 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,204 op->dentry = dentry;
179 &dir_data_version, &scb[0]);205 op->ops = &afs_silly_unlink_operation;
180 ret = afs_end_vnode_operation(&fc);
181 if (ret == 0) {
182 drop_nlink(&vnode->vfs_inode);
183 if (vnode->vfs_inode.i_nlink == 0) {
184 set_bit(AFS_VNODE_DELETED, &vnode->flags);
185 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
186 }
187 }
188 if (ret == 0) {
189 down_write(&dvnode->validate_lock);
190 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
191 dvnode->status.data_version == dir_data_version)
192 afs_edit_dir_remove(dvnode, &dentry->d_name,
193 afs_edit_dir_for_unlink);
194 up_write(&dvnode->validate_lock);
195 }
196 }
197 206
198 kfree(scb);207 trace_afs_silly_rename(vnode, true);
199 _leave(" = %d", ret);208 return afs_do_sync_operation(op);
200 return ret;
201}209}
202 210
203/*211/*
fs/afs/dynroot.c+93−0
@@ -10,6 +10,99 @@ · 9 unmodified lines
10#include <linux/dns_resolver.h>10#include <linux/dns_resolver.h>
11#include "internal.h"11#include "internal.h"
12 12
13static 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 */
20static int afs_iget5_pseudo_test(struct inode *inode, void *opaque)
21{
22 return 0;
23}
24
25/*
26 * iget5() inode initialiser
27 */
28static 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 */
45struct 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 * Probe to see if a cell may exist. This prevents positive dentries from107 * Probe to see if a cell may exist. This prevents positive dentries from
15 * being created unnecessarily.108 * being created unnecessarily.
fs/afs/file.c+32−30
@@ -69,7 +69,7 @@ static const struct vm_operations_struct afs_vm_ops = { · 68 unmodified lines
69 */69 */
70void afs_put_wb_key(struct afs_wb_key *wbk)70void 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 key_put(wbk->key);73 key_put(wbk->key);
74 kfree(wbk);74 kfree(wbk);
75 }75 }
@@ -220,14 +220,35 @@ static void afs_file_readpage_read_complete(struct page *page, · 144 unmodified lines
220}220}
221#endif221#endif
222 222
223static 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
234static void afs_fetch_data_put(struct afs_operation *op)
235{
236 afs_put_read(op->fetch.req);
237}
238
239static 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 * Fetch file data from the volume.247 * Fetch file data from the volume.
225 */248 */
226int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *req)249int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *req)
227{250{
228 struct afs_fs_cursor fc;251 struct afs_operation *op;
229 struct afs_status_cb *scb;
230 int ret;
231 252
232 _enter("%s{%llx:%llu.%u},%x,,,",253 _enter("%s{%llx:%llu.%u},%x,,,",
233 vnode->volume->name,254 vnode->volume->name,
@@ -236,34 +257,15 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *re · 2 unmodified lines
236 vnode->fid.unique,257 vnode->fid.unique,
237 key_serial(key));258 key_serial(key));
238 259
239 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);260 op = afs_alloc_operation(key, vnode->volume);
240 if (!scb)261 if (IS_ERR(op))
241 return -ENOMEM;262 return PTR_ERR(op);
242
243 ret = -ERESTARTSYS;
244 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
245 afs_dataversion_t data_version = vnode->status.data_version;
246 263
247 while (afs_select_fileserver(&fc)) {264 afs_op_set_vnode(op, 0, vnode);
248 fc.cb_break = afs_calc_vnode_cb_break(vnode);
249 afs_fs_fetch_data(&fc, scb, req);
250 }
251
252 afs_check_for_remote_deletion(&fc, vnode);
253 afs_vnode_commit_status(&fc, vnode, fc.cb_break,
254 &data_version, scb);
255 ret = afs_end_vnode_operation(&fc);
256 }
257 265
258 if (ret == 0) {266 op->fetch.req = afs_get_read(req);
259 afs_stat_v(vnode, n_fetches);267 op->ops = &afs_fetch_data_operation;
260 atomic_long_add(req->actual_len,268 return afs_do_sync_operation(op);
261 &afs_v2net(vnode)->n_fetch_bytes);
262 }
263
264 kfree(scb);
265 _leave(" = %d", ret);
266 return ret;
267}269}
268 270
269/*271/*
fs/afs/flock.c+53−61
@@ -70,7 +70,8 @@ static void afs_schedule_lock_extension(struct afs_vnode *vnode) · 69 unmodified lines
70 */70 */
71void afs_lock_op_done(struct afs_call *call)71void 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 if (call->error == 0) {76 if (call->error == 0) {
76 spin_lock(&vnode->lock);77 spin_lock(&vnode->lock);
@@ -172,15 +173,28 @@ static void afs_kill_lockers_enoent(struct afs_vnode *vnode) · 95 unmodified lines
172 vnode->lock_key = NULL;173 vnode->lock_key = NULL;
173}174}
174 175
176static void afs_lock_success(struct afs_operation *op)
177{
178 struct afs_vnode *vnode = op->file[0].vnode;
179
180 _enter("op=%08x", op->debug_id);
181 afs_check_for_remote_deletion(op, vnode);
182 afs_vnode_commit_status(op, &op->file[0]);
183}
184
185static const struct afs_operation_ops afs_set_lock_operation = {
186 .issue_afs_rpc = afs_fs_set_lock,
187 .issue_yfs_rpc = yfs_fs_set_lock,
188 .success = afs_lock_success,
189};
190
175/*191/*
176 * Get a lock on a file192 * Get a lock on a file
177 */193 */
178static int afs_set_lock(struct afs_vnode *vnode, struct key *key,194static int afs_set_lock(struct afs_vnode *vnode, struct key *key,
179 afs_lock_type_t type)195 afs_lock_type_t type)
180{196{
181 struct afs_status_cb *scb;197 struct afs_operation *op;
182 struct afs_fs_cursor fc;
183 int ret;
184 198
185 _enter("%s{%llx:%llu.%u},%x,%u",199 _enter("%s{%llx:%llu.%u},%x,%u",
186 vnode->volume->name,200 vnode->volume->name,
@@ -189,35 +203,29 @@ static int afs_set_lock(struct afs_vnode *vnode, struct key *key, · 2 unmodified lines
189 vnode->fid.unique,203 vnode->fid.unique,
190 key_serial(key), type);204 key_serial(key), type);
191 205
192 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);206 op = afs_alloc_operation(key, vnode->volume);
193 if (!scb)207 if (IS_ERR(op))
194 return -ENOMEM;208 return PTR_ERR(op);
195 209
196 ret = -ERESTARTSYS;210 afs_op_set_vnode(op, 0, vnode);
197 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
198 while (afs_select_fileserver(&fc)) {
199 fc.cb_break = afs_calc_vnode_cb_break(vnode);
200 afs_fs_set_lock(&fc, type, scb);
201 }
202
203 afs_check_for_remote_deletion(&fc, vnode);
204 afs_vnode_commit_status(&fc, vnode, fc.cb_break, NULL, scb);
205 ret = afs_end_vnode_operation(&fc);
206 }
207 211
208 kfree(scb);212 op->lock.type = type;
209 _leave(" = %d", ret);213 op->ops = &afs_set_lock_operation;
210 return ret;214 return afs_do_sync_operation(op);
211}215}
212 216
217static const struct afs_operation_ops afs_extend_lock_operation = {
218 .issue_afs_rpc = afs_fs_extend_lock,
219 .issue_yfs_rpc = yfs_fs_extend_lock,
220 .success = afs_lock_success,
221};
222
213/*223/*
214 * Extend a lock on a file224 * Extend a lock on a file
215 */225 */
216static int afs_extend_lock(struct afs_vnode *vnode, struct key *key)226static int afs_extend_lock(struct afs_vnode *vnode, struct key *key)
217{227{
218 struct afs_status_cb *scb;228 struct afs_operation *op;
219 struct afs_fs_cursor fc;
220 int ret;
221 229
222 _enter("%s{%llx:%llu.%u},%x",230 _enter("%s{%llx:%llu.%u},%x",
223 vnode->volume->name,231 vnode->volume->name,
@@ -226,35 +234,29 @@ static int afs_extend_lock(struct afs_vnode *vnode, struct key *key) · 2 unmodified lines
226 vnode->fid.unique,234 vnode->fid.unique,
227 key_serial(key));235 key_serial(key));
228 236
229 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);237 op = afs_alloc_operation(key, vnode->volume);
230 if (!scb)238 if (IS_ERR(op))
231 return -ENOMEM;239 return PTR_ERR(op);
232
233 ret = -ERESTARTSYS;
234 if (afs_begin_vnode_operation(&fc, vnode, key, false)) {
235 while (afs_select_current_fileserver(&fc)) {
236 fc.cb_break = afs_calc_vnode_cb_break(vnode);
237 afs_fs_extend_lock(&fc, scb);
238 }
239 240
240 afs_check_for_remote_deletion(&fc, vnode);241 afs_op_set_vnode(op, 0, vnode);
241 afs_vnode_commit_status(&fc, vnode, fc.cb_break, NULL, scb);
242 ret = afs_end_vnode_operation(&fc);
243 }
244 242
245 kfree(scb);243 op->flags |= AFS_OPERATION_UNINTR;
246 _leave(" = %d", ret);244 op->ops = &afs_extend_lock_operation;
247 return ret;245 return afs_do_sync_operation(op);
248}246}
249 247
248static const struct afs_operation_ops afs_release_lock_operation = {
249 .issue_afs_rpc = afs_fs_release_lock,
250 .issue_yfs_rpc = yfs_fs_release_lock,
251 .success = afs_lock_success,
252};
253
250/*254/*
251 * Release a lock on a file255 * Release a lock on a file
252 */256 */
253static int afs_release_lock(struct afs_vnode *vnode, struct key *key)257static int afs_release_lock(struct afs_vnode *vnode, struct key *key)
254{258{
255 struct afs_status_cb *scb;259 struct afs_operation *op;
256 struct afs_fs_cursor fc;
257 int ret;
258 260
259 _enter("%s{%llx:%llu.%u},%x",261 _enter("%s{%llx:%llu.%u},%x",
260 vnode->volume->name,262 vnode->volume->name,
@@ -263,25 +265,15 @@ static int afs_release_lock(struct afs_vnode *vnode, struct key *key) · 2 unmodified lines
263 vnode->fid.unique,265 vnode->fid.unique,
264 key_serial(key));266 key_serial(key));
265 267
266 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);268 op = afs_alloc_operation(key, vnode->volume);
267 if (!scb)269 if (IS_ERR(op))
268 return -ENOMEM;270 return PTR_ERR(op);
269 271
270 ret = -ERESTARTSYS;272 afs_op_set_vnode(op, 0, vnode);
271 if (afs_begin_vnode_operation(&fc, vnode, key, false)) {
272 while (afs_select_current_fileserver(&fc)) {
273 fc.cb_break = afs_calc_vnode_cb_break(vnode);
274 afs_fs_release_lock(&fc, scb);
275 }
276 273
277 afs_check_for_remote_deletion(&fc, vnode);274 op->flags |= AFS_OPERATION_UNINTR;
278 afs_vnode_commit_status(&fc, vnode, fc.cb_break, NULL, scb);275 op->ops = &afs_release_lock_operation;
279 ret = afs_end_vnode_operation(&fc);276 return afs_do_sync_operation(op);
280 }
281
282 kfree(scb);
283 _leave(" = %d", ret);
284 return ret;
285}277}
286 278
287/*279/*
fs/afs/fs_operation.c+239−0
@@ -0,0 +1,239 @@
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
13static atomic_t afs_operation_debug_counter;
14
15/*
16 * Create an operation against a volume.
17 */
18struct 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 */
53static 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
97static 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
110static 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 */
134bool 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 */
156static 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 */
175void 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 */
207int 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
234int 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}
fs/afs/fs_probe.c+266−73
@@ -1,7 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/* AFS fileserver probing2/* 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 * Written by David Howells (dhowells@redhat.com)5 * Written by David Howells (dhowells@redhat.com)
6 */6 */
7 7
@@ -11,15 +11,86 @@ · 3 unmodified lines
11#include "internal.h"11#include "internal.h"
12#include "protocol_yfs.h"12#include "protocol_yfs.h"
13 13
14static bool afs_fs_probe_done(struct afs_server *server)14static unsigned int afs_fs_probe_fast_poll_interval = 30 * HZ;
15static unsigned int afs_fs_probe_slow_poll_interval = 5 * 60 * HZ;
16
17/*
18 * Start the probe polling timer. We have to supply it with an inc on the
19 * outstanding server count.
20 */
21static 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 */
40static 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 */
60static 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 */
74static void afs_fs_probe_not_done(struct afs_net *net,
75 struct afs_server *server,
76 struct afs_addr_cursor *ac)
15{77{
16 if (!atomic_dec_and_test(&server->probe_outstanding))78 struct afs_addr_list *alist = ac->alist;
17 return false;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);
18 85
19 wake_up_var(&server->probe_outstanding);86 server->probe.local_failure = true;
20 clear_bit_unlock(AFS_SERVER_FL_PROBING, &server->flags);87 if (server->probe.error == 0)
21 wake_up_bit(&server->flags, AFS_SERVER_FL_PROBING);88 server->probe.error = -ENOMEM;
22 return true;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/*
@@ -30,10 +101,8 @@ void afs_fileserver_probe_result(struct afs_call *call) · 4 unmodified lines
30{101{
31 struct afs_addr_list *alist = call->alist;102 struct afs_addr_list *alist = call->alist;
32 struct afs_server *server = call->server;103 struct afs_server *server = call->server;
33 unsigned int server_index = call->server_index;
34 unsigned int index = call->addr_ix;104 unsigned int index = call->addr_ix;
35 unsigned int rtt_us = 0;105 unsigned int rtt_us = 0;
36 bool have_result = false;
37 int ret = call->error;106 int ret = call->error;
38 107
39 _enter("%pU,%u", &server->uuid, index);108 _enter("%pU,%u", &server->uuid, index);
@@ -52,8 +121,9 @@ void afs_fileserver_probe_result(struct afs_call *call) · 12 unmodified lines
52 goto responded;121 goto responded;
53 case -ENOMEM:122 case -ENOMEM:
54 case -ENONET:123 case -ENONET:
124 clear_bit(index, &alist->responded);
55 server->probe.local_failure = true;125 server->probe.local_failure = true;
56 afs_io_error(call, afs_io_error_fs_probe_fail);126 trace_afs_io_error(call->debug_id, ret, afs_io_error_fs_probe_fail);
57 goto out;127 goto out;
58 case -ECONNRESET: /* Responded, but call expired. */128 case -ECONNRESET: /* Responded, but call expired. */
59 case -ERFKILL:129 case -ERFKILL:
@@ -72,12 +142,11 @@ void afs_fileserver_probe_result(struct afs_call *call) · 12 unmodified lines
72 server->probe.error == -ETIMEDOUT ||142 server->probe.error == -ETIMEDOUT ||
73 server->probe.error == -ETIME))143 server->probe.error == -ETIME))
74 server->probe.error = ret;144 server->probe.error = ret;
75 afs_io_error(call, afs_io_error_fs_probe_fail);145 trace_afs_io_error(call->debug_id, ret, afs_io_error_fs_probe_fail);
76 goto out;146 goto out;
77 }147 }
78 148
79responded:149responded:
80 set_bit(index, &alist->responded);
81 clear_bit(index, &alist->failed);150 clear_bit(index, &alist->failed);
82 151
83 if (call->service_id == YFS_FS_SERVICE) {152 if (call->service_id == YFS_FS_SERVICE) {
@@ -95,39 +164,34 @@ responded: · 11 unmodified lines
95 rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall);164 rtt_us = rxrpc_kernel_get_srtt(call->net->socket, call->rxcall);
96 if (rtt_us < server->probe.rtt) {165 if (rtt_us < server->probe.rtt) {
97 server->probe.rtt = rtt_us;166 server->probe.rtt = rtt_us;
167 server->rtt = rtt_us;
98 alist->preferred = index;168 alist->preferred = index;
99 have_result = true;
100 }169 }
101 170
102 smp_wmb(); /* Set rtt before responded. */171 smp_wmb(); /* Set rtt before responded. */
103 server->probe.responded = true;172 server->probe.responded = true;
104 set_bit(AFS_SERVER_FL_PROBED, &server->flags);173 set_bit(index, &alist->responded);
174 set_bit(AFS_SERVER_FL_RESPONDING, &server->flags);
105out:175out:
106 spin_unlock(&server->probe_lock);176 spin_unlock(&server->probe_lock);
107 177
108 _debug("probe [%u][%u] %pISpc rtt=%u ret=%d",178 _debug("probe %pU [%u] %pISpc rtt=%u ret=%d",
109 server_index, index, &alist->addrs[index].transport, rtt_us, ret);179 &server->uuid, index, &alist->addrs[index].transport,
180 rtt_us, ret);
110 181
111 have_result |= afs_fs_probe_done(server);182 return afs_done_one_fs_probe(call->net, server);
112 if (have_result)
113 wake_up_all(&server->probe_wq);
114}183}
115 184
116/*185/*
117 * Probe all of a fileserver's addresses to find out the best route and to186 * Probe one or all of a fileserver's addresses to find out the best route and
118 * query its capabilities.187 * to query its capabilities.
119 */188 */
120static int afs_do_probe_fileserver(struct afs_net *net,189void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
121 struct afs_server *server,190 struct key *key, bool all)
122 struct key *key,
123 unsigned int server_index,
124 struct afs_error *_e)
125{191{
126 struct afs_addr_cursor ac = {192 struct afs_addr_cursor ac = {
127 .index = 0,193 .index = 0,
128 };194 };
129 struct afs_call *call;
130 bool in_progress = false;
131 195
132 _enter("%pU", &server->uuid);196 _enter("%pU", &server->uuid);
133 197
@@ -137,50 +201,25 @@ static int afs_do_probe_fileserver(struct afs_net *net, · 3 unmodified lines
137 afs_get_addrlist(ac.alist);201 afs_get_addrlist(ac.alist);
138 read_unlock(&server->fs_lock);202 read_unlock(&server->fs_lock);
139 203
140 atomic_set(&server->probe_outstanding, ac.alist->nr_addrs);204 server->probed_at = jiffies;
205 atomic_set(&server->probe_outstanding, all ? ac.alist->nr_addrs : 1);
141 memset(&server->probe, 0, sizeof(server->probe));206 memset(&server->probe, 0, sizeof(server->probe));
142 server->probe.rtt = UINT_MAX;207 server->probe.rtt = UINT_MAX;
143 208
144 for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) {209 ac.index = ac.alist->preferred;
145 call = afs_fs_get_capabilities(net, server, &ac, key, server_index);210 if (ac.index < 0 || ac.index >= ac.alist->nr_addrs)
146 if (!IS_ERR(call)) {211 all = true;
147 afs_put_call(call);
148 in_progress = true;
149 } else {
150 afs_prioritise_error(_e, PTR_ERR(call), ac.abort_code);
151 }
152 }
153
154 if (!in_progress)
155 afs_fs_probe_done(server);
156 afs_put_addrlist(ac.alist);
157 return in_progress;
158}
159 212
160/*213 if (all) {
161 * Send off probes to all unprobed servers.214 for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++)
162 */215 if (!afs_fs_get_capabilities(net, server, &ac, key))
163int afs_probe_fileservers(struct afs_net *net, struct key *key,216 afs_fs_probe_not_done(net, server, &ac);
164 struct afs_server_list *list)217 } else {
165{218 if (!afs_fs_get_capabilities(net, server, &ac, key))
166 struct afs_server *server;219 afs_fs_probe_not_done(net, server, &ac);
167 struct afs_error e;
168 bool in_progress = false;
169 int i;
170
171 e.error = 0;
172 e.responded = false;
173 for (i = 0; i < list->nr_servers; i++) {
174 server = list->servers[i].server;
175 if (test_bit(AFS_SERVER_FL_PROBED, &server->flags))
176 continue;
177
178 if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags) &&
179 afs_do_probe_fileserver(net, server, key, i, &e))
180 in_progress = true;
181 }220 }
182 221
183 return in_progress ? 0 : e.error;222 afs_put_addrlist(ac.alist);
184}223}
185 224
186/*225/*
@@ -190,7 +229,7 @@ int afs_wait_for_fs_probes(struct afs_server_list *slist, unsigned long untried) · 3 unmodified lines
190{229{
191 struct wait_queue_entry *waits;230 struct wait_queue_entry *waits;
192 struct afs_server *server;231 struct afs_server *server;
193 unsigned int rtt = UINT_MAX;232 unsigned int rtt = UINT_MAX, rtt_s;
194 bool have_responders = false;233 bool have_responders = false;
195 int pref = -1, i;234 int pref = -1, i;
196 235
@@ -200,7 +239,7 @@ int afs_wait_for_fs_probes(struct afs_server_list *slist, unsigned long untried) · 3 unmodified lines
200 for (i = 0; i < slist->nr_servers; i++) {239 for (i = 0; i < slist->nr_servers; i++) {
201 if (test_bit(i, &untried)) {240 if (test_bit(i, &untried)) {
202 server = slist->servers[i].server;241 server = slist->servers[i].server;
203 if (!test_bit(AFS_SERVER_FL_PROBING, &server->flags))242 if (!atomic_read(&server->probe_outstanding))
204 __clear_bit(i, &untried);243 __clear_bit(i, &untried);
205 if (server->probe.responded)244 if (server->probe.responded)
206 have_responders = true;245 have_responders = true;
@@ -230,7 +269,7 @@ int afs_wait_for_fs_probes(struct afs_server_list *slist, unsigned long untried) · 23 unmodified lines
230 server = slist->servers[i].server;269 server = slist->servers[i].server;
231 if (server->probe.responded)270 if (server->probe.responded)
232 goto stop;271 goto stop;
233 if (test_bit(AFS_SERVER_FL_PROBING, &server->flags))272 if (atomic_read(&server->probe_outstanding))
234 still_probing = true;273 still_probing = true;
235 }274 }
236 }275 }
@@ -246,10 +285,11 @@ stop: · 9 unmodified lines
246 for (i = 0; i < slist->nr_servers; i++) {285 for (i = 0; i < slist->nr_servers; i++) {
247 if (test_bit(i, &untried)) {286 if (test_bit(i, &untried)) {
248 server = slist->servers[i].server;287 server = slist->servers[i].server;
249 if (server->probe.responded &&288 rtt_s = READ_ONCE(server->rtt);
250 server->probe.rtt < rtt) {289 if (test_bit(AFS_SERVER_FL_RESPONDING, &server->flags) &&
290 rtt_s < rtt) {
251 pref = i;291 pref = i;
252 rtt = server->probe.rtt;292 rtt = rtt_s;
253 }293 }
254 294
255 remove_wait_queue(&server->probe_wq, &waits[i]);295 remove_wait_queue(&server->probe_wq, &waits[i]);
@@ -265,3 +305,156 @@ stop: · 9 unmodified lines
265 slist->preferred = pref;305 slist->preferred = pref;
266 return 0;306 return 0;
267}307}
308
309/*
310 * Probe timer. We have an increment on fs_outstanding that we need to pass
311 * along to the work item.
312 */
313void afs_fs_probe_timer(struct timer_list *timer)
314{
315 struct afs_net *net = container_of(timer, struct afs_net, fs_probe_timer);
316
317 if (!queue_work(afs_wq, &net->fs_prober))
318 afs_dec_servers_outstanding(net);
319}
320
321/*
322 * Dispatch a probe to a server.
323 */
324static void afs_dispatch_fs_probe(struct afs_net *net, struct afs_server *server, bool all)
325 __releases(&net->fs_lock)
326{
327 struct key *key = NULL;
328
329 /* We remove it from the queues here - it will be added back to
330 * one of the queues on the completion of the probe.
331 */
332 list_del_init(&server->probe_link);
333
334 afs_get_server(server, afs_server_trace_get_probe);
335 write_sequnlock(&net->fs_lock);
336
337 afs_fs_probe_fileserver(net, server, key, all);
338 afs_put_server(net, server, afs_server_trace_put_probe);
339}
340
341/*
342 * Probe a server immediately without waiting for its due time to come
343 * round. This is used when all of the addresses have been tried.
344 */
345void afs_probe_fileserver(struct afs_net *net, struct afs_server *server)
346{
347 write_seqlock(&net->fs_lock);
348 if (!list_empty(&server->probe_link))
349 return afs_dispatch_fs_probe(net, server, true);
350 write_sequnlock(&net->fs_lock);
351}
352
353/*
354 * Probe dispatcher to regularly dispatch probes to keep NAT alive.
355 */
356void afs_fs_probe_dispatcher(struct work_struct *work)
357{
358 struct afs_net *net = container_of(work, struct afs_net, fs_prober);
359 struct afs_server *fast, *slow, *server;
360 unsigned long nowj, timer_at, poll_at;
361 bool first_pass = true, set_timer = false;
362
363 if (!net->live)
364 return;
365
366 _enter("");
367
368 if (list_empty(&net->fs_probe_fast) && list_empty(&net->fs_probe_slow)) {
369 _leave(" [none]");
370 return;
371 }
372
373again:
374 write_seqlock(&net->fs_lock);
375
376 fast = slow = server = NULL;
377 nowj = jiffies;
378 timer_at = nowj + MAX_JIFFY_OFFSET;
379
380 if (!list_empty(&net->fs_probe_fast)) {
381 fast = list_first_entry(&net->fs_probe_fast, struct afs_server, probe_link);
382 poll_at = fast->probed_at + afs_fs_probe_fast_poll_interval;
383 if (time_before(nowj, poll_at)) {
384 timer_at = poll_at;
385 set_timer = true;
386 fast = NULL;
387 }
388 }
389
390 if (!list_empty(&net->fs_probe_slow)) {
391 slow = list_first_entry(&net->fs_probe_slow, struct afs_server, probe_link);
392 poll_at = slow->probed_at + afs_fs_probe_slow_poll_interval;
393 if (time_before(nowj, poll_at)) {
394 if (time_before(poll_at, timer_at))
395 timer_at = poll_at;
396 set_timer = true;
397 slow = NULL;
398 }
399 }
400
401 server = fast ?: slow;
402 if (server)
403 _debug("probe %pU", &server->uuid);
404
405 if (server && (first_pass || !need_resched())) {
406 afs_dispatch_fs_probe(net, server, server == fast);
407 first_pass = false;
408 goto again;
409 }
410
411 write_sequnlock(&net->fs_lock);
412
413 if (server) {
414 if (!queue_work(afs_wq, &net->fs_prober))
415 afs_dec_servers_outstanding(net);
416 _leave(" [requeue]");
417 } else if (set_timer) {
418 if (timer_reduce(&net->fs_probe_timer, timer_at))
419 afs_dec_servers_outstanding(net);
420 _leave(" [timer]");
421 } else {
422 afs_dec_servers_outstanding(net);
423 _leave(" [quiesce]");
424 }
425}
426
427/*
428 * Wait for a probe on a particular fileserver to complete for 2s.
429 */
430int afs_wait_for_one_fs_probe(struct afs_server *server, bool is_intr)
431{
432 struct wait_queue_entry wait;
433 unsigned long timo = 2 * HZ;
434
435 if (atomic_read(&server->probe_outstanding) == 0)
436 goto dont_wait;
437
438 init_wait_entry(&wait, 0);
439 for (;;) {
440 prepare_to_wait_event(&server->probe_wq, &wait,
441 is_intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
442 if (timo == 0 ||
443 server->probe.responded ||
444 atomic_read(&server->probe_outstanding) == 0 ||
445 (is_intr && signal_pending(current)))
446 break;
447 timo = schedule_timeout(timo);
448 }
449
450 finish_wait(&server->probe_wq, &wait);
451
452dont_wait:
453 if (server->probe.responded)
454 return 0;
455 if (is_intr && signal_pending(current))
456 return -ERESTARTSYS;
457 if (timo == 0)
458 return -ETIME;
459 return -EDESTADDRREQ;
460}
fs/afs/fsclient.c+511−794
@@ -13,12 +13,6 @@ · 12 unmodified lines
13#include "internal.h"13#include "internal.h"
14#include "afs_fs.h"14#include "afs_fs.h"
15#include "xdr_fs.h"15#include "xdr_fs.h"
16#include "protocol_yfs.h"
17
18static 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 * decode an AFSFid block18 * decode an AFSFid block
@@ -56,16 +50,15 @@ static void xdr_dump_bad(const __be32 *bp) · 31 unmodified lines
56/*50/*
57 * decode an AFSFetchStatus block51 * decode an AFSFetchStatus block
58 */52 */
59static int xdr_decode_AFSFetchStatus(const __be32 **_bp,53static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
60 struct afs_call *call,54 struct afs_call *call,
61 struct afs_status_cb *scb)55 struct afs_status_cb *scb)
62{56{
63 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;57 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
64 struct afs_file_status *status = &scb->status;58 struct afs_file_status *status = &scb->status;
65 bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);59 bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
66 u64 data_version, size;60 u64 data_version, size;
67 u32 type, abort_code;61 u32 type, abort_code;
68 int ret;
69 62
70 abort_code = ntohl(xdr->abort_code);63 abort_code = ntohl(xdr->abort_code);
71 64
@@ -79,7 +72,7 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp, · 7 unmodified lines
79 */72 */
80 status->abort_code = abort_code;73 status->abort_code = abort_code;
81 scb->have_error = true;74 scb->have_error = true;
82 goto good;75 goto advance;
83 }76 }
84 77
85 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));78 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
@@ -89,7 +82,7 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp, · 3 unmodified lines
89 if (abort_code != 0 && inline_error) {82 if (abort_code != 0 && inline_error) {
90 status->abort_code = abort_code;83 status->abort_code = abort_code;
91 scb->have_error = true;84 scb->have_error = true;
92 goto good;85 goto advance;
93 }86 }
94 87
95 type = ntohl(xdr->type);88 type = ntohl(xdr->type);
@@ -125,15 +118,13 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp, · 29 unmodified lines
125 data_version |= (u64)ntohl(xdr->data_version_hi) << 32;118 data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
126 status->data_version = data_version;119 status->data_version = data_version;
127 scb->have_status = true;120 scb->have_status = true;
128good:
129 ret = 0;
130advance:121advance:
131 *_bp = (const void *)*_bp + sizeof(*xdr);122 *_bp = (const void *)*_bp + sizeof(*xdr);
132 return ret;123 return;
133 124
134bad:125bad:
135 xdr_dump_bad(*_bp);126 xdr_dump_bad(*_bp);
136 ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);127 afs_protocol_error(call, afs_eproto_bad_status);
137 goto advance;128 goto advance;
138}129}
139 130
@@ -243,8 +234,10 @@ static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp, · 103 unmodified lines
243/*234/*
244 * deliver reply data to an FS.FetchStatus235 * deliver reply data to an FS.FetchStatus
245 */236 */
246static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)237static int afs_deliver_fs_fetch_status(struct afs_call *call)
247{238{
239 struct afs_operation *op = call->op;
240 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
248 const __be32 *bp;241 const __be32 *bp;
249 int ret;242 int ret;
250 243
@@ -254,11 +247,9 @@ static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call) · 3 unmodified lines
254 247
255 /* unmarshall the reply once we've received all of it */248 /* unmarshall the reply once we've received all of it */
256 bp = call->buffer;249 bp = call->buffer;
257 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);250 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
258 if (ret < 0)251 xdr_decode_AFSCallBack(&bp, call, &vp->scb);
259 return ret;252 xdr_decode_AFSVolSync(&bp, &op->volsync);
260 xdr_decode_AFSCallBack(&bp, call, call->out_scb);
261 xdr_decode_AFSVolSync(&bp, call->out_volsync);
262 253
263 _leave(" = 0 [done]");254 _leave(" = 0 [done]");
264 return 0;255 return 0;
@@ -267,54 +258,39 @@ static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call) · 2 unmodified lines
267/*258/*
268 * FS.FetchStatus operation type259 * FS.FetchStatus operation type
269 */260 */
270static const struct afs_call_type afs_RXFSFetchStatus_vnode = {261static const struct afs_call_type afs_RXFSFetchStatus = {
271 .name = "FS.FetchStatus(vnode)",262 .name = "FS.FetchStatus",
272 .op = afs_FS_FetchStatus,263 .op = afs_FS_FetchStatus,
273 .deliver = afs_deliver_fs_fetch_status_vnode,264 .deliver = afs_deliver_fs_fetch_status,
274 .destructor = afs_flat_call_destructor,265 .destructor = afs_flat_call_destructor,
275};266};
276 267
277/*268/*
278 * fetch the status information for a file269 * fetch the status information for a file
279 */270 */
280int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb,271void afs_fs_fetch_status(struct afs_operation *op)
281 struct afs_volsync *volsync)
282{272{
283 struct afs_vnode *vnode = fc->vnode;273 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
284 struct afs_call *call;274 struct afs_call *call;
285 struct afs_net *net = afs_v2net(vnode);
286 __be32 *bp;275 __be32 *bp;
287 276
288 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
289 return yfs_fs_fetch_file_status(fc, scb, volsync);
290
291 _enter(",%x,{%llx:%llu},,",277 _enter(",%x,{%llx:%llu},,",
292 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);278 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
293 279
294 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode,280 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchStatus,
295 16, (21 + 3 + 6) * 4);281 16, (21 + 3 + 6) * 4);
296 if (!call) {282 if (!call)
297 fc->ac.error = -ENOMEM;283 return afs_op_nomem(op);
298 return -ENOMEM;
299 }
300
301 call->key = fc->key;
302 call->out_scb = scb;
303 call->out_volsync = volsync;
304 284
305 /* marshall the parameters */285 /* marshall the parameters */
306 bp = call->request;286 bp = call->request;
307 bp[0] = htonl(FSFETCHSTATUS);287 bp[0] = htonl(FSFETCHSTATUS);
308 bp[1] = htonl(vnode->fid.vid);288 bp[1] = htonl(vp->fid.vid);
309 bp[2] = htonl(vnode->fid.vnode);289 bp[2] = htonl(vp->fid.vnode);
310 bp[3] = htonl(vnode->fid.unique);290 bp[3] = htonl(vp->fid.unique);
311 291
312 afs_use_fs_server(call, fc->cbi);292 trace_afs_make_fs_call(call, &vp->fid);
313 trace_afs_make_fs_call(call, &vnode->fid);293 afs_make_op_call(op, call, GFP_NOFS);
314
315 afs_set_fc_call(call, fc);
316 afs_make_call(&fc->ac, call, GFP_NOFS);
317 return afs_wait_for_call_to_complete(call, &fc->ac);
318}294}
319 295
320/*296/*
@@ -322,7 +298,9 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb · 1 unmodified line
322 */298 */
323static int afs_deliver_fs_fetch_data(struct afs_call *call)299static int afs_deliver_fs_fetch_data(struct afs_call *call)
324{300{
325 struct afs_read *req = call->read_request;301 struct afs_operation *op = call->op;
302 struct afs_vnode_param *vp = &op->file[0];
303 struct afs_read *req = op->fetch.req;
326 const __be32 *bp;304 const __be32 *bp;
327 unsigned int size;305 unsigned int size;
328 int ret;306 int ret;
@@ -419,14 +397,12 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) · 90 unmodified lines
419 return ret;397 return ret;
420 398
421 bp = call->buffer;399 bp = call->buffer;
422 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);400 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
423 if (ret < 0)401 xdr_decode_AFSCallBack(&bp, call, &vp->scb);
424 return ret;402 xdr_decode_AFSVolSync(&bp, &op->volsync);
425 xdr_decode_AFSCallBack(&bp, call, call->out_scb);
426 xdr_decode_AFSVolSync(&bp, call->out_volsync);
427 403
428 req->data_version = call->out_scb->status.data_version;404 req->data_version = vp->scb.status.data_version;
429 req->file_size = call->out_scb->status.size;405 req->file_size = vp->scb.status.size;
430 406
431 call->unmarshall++;407 call->unmarshall++;
432 408
@@ -449,14 +425,6 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) · 16 unmodified lines
449 return 0;425 return 0;
450}426}
451 427
452static void afs_fetch_data_destructor(struct afs_call *call)
453{
454 struct afs_read *req = call->read_request;
455
456 afs_put_read(req);
457 afs_flat_call_destructor(call);
458}
459
460/*428/*
461 * FS.FetchData operation type429 * FS.FetchData operation type
462 */430 */
@@ -464,102 +432,79 @@ static const struct afs_call_type afs_RXFSFetchData = { · 1 unmodified line
464 .name = "FS.FetchData",432 .name = "FS.FetchData",
465 .op = afs_FS_FetchData,433 .op = afs_FS_FetchData,
466 .deliver = afs_deliver_fs_fetch_data,434 .deliver = afs_deliver_fs_fetch_data,
467 .destructor = afs_fetch_data_destructor,435 .destructor = afs_flat_call_destructor,
468};436};
469 437
470static const struct afs_call_type afs_RXFSFetchData64 = {438static const struct afs_call_type afs_RXFSFetchData64 = {
471 .name = "FS.FetchData64",439 .name = "FS.FetchData64",
472 .op = afs_FS_FetchData64,440 .op = afs_FS_FetchData64,
473 .deliver = afs_deliver_fs_fetch_data,441 .deliver = afs_deliver_fs_fetch_data,
474 .destructor = afs_fetch_data_destructor,442 .destructor = afs_flat_call_destructor,
475};443};
476 444
477/*445/*
478 * fetch data from a very large file446 * fetch data from a very large file
479 */447 */
480static int afs_fs_fetch_data64(struct afs_fs_cursor *fc,448static void afs_fs_fetch_data64(struct afs_operation *op)
481 struct afs_status_cb *scb,
482 struct afs_read *req)
483{449{
484 struct afs_vnode *vnode = fc->vnode;450 struct afs_vnode_param *vp = &op->file[0];
451 struct afs_read *req = op->fetch.req;
485 struct afs_call *call;452 struct afs_call *call;
486 struct afs_net *net = afs_v2net(vnode);
487 __be32 *bp;453 __be32 *bp;
488 454
489 _enter("");455 _enter("");
490 456
491 call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);457 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
492 if (!call)458 if (!call)
493 return -ENOMEM;459 return afs_op_nomem(op);
494
495 call->key = fc->key;
496 call->out_scb = scb;
497 call->out_volsync = NULL;
498 call->read_request = afs_get_read(req);
499 460
500 /* marshall the parameters */461 /* marshall the parameters */
501 bp = call->request;462 bp = call->request;
502 bp[0] = htonl(FSFETCHDATA64);463 bp[0] = htonl(FSFETCHDATA64);
503 bp[1] = htonl(vnode->fid.vid);464 bp[1] = htonl(vp->fid.vid);
504 bp[2] = htonl(vnode->fid.vnode);465 bp[2] = htonl(vp->fid.vnode);
505 bp[3] = htonl(vnode->fid.unique);466 bp[3] = htonl(vp->fid.unique);
506 bp[4] = htonl(upper_32_bits(req->pos));467 bp[4] = htonl(upper_32_bits(req->pos));
507 bp[5] = htonl(lower_32_bits(req->pos));468 bp[5] = htonl(lower_32_bits(req->pos));
508 bp[6] = 0;469 bp[6] = 0;
509 bp[7] = htonl(lower_32_bits(req->len));470 bp[7] = htonl(lower_32_bits(req->len));
510 471
511 afs_use_fs_server(call, fc->cbi);472 trace_afs_make_fs_call(call, &vp->fid);
512 trace_afs_make_fs_call(call, &vnode->fid);473 afs_make_op_call(op, call, GFP_NOFS);
513 afs_set_fc_call(call, fc);
514 afs_make_call(&fc->ac, call, GFP_NOFS);
515 return afs_wait_for_call_to_complete(call, &fc->ac);
516}474}
517 475
518/*476/*
519 * fetch data from a file477 * fetch data from a file
520 */478 */
521int afs_fs_fetch_data(struct afs_fs_cursor *fc,479void afs_fs_fetch_data(struct afs_operation *op)
522 struct afs_status_cb *scb,
523 struct afs_read *req)
524{480{
525 struct afs_vnode *vnode = fc->vnode;481 struct afs_vnode_param *vp = &op->file[0];
526 struct afs_call *call;482 struct afs_call *call;
527 struct afs_net *net = afs_v2net(vnode);483 struct afs_read *req = op->fetch.req;
528 __be32 *bp;484 __be32 *bp;
529 485
530 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
531 return yfs_fs_fetch_data(fc, scb, req);
532
533 if (upper_32_bits(req->pos) ||486 if (upper_32_bits(req->pos) ||
534 upper_32_bits(req->len) ||487 upper_32_bits(req->len) ||
535 upper_32_bits(req->pos + req->len))488 upper_32_bits(req->pos + req->len))
536 return afs_fs_fetch_data64(fc, scb, req);489 return afs_fs_fetch_data64(op);
537 490
538 _enter("");491 _enter("");
539 492
540 call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);493 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
541 if (!call)494 if (!call)
542 return -ENOMEM;495 return afs_op_nomem(op);
543
544 call->key = fc->key;
545 call->out_scb = scb;
546 call->out_volsync = NULL;
547 call->read_request = afs_get_read(req);
548 496
549 /* marshall the parameters */497 /* marshall the parameters */
550 bp = call->request;498 bp = call->request;
551 bp[0] = htonl(FSFETCHDATA);499 bp[0] = htonl(FSFETCHDATA);
552 bp[1] = htonl(vnode->fid.vid);500 bp[1] = htonl(vp->fid.vid);
553 bp[2] = htonl(vnode->fid.vnode);501 bp[2] = htonl(vp->fid.vnode);
554 bp[3] = htonl(vnode->fid.unique);502 bp[3] = htonl(vp->fid.unique);
555 bp[4] = htonl(lower_32_bits(req->pos));503 bp[4] = htonl(lower_32_bits(req->pos));
556 bp[5] = htonl(lower_32_bits(req->len));504 bp[5] = htonl(lower_32_bits(req->len));
557 505
558 afs_use_fs_server(call, fc->cbi);506 trace_afs_make_fs_call(call, &vp->fid);
559 trace_afs_make_fs_call(call, &vnode->fid);507 afs_make_op_call(op, call, GFP_NOFS);
560 afs_set_fc_call(call, fc);
561 afs_make_call(&fc->ac, call, GFP_NOFS);
562 return afs_wait_for_call_to_complete(call, &fc->ac);
563}508}
564 509
565/*510/*
@@ -567,6 +512,9 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, · 1 unmodified line
567 */512 */
568static int afs_deliver_fs_create_vnode(struct afs_call *call)513static int afs_deliver_fs_create_vnode(struct afs_call *call)
569{514{
515 struct afs_operation *op = call->op;
516 struct afs_vnode_param *dvp = &op->file[0];
517 struct afs_vnode_param *vp = &op->file[1];
570 const __be32 *bp;518 const __be32 *bp;
571 int ret;519 int ret;
572 520
@@ -576,15 +524,11 @@ static int afs_deliver_fs_create_vnode(struct afs_call *call) · 3 unmodified lines
576 524
577 /* unmarshall the reply once we've received all of it */525 /* unmarshall the reply once we've received all of it */
578 bp = call->buffer;526 bp = call->buffer;
579 xdr_decode_AFSFid(&bp, call->out_fid);527 xdr_decode_AFSFid(&bp, &op->file[1].fid);
580 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);528 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
581 if (ret < 0)529 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);
582 return ret;530 xdr_decode_AFSCallBack(&bp, call, &vp->scb);
583 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);531 xdr_decode_AFSVolSync(&bp, &op->volsync);
584 if (ret < 0)
585 return ret;
586 xdr_decode_AFSCallBack(&bp, call, call->out_scb);
587 xdr_decode_AFSVolSync(&bp, call->out_volsync);
588 532
589 _leave(" = 0 [done]");533 _leave(" = 0 [done]");
590 return 0;534 return 0;
@@ -600,6 +544,52 @@ static const struct afs_call_type afs_RXFSCreateFile = { · 9 unmodified lines
600 .destructor = afs_flat_call_destructor,544 .destructor = afs_flat_call_destructor,
601};545};
602 546
547/*
548 * Create a file.
549 */
550void afs_fs_create_file(struct afs_operation *op)
551{
552 const struct qstr *name = &op->dentry->d_name;
553 struct afs_vnode_param *dvp = &op->file[0];
554 struct afs_call *call;
555 size_t namesz, reqsz, padsz;
556 __be32 *bp;
557
558 _enter("");
559
560 namesz = name->len;
561 padsz = (4 - (namesz & 3)) & 3;
562 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
563
564 call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile,
565 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
566 if (!call)
567 return afs_op_nomem(op);
568
569 /* marshall the parameters */
570 bp = call->request;
571 *bp++ = htonl(FSCREATEFILE);
572 *bp++ = htonl(dvp->fid.vid);
573 *bp++ = htonl(dvp->fid.vnode);
574 *bp++ = htonl(dvp->fid.unique);
575 *bp++ = htonl(namesz);
576 memcpy(bp, name->name, namesz);
577 bp = (void *) bp + namesz;
578 if (padsz > 0) {
579 memset(bp, 0, padsz);
580 bp = (void *) bp + padsz;
581 }
582 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
583 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
584 *bp++ = 0; /* owner */
585 *bp++ = 0; /* group */
586 *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */
587 *bp++ = 0; /* segment size */
588
589 trace_afs_make_fs_call1(call, &dvp->fid, name);
590 afs_make_op_call(op, call, GFP_NOFS);
591}
592
603static const struct afs_call_type afs_RXFSMakeDir = {593static const struct afs_call_type afs_RXFSMakeDir = {
604 .name = "FS.MakeDir",594 .name = "FS.MakeDir",
605 .op = afs_FS_MakeDir,595 .op = afs_FS_MakeDir,
@@ -608,80 +598,58 @@ static const struct afs_call_type afs_RXFSMakeDir = { · 2 unmodified lines
608};598};
609 599
610/*600/*
611 * create a file or make a directory601 * Create a new directory
612 */602 */
613int afs_fs_create(struct afs_fs_cursor *fc,603void afs_fs_make_dir(struct afs_operation *op)
614 const char *name,
615 umode_t mode,
616 struct afs_status_cb *dvnode_scb,
617 struct afs_fid *newfid,
618 struct afs_status_cb *new_scb)
619{604{
620 struct afs_vnode *dvnode = fc->vnode;605 const struct qstr *name = &op->dentry->d_name;
606 struct afs_vnode_param *dvp = &op->file[0];
621 struct afs_call *call;607 struct afs_call *call;
622 struct afs_net *net = afs_v2net(dvnode);
623 size_t namesz, reqsz, padsz;608 size_t namesz, reqsz, padsz;
624 __be32 *bp;609 __be32 *bp;
625 610
626 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)){
627 if (S_ISDIR(mode))
628 return yfs_fs_make_dir(fc, name, mode, dvnode_scb,
629 newfid, new_scb);
630 else
631 return yfs_fs_create_file(fc, name, mode, dvnode_scb,
632 newfid, new_scb);
633 }
634
635 _enter("");611 _enter("");
636 612
637 namesz = strlen(name);613 namesz = name->len;
638 padsz = (4 - (namesz & 3)) & 3;614 padsz = (4 - (namesz & 3)) & 3;
639 reqsz = (5 * 4) + namesz + padsz + (6 * 4);615 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
640 616
641 call = afs_alloc_flat_call(617 call = afs_alloc_flat_call(op->net, &afs_RXFSMakeDir,
642 net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile,618 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
643 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
644 if (!call)619 if (!call)
645 return -ENOMEM;620 return afs_op_nomem(op);
646
647 call->key = fc->key;
648 call->out_dir_scb = dvnode_scb;
649 call->out_fid = newfid;
650 call->out_scb = new_scb;
651 621
652 /* marshall the parameters */622 /* marshall the parameters */
653 bp = call->request;623 bp = call->request;
654 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);624 *bp++ = htonl(FSMAKEDIR);
655 *bp++ = htonl(dvnode->fid.vid);625 *bp++ = htonl(dvp->fid.vid);
656 *bp++ = htonl(dvnode->fid.vnode);626 *bp++ = htonl(dvp->fid.vnode);
657 *bp++ = htonl(dvnode->fid.unique);627 *bp++ = htonl(dvp->fid.unique);
658 *bp++ = htonl(namesz);628 *bp++ = htonl(namesz);
659 memcpy(bp, name, namesz);629 memcpy(bp, name->name, namesz);
660 bp = (void *) bp + namesz;630 bp = (void *) bp + namesz;
661 if (padsz > 0) {631 if (padsz > 0) {
662 memset(bp, 0, padsz);632 memset(bp, 0, padsz);
663 bp = (void *) bp + padsz;633 bp = (void *) bp + padsz;
664 }634 }
665 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);635 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
666 *bp++ = htonl(dvnode->vfs_inode.i_mtime.tv_sec); /* mtime */636 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
667 *bp++ = 0; /* owner */637 *bp++ = 0; /* owner */
668 *bp++ = 0; /* group */638 *bp++ = 0; /* group */
669 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */639 *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */
670 *bp++ = 0; /* segment size */640 *bp++ = 0; /* segment size */
671 641
672 afs_use_fs_server(call, fc->cbi);642 trace_afs_make_fs_call1(call, &dvp->fid, name);
673 trace_afs_make_fs_call1(call, &dvnode->fid, name);643 afs_make_op_call(op, call, GFP_NOFS);
674 afs_set_fc_call(call, fc);
675 afs_make_call(&fc->ac, call, GFP_NOFS);
676 return afs_wait_for_call_to_complete(call, &fc->ac);
677}644}
678 645
679/*646/*
680 * Deliver reply data to any operation that returns directory status and volume647 * Deliver reply data to any operation that returns status and volume sync.
681 * sync.
682 */648 */
683static int afs_deliver_fs_dir_status_and_vol(struct afs_call *call)649static int afs_deliver_fs_file_status_and_vol(struct afs_call *call)
684{650{
651 struct afs_operation *op = call->op;
652 struct afs_vnode_param *vp = &op->file[0];
685 const __be32 *bp;653 const __be32 *bp;
686 int ret;654 int ret;
687 655
@@ -691,81 +659,108 @@ static int afs_deliver_fs_dir_status_and_vol(struct afs_call *call) · 3 unmodified lines
691 659
692 /* unmarshall the reply once we've received all of it */660 /* unmarshall the reply once we've received all of it */
693 bp = call->buffer;661 bp = call->buffer;
694 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);662 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
695 if (ret < 0)663 xdr_decode_AFSVolSync(&bp, &op->volsync);
696 return ret;
697 xdr_decode_AFSVolSync(&bp, call->out_volsync);
698 664
699 _leave(" = 0 [done]");665 _leave(" = 0 [done]");
700 return 0;666 return 0;
701}667}
702 668
703/*669/*
704 * FS.RemoveDir/FS.RemoveFile operation type670 * FS.RemoveFile operation type
705 */671 */
706static const struct afs_call_type afs_RXFSRemoveFile = {672static const struct afs_call_type afs_RXFSRemoveFile = {
707 .name = "FS.RemoveFile",673 .name = "FS.RemoveFile",
708 .op = afs_FS_RemoveFile,674 .op = afs_FS_RemoveFile,
709 .deliver = afs_deliver_fs_dir_status_and_vol,675 .deliver = afs_deliver_fs_file_status_and_vol,
710 .destructor = afs_flat_call_destructor,676 .destructor = afs_flat_call_destructor,
711};677};
712 678
679/*
680 * Remove a file.
681 */
682void afs_fs_remove_file(struct afs_operation *op)
683{
684 const struct qstr *name = &op->dentry->d_name;
685 struct afs_vnode_param *dvp = &op->file[0];
686 struct afs_call *call;
687 size_t namesz, reqsz, padsz;
688 __be32 *bp;
689
690 _enter("");
691
692 namesz = name->len;
693 padsz = (4 - (namesz & 3)) & 3;
694 reqsz = (5 * 4) + namesz + padsz;
695
696 call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveFile,
697 reqsz, (21 + 6) * 4);
698 if (!call)
699 return afs_op_nomem(op);
700
701 /* marshall the parameters */
702 bp = call->request;
703 *bp++ = htonl(FSREMOVEFILE);
704 *bp++ = htonl(dvp->fid.vid);
705 *bp++ = htonl(dvp->fid.vnode);
706 *bp++ = htonl(dvp->fid.unique);
707 *bp++ = htonl(namesz);
708 memcpy(bp, name->name, namesz);
709 bp = (void *) bp + namesz;
710 if (padsz > 0) {
711 memset(bp, 0, padsz);
712 bp = (void *) bp + padsz;
713 }
714
715 trace_afs_make_fs_call1(call, &dvp->fid, name);
716 afs_make_op_call(op, call, GFP_NOFS);
717}
718
713static const struct afs_call_type afs_RXFSRemoveDir = {719static const struct afs_call_type afs_RXFSRemoveDir = {
714 .name = "FS.RemoveDir",720 .name = "FS.RemoveDir",
715 .op = afs_FS_RemoveDir,721 .op = afs_FS_RemoveDir,
716 .deliver = afs_deliver_fs_dir_status_and_vol,722 .deliver = afs_deliver_fs_file_status_and_vol,
717 .destructor = afs_flat_call_destructor,723 .destructor = afs_flat_call_destructor,
718};724};
719 725
720/*726/*
721 * remove a file or directory727 * Remove a directory.
722 */728 */
723int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,729void afs_fs_remove_dir(struct afs_operation *op)
724 const char *name, bool isdir, struct afs_status_cb *dvnode_scb)
725{730{
726 struct afs_vnode *dvnode = fc->vnode;731 const struct qstr *name = &op->dentry->d_name;
732 struct afs_vnode_param *dvp = &op->file[0];
727 struct afs_call *call;733 struct afs_call *call;
728 struct afs_net *net = afs_v2net(dvnode);
729 size_t namesz, reqsz, padsz;734 size_t namesz, reqsz, padsz;
730 __be32 *bp;735 __be32 *bp;
731 736
732 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
733 return yfs_fs_remove(fc, vnode, name, isdir, dvnode_scb);
734
735 _enter("");737 _enter("");
736 738
737 namesz = strlen(name);739 namesz = name->len;
738 padsz = (4 - (namesz & 3)) & 3;740 padsz = (4 - (namesz & 3)) & 3;
739 reqsz = (5 * 4) + namesz + padsz;741 reqsz = (5 * 4) + namesz + padsz;
740 742
741 call = afs_alloc_flat_call(743 call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveDir,
742 net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile,744 reqsz, (21 + 6) * 4);
743 reqsz, (21 + 6) * 4);
744 if (!call)745 if (!call)
745 return -ENOMEM;746 return afs_op_nomem(op);
746
747 call->key = fc->key;
748 call->out_dir_scb = dvnode_scb;
749 747
750 /* marshall the parameters */748 /* marshall the parameters */
751 bp = call->request;749 bp = call->request;
752 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);750 *bp++ = htonl(FSREMOVEDIR);
753 *bp++ = htonl(dvnode->fid.vid);751 *bp++ = htonl(dvp->fid.vid);
754 *bp++ = htonl(dvnode->fid.vnode);752 *bp++ = htonl(dvp->fid.vnode);
755 *bp++ = htonl(dvnode->fid.unique);753 *bp++ = htonl(dvp->fid.unique);
756 *bp++ = htonl(namesz);754 *bp++ = htonl(namesz);
757 memcpy(bp, name, namesz);755 memcpy(bp, name->name, namesz);
758 bp = (void *) bp + namesz;756 bp = (void *) bp + namesz;
759 if (padsz > 0) {757 if (padsz > 0) {
760 memset(bp, 0, padsz);758 memset(bp, 0, padsz);
761 bp = (void *) bp + padsz;759 bp = (void *) bp + padsz;
762 }760 }
763 761
764 afs_use_fs_server(call, fc->cbi);762 trace_afs_make_fs_call1(call, &dvp->fid, name);
765 trace_afs_make_fs_call1(call, &dvnode->fid, name);763 afs_make_op_call(op, call, GFP_NOFS);
766 afs_set_fc_call(call, fc);
767 afs_make_call(&fc->ac, call, GFP_NOFS);
768 return afs_wait_for_call_to_complete(call, &fc->ac);
769}764}
770 765
771/*766/*
@@ -773,6 +768,9 @@ int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, · 1 unmodified line
773 */768 */
774static int afs_deliver_fs_link(struct afs_call *call)769static int afs_deliver_fs_link(struct afs_call *call)
775{770{
771 struct afs_operation *op = call->op;
772 struct afs_vnode_param *dvp = &op->file[0];
773 struct afs_vnode_param *vp = &op->file[1];
776 const __be32 *bp;774 const __be32 *bp;
777 int ret;775 int ret;
778 776
@@ -784,13 +782,9 @@ static int afs_deliver_fs_link(struct afs_call *call) · 5 unmodified lines
784 782
785 /* unmarshall the reply once we've received all of it */783 /* unmarshall the reply once we've received all of it */
786 bp = call->buffer;784 bp = call->buffer;
787 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);785 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
788 if (ret < 0)786 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);
789 return ret;787 xdr_decode_AFSVolSync(&bp, &op->volsync);
790 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
791 if (ret < 0)
792 return ret;
793 xdr_decode_AFSVolSync(&bp, call->out_volsync);
794 788
795 _leave(" = 0 [done]");789 _leave(" = 0 [done]");
796 return 0;790 return 0;
@@ -809,56 +803,44 @@ static const struct afs_call_type afs_RXFSLink = { · 12 unmodified lines
809/*803/*
810 * make a hard link804 * make a hard link
811 */805 */
812int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,806void afs_fs_link(struct afs_operation *op)
813 const char *name,
814 struct afs_status_cb *dvnode_scb,
815 struct afs_status_cb *vnode_scb)
816{807{
817 struct afs_vnode *dvnode = fc->vnode;808 const struct qstr *name = &op->dentry->d_name;
809 struct afs_vnode_param *dvp = &op->file[0];
810 struct afs_vnode_param *vp = &op->file[1];
818 struct afs_call *call;811 struct afs_call *call;
819 struct afs_net *net = afs_v2net(vnode);
820 size_t namesz, reqsz, padsz;812 size_t namesz, reqsz, padsz;
821 __be32 *bp;813 __be32 *bp;
822 814
823 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
824 return yfs_fs_link(fc, vnode, name, dvnode_scb, vnode_scb);
825
826 _enter("");815 _enter("");
827 816
828 namesz = strlen(name);817 namesz = name->len;
829 padsz = (4 - (namesz & 3)) & 3;818 padsz = (4 - (namesz & 3)) & 3;
830 reqsz = (5 * 4) + namesz + padsz + (3 * 4);819 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
831 820
832 call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);821 call = afs_alloc_flat_call(op->net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
833 if (!call)822 if (!call)
834 return -ENOMEM;823 return afs_op_nomem(op);
835
836 call->key = fc->key;
837 call->out_dir_scb = dvnode_scb;
838 call->out_scb = vnode_scb;
839 824
840 /* marshall the parameters */825 /* marshall the parameters */
841 bp = call->request;826 bp = call->request;
842 *bp++ = htonl(FSLINK);827 *bp++ = htonl(FSLINK);
843 *bp++ = htonl(dvnode->fid.vid);828 *bp++ = htonl(dvp->fid.vid);
844 *bp++ = htonl(dvnode->fid.vnode);829 *bp++ = htonl(dvp->fid.vnode);
845 *bp++ = htonl(dvnode->fid.unique);830 *bp++ = htonl(dvp->fid.unique);
846 *bp++ = htonl(namesz);831 *bp++ = htonl(namesz);
847 memcpy(bp, name, namesz);832 memcpy(bp, name->name, namesz);
848 bp = (void *) bp + namesz;833 bp = (void *) bp + namesz;
849 if (padsz > 0) {834 if (padsz > 0) {
850 memset(bp, 0, padsz);835 memset(bp, 0, padsz);
851 bp = (void *) bp + padsz;836 bp = (void *) bp + padsz;
852 }837 }
853 *bp++ = htonl(vnode->fid.vid);838 *bp++ = htonl(vp->fid.vid);
854 *bp++ = htonl(vnode->fid.vnode);839 *bp++ = htonl(vp->fid.vnode);
855 *bp++ = htonl(vnode->fid.unique);840 *bp++ = htonl(vp->fid.unique);
856 841
857 afs_use_fs_server(call, fc->cbi);842 trace_afs_make_fs_call1(call, &vp->fid, name);
858 trace_afs_make_fs_call1(call, &vnode->fid, name);843 afs_make_op_call(op, call, GFP_NOFS);
859 afs_set_fc_call(call, fc);
860 afs_make_call(&fc->ac, call, GFP_NOFS);
861 return afs_wait_for_call_to_complete(call, &fc->ac);
862}844}
863 845
864/*846/*
@@ -866,6 +848,9 @@ int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, · 1 unmodified line
866 */848 */
867static int afs_deliver_fs_symlink(struct afs_call *call)849static int afs_deliver_fs_symlink(struct afs_call *call)
868{850{
851 struct afs_operation *op = call->op;
852 struct afs_vnode_param *dvp = &op->file[0];
853 struct afs_vnode_param *vp = &op->file[1];
869 const __be32 *bp;854 const __be32 *bp;
870 int ret;855 int ret;
871 856
@@ -877,14 +862,10 @@ static int afs_deliver_fs_symlink(struct afs_call *call) · 5 unmodified lines
877 862
878 /* unmarshall the reply once we've received all of it */863 /* unmarshall the reply once we've received all of it */
879 bp = call->buffer;864 bp = call->buffer;
880 xdr_decode_AFSFid(&bp, call->out_fid);865 xdr_decode_AFSFid(&bp, &vp->fid);
881 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);866 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
882 if (ret < 0)867 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);
883 return ret;868 xdr_decode_AFSVolSync(&bp, &op->volsync);
884 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
885 if (ret < 0)
886 return ret;
887 xdr_decode_AFSVolSync(&bp, call->out_volsync);
888 869
889 _leave(" = 0 [done]");870 _leave(" = 0 [done]");
890 return 0;871 return 0;
@@ -903,75 +884,58 @@ static const struct afs_call_type afs_RXFSSymlink = { · 12 unmodified lines
903/*884/*
904 * create a symbolic link885 * create a symbolic link
905 */886 */
906int afs_fs_symlink(struct afs_fs_cursor *fc,887void afs_fs_symlink(struct afs_operation *op)
907 const char *name,
908 const char *contents,
909 struct afs_status_cb *dvnode_scb,
910 struct afs_fid *newfid,
911 struct afs_status_cb *new_scb)
912{888{
913 struct afs_vnode *dvnode = fc->vnode;889 const struct qstr *name = &op->dentry->d_name;
890 struct afs_vnode_param *dvp = &op->file[0];
914 struct afs_call *call;891 struct afs_call *call;
915 struct afs_net *net = afs_v2net(dvnode);
916 size_t namesz, reqsz, padsz, c_namesz, c_padsz;892 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
917 __be32 *bp;893 __be32 *bp;
918 894
919 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
920 return yfs_fs_symlink(fc, name, contents, dvnode_scb,
921 newfid, new_scb);
922
923 _enter("");895 _enter("");
924 896
925 namesz = strlen(name);897 namesz = name->len;
926 padsz = (4 - (namesz & 3)) & 3;898 padsz = (4 - (namesz & 3)) & 3;
927 899
928 c_namesz = strlen(contents);900 c_namesz = strlen(op->create.symlink);
929 c_padsz = (4 - (c_namesz & 3)) & 3;901 c_padsz = (4 - (c_namesz & 3)) & 3;
930 902
931 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);903 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
932 904
933 call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,905 call = afs_alloc_flat_call(op->net, &afs_RXFSSymlink, reqsz,
934 (3 + 21 + 21 + 6) * 4);906 (3 + 21 + 21 + 6) * 4);
935 if (!call)907 if (!call)
936 return -ENOMEM;908 return afs_op_nomem(op);
937
938 call->key = fc->key;
939 call->out_dir_scb = dvnode_scb;
940 call->out_fid = newfid;
941 call->out_scb = new_scb;
942 909
943 /* marshall the parameters */910 /* marshall the parameters */
944 bp = call->request;911 bp = call->request;
945 *bp++ = htonl(FSSYMLINK);912 *bp++ = htonl(FSSYMLINK);
946 *bp++ = htonl(dvnode->fid.vid);913 *bp++ = htonl(dvp->fid.vid);
947 *bp++ = htonl(dvnode->fid.vnode);914 *bp++ = htonl(dvp->fid.vnode);
948 *bp++ = htonl(dvnode->fid.unique);915 *bp++ = htonl(dvp->fid.unique);
949 *bp++ = htonl(namesz);916 *bp++ = htonl(namesz);
950 memcpy(bp, name, namesz);917 memcpy(bp, name->name, namesz);
951 bp = (void *) bp + namesz;918 bp = (void *) bp + namesz;
952 if (padsz > 0) {919 if (padsz > 0) {
953 memset(bp, 0, padsz);920 memset(bp, 0, padsz);
954 bp = (void *) bp + padsz;921 bp = (void *) bp + padsz;
955 }922 }
956 *bp++ = htonl(c_namesz);923 *bp++ = htonl(c_namesz);
957 memcpy(bp, contents, c_namesz);924 memcpy(bp, op->create.symlink, c_namesz);
958 bp = (void *) bp + c_namesz;925 bp = (void *) bp + c_namesz;
959 if (c_padsz > 0) {926 if (c_padsz > 0) {
960 memset(bp, 0, c_padsz);927 memset(bp, 0, c_padsz);
961 bp = (void *) bp + c_padsz;928 bp = (void *) bp + c_padsz;
962 }929 }
963 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);930 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
964 *bp++ = htonl(dvnode->vfs_inode.i_mtime.tv_sec); /* mtime */931 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
965 *bp++ = 0; /* owner */932 *bp++ = 0; /* owner */
966 *bp++ = 0; /* group */933 *bp++ = 0; /* group */
967 *bp++ = htonl(S_IRWXUGO); /* unix mode */934 *bp++ = htonl(S_IRWXUGO); /* unix mode */
968 *bp++ = 0; /* segment size */935 *bp++ = 0; /* segment size */
969 936
970 afs_use_fs_server(call, fc->cbi);937 trace_afs_make_fs_call1(call, &dvp->fid, name);
971 trace_afs_make_fs_call1(call, &dvnode->fid, name);938 afs_make_op_call(op, call, GFP_NOFS);
972 afs_set_fc_call(call, fc);
973 afs_make_call(&fc->ac, call, GFP_NOFS);
974 return afs_wait_for_call_to_complete(call, &fc->ac);
975}939}
976 940
977/*941/*
@@ -979,6 +943,9 @@ int afs_fs_symlink(struct afs_fs_cursor *fc, · 1 unmodified line
979 */943 */
980static int afs_deliver_fs_rename(struct afs_call *call)944static int afs_deliver_fs_rename(struct afs_call *call)
981{945{
946 struct afs_operation *op = call->op;
947 struct afs_vnode_param *orig_dvp = &op->file[0];
948 struct afs_vnode_param *new_dvp = &op->file[1];
982 const __be32 *bp;949 const __be32 *bp;
983 int ret;950 int ret;
984 951
@@ -986,17 +953,13 @@ static int afs_deliver_fs_rename(struct afs_call *call) · 1 unmodified line
986 if (ret < 0)953 if (ret < 0)
987 return ret;954 return ret;
988 955
956 bp = call->buffer;
989 /* If the two dirs are the same, we have two copies of the same status957 /* If the two dirs are the same, we have two copies of the same status
990 * report, so we just decode it twice.958 * report, so we just decode it twice.
991 */959 */
992 bp = call->buffer;960 xdr_decode_AFSFetchStatus(&bp, call, &orig_dvp->scb);
993 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);961 xdr_decode_AFSFetchStatus(&bp, call, &new_dvp->scb);
994 if (ret < 0)962 xdr_decode_AFSVolSync(&bp, &op->volsync);
995 return ret;
996 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
997 if (ret < 0)
998 return ret;
999 xdr_decode_AFSVolSync(&bp, call->out_volsync);
1000 963
1001 _leave(" = 0 [done]");964 _leave(" = 0 [done]");
1002 return 0;965 return 0;
@@ -1015,31 +978,22 @@ static const struct afs_call_type afs_RXFSRename = { · 12 unmodified lines
1015/*978/*
1016 * Rename/move a file or directory.979 * Rename/move a file or directory.
1017 */980 */
1018int afs_fs_rename(struct afs_fs_cursor *fc,981void afs_fs_rename(struct afs_operation *op)
1019 const char *orig_name,
1020 struct afs_vnode *new_dvnode,
1021 const char *new_name,
1022 struct afs_status_cb *orig_dvnode_scb,
1023 struct afs_status_cb *new_dvnode_scb)
1024{982{
1025 struct afs_vnode *orig_dvnode = fc->vnode;983 struct afs_vnode_param *orig_dvp = &op->file[0];
984 struct afs_vnode_param *new_dvp = &op->file[1];
985 const struct qstr *orig_name = &op->dentry->d_name;
986 const struct qstr *new_name = &op->dentry_2->d_name;
1026 struct afs_call *call;987 struct afs_call *call;
1027 struct afs_net *net = afs_v2net(orig_dvnode);
1028 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;988 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1029 __be32 *bp;989 __be32 *bp;
1030 990
1031 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1032 return yfs_fs_rename(fc, orig_name,
1033 new_dvnode, new_name,
1034 orig_dvnode_scb,
1035 new_dvnode_scb);
1036
1037 _enter("");991 _enter("");
1038 992
1039 o_namesz = strlen(orig_name);993 o_namesz = orig_name->len;
1040 o_padsz = (4 - (o_namesz & 3)) & 3;994 o_padsz = (4 - (o_namesz & 3)) & 3;
1041 995
1042 n_namesz = strlen(new_name);996 n_namesz = new_name->len;
1043 n_padsz = (4 - (n_namesz & 3)) & 3;997 n_padsz = (4 - (n_namesz & 3)) & 3;
1044 998
1045 reqsz = (4 * 4) +999 reqsz = (4 * 4) +
@@ -1047,51 +1001,46 @@ int afs_fs_rename(struct afs_fs_cursor *fc, · 1 unmodified line
1047 (3 * 4) +1001 (3 * 4) +
1048 4 + n_namesz + n_padsz;1002 4 + n_namesz + n_padsz;
1049 1003
1050 call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);1004 call = afs_alloc_flat_call(op->net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1051 if (!call)1005 if (!call)
1052 return -ENOMEM;1006 return afs_op_nomem(op);
1053
1054 call->key = fc->key;
1055 call->out_dir_scb = orig_dvnode_scb;
1056 call->out_scb = new_dvnode_scb;
1057 1007
1058 /* marshall the parameters */1008 /* marshall the parameters */
1059 bp = call->request;1009 bp = call->request;
1060 *bp++ = htonl(FSRENAME);1010 *bp++ = htonl(FSRENAME);
1061 *bp++ = htonl(orig_dvnode->fid.vid);1011 *bp++ = htonl(orig_dvp->fid.vid);
1062 *bp++ = htonl(orig_dvnode->fid.vnode);1012 *bp++ = htonl(orig_dvp->fid.vnode);
1063 *bp++ = htonl(orig_dvnode->fid.unique);1013 *bp++ = htonl(orig_dvp->fid.unique);
1064 *bp++ = htonl(o_namesz);1014 *bp++ = htonl(o_namesz);
1065 memcpy(bp, orig_name, o_namesz);1015 memcpy(bp, orig_name->name, o_namesz);
1066 bp = (void *) bp + o_namesz;1016 bp = (void *) bp + o_namesz;
1067 if (o_padsz > 0) {1017 if (o_padsz > 0) {
1068 memset(bp, 0, o_padsz);1018 memset(bp, 0, o_padsz);
1069 bp = (void *) bp + o_padsz;1019 bp = (void *) bp + o_padsz;
1070 }1020 }
1071 1021
1072 *bp++ = htonl(new_dvnode->fid.vid);1022 *bp++ = htonl(new_dvp->fid.vid);
1073 *bp++ = htonl(new_dvnode->fid.vnode);1023 *bp++ = htonl(new_dvp->fid.vnode);
1074 *bp++ = htonl(new_dvnode->fid.unique);1024 *bp++ = htonl(new_dvp->fid.unique);
1075 *bp++ = htonl(n_namesz);1025 *bp++ = htonl(n_namesz);
1076 memcpy(bp, new_name, n_namesz);1026 memcpy(bp, new_name->name, n_namesz);
1077 bp = (void *) bp + n_namesz;1027 bp = (void *) bp + n_namesz;
1078 if (n_padsz > 0) {1028 if (n_padsz > 0) {
1079 memset(bp, 0, n_padsz);1029 memset(bp, 0, n_padsz);
1080 bp = (void *) bp + n_padsz;1030 bp = (void *) bp + n_padsz;
1081 }1031 }
1082 1032
1083 afs_use_fs_server(call, fc->cbi);1033 trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1084 trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);1034 afs_make_op_call(op, call, GFP_NOFS);
1085 afs_set_fc_call(call, fc);
1086 afs_make_call(&fc->ac, call, GFP_NOFS);
1087 return afs_wait_for_call_to_complete(call, &fc->ac);
1088}1035}
1089 1036
1090/*1037/*
1091 * deliver reply data to an FS.StoreData1038 * Deliver reply data to FS.StoreData or FS.StoreStatus
1092 */1039 */
1093static int afs_deliver_fs_store_data(struct afs_call *call)1040static int afs_deliver_fs_store_data(struct afs_call *call)
1094{1041{
1042 struct afs_operation *op = call->op;
1043 struct afs_vnode_param *vp = &op->file[0];
1095 const __be32 *bp;1044 const __be32 *bp;
1096 int ret;1045 int ret;
1097 1046
@@ -1103,10 +1052,8 @@ static int afs_deliver_fs_store_data(struct afs_call *call) · 5 unmodified lines
1103 1052
1104 /* unmarshall the reply once we've received all of it */1053 /* unmarshall the reply once we've received all of it */
1105 bp = call->buffer;1054 bp = call->buffer;
1106 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);1055 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
1107 if (ret < 0)1056 xdr_decode_AFSVolSync(&bp, &op->volsync);
1108 return ret;
1109 xdr_decode_AFSVolSync(&bp, call->out_volsync);
1110 1057
1111 _leave(" = 0 [done]");1058 _leave(" = 0 [done]");
1112 return 0;1059 return 0;
@@ -1132,90 +1079,69 @@ static const struct afs_call_type afs_RXFSStoreData64 = { · 19 unmodified lines
1132/*1079/*
1133 * store a set of pages to a very large file1080 * store a set of pages to a very large file
1134 */1081 */
1135static int afs_fs_store_data64(struct afs_fs_cursor *fc,1082static void afs_fs_store_data64(struct afs_operation *op,
1136 struct address_space *mapping,1083 loff_t pos, loff_t size, loff_t i_size)
1137 pgoff_t first, pgoff_t last,
1138 unsigned offset, unsigned to,
1139 loff_t size, loff_t pos, loff_t i_size,
1140 struct afs_status_cb *scb)
1141{1084{
1142 struct afs_vnode *vnode = fc->vnode;1085 struct afs_vnode_param *vp = &op->file[0];
1143 struct afs_call *call;1086 struct afs_call *call;
1144 struct afs_net *net = afs_v2net(vnode);
1145 __be32 *bp;1087 __be32 *bp;
1146 1088
1147 _enter(",%x,{%llx:%llu},,",1089 _enter(",%x,{%llx:%llu},,",
1148 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1090 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1149 1091
1150 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,1092 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64,
1151 (4 + 6 + 3 * 2) * 4,1093 (4 + 6 + 3 * 2) * 4,
1152 (21 + 6) * 4);1094 (21 + 6) * 4);
1153 if (!call)1095 if (!call)
1154 return -ENOMEM;1096 return afs_op_nomem(op);
1155 1097
1156 call->key = fc->key;
1157 call->mapping = mapping;
1158 call->first = first;
1159 call->last = last;
1160 call->first_offset = offset;
1161 call->last_to = to;
1162 call->send_pages = true;1098 call->send_pages = true;
1163 call->out_scb = scb;
1164 1099
1165 /* marshall the parameters */1100 /* marshall the parameters */
1166 bp = call->request;1101 bp = call->request;
1167 *bp++ = htonl(FSSTOREDATA64);1102 *bp++ = htonl(FSSTOREDATA64);
1168 *bp++ = htonl(vnode->fid.vid);1103 *bp++ = htonl(vp->fid.vid);
1169 *bp++ = htonl(vnode->fid.vnode);1104 *bp++ = htonl(vp->fid.vnode);
1170 *bp++ = htonl(vnode->fid.unique);1105 *bp++ = htonl(vp->fid.unique);
1171 1106
1172 *bp++ = htonl(AFS_SET_MTIME); /* mask */1107 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1173 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */1108 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
1174 *bp++ = 0; /* owner */1109 *bp++ = 0; /* owner */
1175 *bp++ = 0; /* group */1110 *bp++ = 0; /* group */
1176 *bp++ = 0; /* unix mode */1111 *bp++ = 0; /* unix mode */
1177 *bp++ = 0; /* segment size */1112 *bp++ = 0; /* segment size */
1178 1113
1179 *bp++ = htonl(pos >> 32);1114 *bp++ = htonl(upper_32_bits(pos));
1180 *bp++ = htonl((u32) pos);1115 *bp++ = htonl(lower_32_bits(pos));
1181 *bp++ = htonl(size >> 32);1116 *bp++ = htonl(upper_32_bits(size));
1182 *bp++ = htonl((u32) size);1117 *bp++ = htonl(lower_32_bits(size));
1183 *bp++ = htonl(i_size >> 32);1118 *bp++ = htonl(upper_32_bits(i_size));
1184 *bp++ = htonl((u32) i_size);1119 *bp++ = htonl(lower_32_bits(i_size));
1185 1120
1186 trace_afs_make_fs_call(call, &vnode->fid);1121 trace_afs_make_fs_call(call, &vp->fid);
1187 afs_set_fc_call(call, fc);1122 afs_make_op_call(op, call, GFP_NOFS);
1188 afs_make_call(&fc->ac, call, GFP_NOFS);
1189 return afs_wait_for_call_to_complete(call, &fc->ac);
1190}1123}
1191 1124
1192/*1125/*
1193 * store a set of pages1126 * store a set of pages
1194 */1127 */
1195int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,1128void afs_fs_store_data(struct afs_operation *op)
1196 pgoff_t first, pgoff_t last,
1197 unsigned offset, unsigned to,
1198 struct afs_status_cb *scb)
1199{1129{
1200 struct afs_vnode *vnode = fc->vnode;1130 struct afs_vnode_param *vp = &op->file[0];
1201 struct afs_call *call;1131 struct afs_call *call;
1202 struct afs_net *net = afs_v2net(vnode);
1203 loff_t size, pos, i_size;1132 loff_t size, pos, i_size;
1204 __be32 *bp;1133 __be32 *bp;
1205 1134
1206 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1207 return yfs_fs_store_data(fc, mapping, first, last, offset, to, scb);
1208
1209 _enter(",%x,{%llx:%llu},,",1135 _enter(",%x,{%llx:%llu},,",
1210 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1136 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1211 1137
1212 size = (loff_t)to - (loff_t)offset;1138 size = (loff_t)op->store.last_to - (loff_t)op->store.first_offset;
1213 if (first != last)1139 if (op->store.first != op->store.last)
1214 size += (loff_t)(last - first) << PAGE_SHIFT;1140 size += (loff_t)(op->store.last - op->store.first) << PAGE_SHIFT;
1215 pos = (loff_t)first << PAGE_SHIFT;1141 pos = (loff_t)op->store.first << PAGE_SHIFT;
1216 pos += offset;1142 pos += op->store.first_offset;
1217 1143
1218 i_size = i_size_read(&vnode->vfs_inode);1144 i_size = i_size_read(&vp->vnode->vfs_inode);
1219 if (pos + size > i_size)1145 if (pos + size > i_size)
1220 i_size = size + pos;1146 i_size = size + pos;
1221 1147
@@ -1223,73 +1149,38 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, · 1 unmodified line
1223 (unsigned long long) size, (unsigned long long) pos,1149 (unsigned long long) size, (unsigned long long) pos,
1224 (unsigned long long) i_size);1150 (unsigned long long) i_size);
1225 1151
1226 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)1152 if (upper_32_bits(pos) || upper_32_bits(i_size) || upper_32_bits(size) ||
1227 return afs_fs_store_data64(fc, mapping, first, last, offset, to,1153 upper_32_bits(pos + size))
1228 size, pos, i_size, scb);1154 return afs_fs_store_data64(op, pos, size, i_size);
1229 1155
1230 call = afs_alloc_flat_call(net, &afs_RXFSStoreData,1156 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData,
1231 (4 + 6 + 3) * 4,1157 (4 + 6 + 3) * 4,
1232 (21 + 6) * 4);1158 (21 + 6) * 4);
1233 if (!call)1159 if (!call)
1234 return -ENOMEM;1160 return afs_op_nomem(op);
1235 1161
1236 call->key = fc->key;
1237 call->mapping = mapping;
1238 call->first = first;
1239 call->last = last;
1240 call->first_offset = offset;
1241 call->last_to = to;
1242 call->send_pages = true;1162 call->send_pages = true;
1243 call->out_scb = scb;
1244 1163
1245 /* marshall the parameters */1164 /* marshall the parameters */
1246 bp = call->request;1165 bp = call->request;
1247 *bp++ = htonl(FSSTOREDATA);1166 *bp++ = htonl(FSSTOREDATA);
1248 *bp++ = htonl(vnode->fid.vid);1167 *bp++ = htonl(vp->fid.vid);
1249 *bp++ = htonl(vnode->fid.vnode);1168 *bp++ = htonl(vp->fid.vnode);
1250 *bp++ = htonl(vnode->fid.unique);1169 *bp++ = htonl(vp->fid.unique);
1251 1170
1252 *bp++ = htonl(AFS_SET_MTIME); /* mask */1171 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1253 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */1172 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
1254 *bp++ = 0; /* owner */1173 *bp++ = 0; /* owner */
1255 *bp++ = 0; /* group */1174 *bp++ = 0; /* group */
1256 *bp++ = 0; /* unix mode */1175 *bp++ = 0; /* unix mode */
1257 *bp++ = 0; /* segment size */1176 *bp++ = 0; /* segment size */
1258 1177
1259 *bp++ = htonl(pos);1178 *bp++ = htonl(lower_32_bits(pos));
1260 *bp++ = htonl(size);1179 *bp++ = htonl(lower_32_bits(size));
1261 *bp++ = htonl(i_size);1180 *bp++ = htonl(lower_32_bits(i_size));
1262
1263 afs_use_fs_server(call, fc->cbi);
1264 trace_afs_make_fs_call(call, &vnode->fid);
1265 afs_set_fc_call(call, fc);
1266 afs_make_call(&fc->ac, call, GFP_NOFS);
1267 return afs_wait_for_call_to_complete(call, &fc->ac);
1268}
1269
1270/*
1271 * deliver reply data to an FS.StoreStatus
1272 */
1273static int afs_deliver_fs_store_status(struct afs_call *call)
1274{
1275 const __be32 *bp;
1276 int ret;
1277
1278 _enter("");
1279 1181
1280 ret = afs_transfer_reply(call);1182 trace_afs_make_fs_call(call, &vp->fid);
1281 if (ret < 0)1183 afs_make_op_call(op, call, GFP_NOFS);
1282 return ret;
1283
1284 /* unmarshall the reply once we've received all of it */
1285 bp = call->buffer;
1286 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
1287 if (ret < 0)
1288 return ret;
1289 xdr_decode_AFSVolSync(&bp, call->out_volsync);
1290
1291 _leave(" = 0 [done]");
1292 return 0;
1293}1184}
1294 1185
1295/*1186/*
@@ -1298,21 +1189,21 @@ static int afs_deliver_fs_store_status(struct afs_call *call) · 2 unmodified lines
1298static const struct afs_call_type afs_RXFSStoreStatus = {1189static const struct afs_call_type afs_RXFSStoreStatus = {
1299 .name = "FS.StoreStatus",1190 .name = "FS.StoreStatus",
1300 .op = afs_FS_StoreStatus,1191 .op = afs_FS_StoreStatus,
1301 .deliver = afs_deliver_fs_store_status,1192 .deliver = afs_deliver_fs_store_data,
1302 .destructor = afs_flat_call_destructor,1193 .destructor = afs_flat_call_destructor,
1303};1194};
1304 1195
1305static const struct afs_call_type afs_RXFSStoreData_as_Status = {1196static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1306 .name = "FS.StoreData",1197 .name = "FS.StoreData",
1307 .op = afs_FS_StoreData,1198 .op = afs_FS_StoreData,
1308 .deliver = afs_deliver_fs_store_status,1199 .deliver = afs_deliver_fs_store_data,
1309 .destructor = afs_flat_call_destructor,1200 .destructor = afs_flat_call_destructor,
1310};1201};
1311 1202
1312static const struct afs_call_type afs_RXFSStoreData64_as_Status = {1203static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1313 .name = "FS.StoreData64",1204 .name = "FS.StoreData64",
1314 .op = afs_FS_StoreData64,1205 .op = afs_FS_StoreData64,
1315 .deliver = afs_deliver_fs_store_status,1206 .deliver = afs_deliver_fs_store_data,
1316 .destructor = afs_flat_call_destructor,1207 .destructor = afs_flat_call_destructor,
1317};1208};
1318 1209
@@ -1320,85 +1211,74 @@ static const struct afs_call_type afs_RXFSStoreData64_as_Status = { · 1 unmodified line
1320 * set the attributes on a very large file, using FS.StoreData rather than1211 * set the attributes on a very large file, using FS.StoreData rather than
1321 * FS.StoreStatus so as to alter the file size also1212 * FS.StoreStatus so as to alter the file size also
1322 */1213 */
1323static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr,1214static void afs_fs_setattr_size64(struct afs_operation *op)
1324 struct afs_status_cb *scb)
1325{1215{
1326 struct afs_vnode *vnode = fc->vnode;1216 struct afs_vnode_param *vp = &op->file[0];
1327 struct afs_call *call;1217 struct afs_call *call;
1328 struct afs_net *net = afs_v2net(vnode);1218 struct iattr *attr = op->setattr.attr;
1329 __be32 *bp;1219 __be32 *bp;
1330 1220
1331 _enter(",%x,{%llx:%llu},,",1221 _enter(",%x,{%llx:%llu},,",
1332 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1222 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1333 1223
1334 ASSERT(attr->ia_valid & ATTR_SIZE);1224 ASSERT(attr->ia_valid & ATTR_SIZE);
1335 1225
1336 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,1226 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64_as_Status,
1337 (4 + 6 + 3 * 2) * 4,1227 (4 + 6 + 3 * 2) * 4,
1338 (21 + 6) * 4);1228 (21 + 6) * 4);
1339 if (!call)1229 if (!call)
1340 return -ENOMEM;1230 return afs_op_nomem(op);
1341
1342 call->key = fc->key;
1343 call->out_scb = scb;
1344 1231
1345 /* marshall the parameters */1232 /* marshall the parameters */
1346 bp = call->request;1233 bp = call->request;
1347 *bp++ = htonl(FSSTOREDATA64);1234 *bp++ = htonl(FSSTOREDATA64);
1348 *bp++ = htonl(vnode->fid.vid);1235 *bp++ = htonl(vp->fid.vid);
1349 *bp++ = htonl(vnode->fid.vnode);1236 *bp++ = htonl(vp->fid.vnode);
1350 *bp++ = htonl(vnode->fid.unique);1237 *bp++ = htonl(vp->fid.unique);
1351 1238
1352 xdr_encode_AFS_StoreStatus(&bp, attr);1239 xdr_encode_AFS_StoreStatus(&bp, attr);
1353 1240
1354 *bp++ = htonl(attr->ia_size >> 32); /* position of start of write */1241 *bp++ = htonl(upper_32_bits(attr->ia_size)); /* position of start of write */
1355 *bp++ = htonl((u32) attr->ia_size);1242 *bp++ = htonl(lower_32_bits(attr->ia_size));
1356 *bp++ = 0; /* size of write */1243 *bp++ = 0; /* size of write */
1357 *bp++ = 0;1244 *bp++ = 0;
1358 *bp++ = htonl(attr->ia_size >> 32); /* new file length */1245 *bp++ = htonl(upper_32_bits(attr->ia_size)); /* new file length */
1359 *bp++ = htonl((u32) attr->ia_size);1246 *bp++ = htonl(lower_32_bits(attr->ia_size));
1360 1247
1361 afs_use_fs_server(call, fc->cbi);1248 trace_afs_make_fs_call(call, &vp->fid);
1362 trace_afs_make_fs_call(call, &vnode->fid);1249 afs_make_op_call(op, call, GFP_NOFS);
1363 afs_set_fc_call(call, fc);
1364 afs_make_call(&fc->ac, call, GFP_NOFS);
1365 return afs_wait_for_call_to_complete(call, &fc->ac);
1366}1250}
1367 1251
1368/*1252/*
1369 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus1253 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1370 * so as to alter the file size also1254 * so as to alter the file size also
1371 */1255 */
1372static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr,1256static void afs_fs_setattr_size(struct afs_operation *op)
1373 struct afs_status_cb *scb)
1374{1257{
1375 struct afs_vnode *vnode = fc->vnode;1258 struct afs_vnode_param *vp = &op->file[0];
1376 struct afs_call *call;1259 struct afs_call *call;
1377 struct afs_net *net = afs_v2net(vnode);1260 struct iattr *attr = op->setattr.attr;
1378 __be32 *bp;1261 __be32 *bp;
1379 1262
1380 _enter(",%x,{%llx:%llu},,",1263 _enter(",%x,{%llx:%llu},,",
1381 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1264 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1382 1265
1383 ASSERT(attr->ia_valid & ATTR_SIZE);1266 ASSERT(attr->ia_valid & ATTR_SIZE);
1384 if (attr->ia_size >> 32)1267 if (upper_32_bits(attr->ia_size))
1385 return afs_fs_setattr_size64(fc, attr, scb);1268 return afs_fs_setattr_size64(op);
1386 1269
1387 call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,1270 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status,
1388 (4 + 6 + 3) * 4,1271 (4 + 6 + 3) * 4,
1389 (21 + 6) * 4);1272 (21 + 6) * 4);
1390 if (!call)1273 if (!call)
1391 return -ENOMEM;1274 return afs_op_nomem(op);
1392
1393 call->key = fc->key;
1394 call->out_scb = scb;
1395 1275
1396 /* marshall the parameters */1276 /* marshall the parameters */
1397 bp = call->request;1277 bp = call->request;
1398 *bp++ = htonl(FSSTOREDATA);1278 *bp++ = htonl(FSSTOREDATA);
1399 *bp++ = htonl(vnode->fid.vid);1279 *bp++ = htonl(vp->fid.vid);
1400 *bp++ = htonl(vnode->fid.vnode);1280 *bp++ = htonl(vp->fid.vnode);
1401 *bp++ = htonl(vnode->fid.unique);1281 *bp++ = htonl(vp->fid.unique);
1402 1282
1403 xdr_encode_AFS_StoreStatus(&bp, attr);1283 xdr_encode_AFS_StoreStatus(&bp, attr);
1404 1284
@@ -1406,57 +1286,44 @@ static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr, · 1 unmodified line
1406 *bp++ = 0; /* size of write */1286 *bp++ = 0; /* size of write */
1407 *bp++ = htonl(attr->ia_size); /* new file length */1287 *bp++ = htonl(attr->ia_size); /* new file length */
1408 1288
1409 afs_use_fs_server(call, fc->cbi);1289 trace_afs_make_fs_call(call, &vp->fid);
1410 trace_afs_make_fs_call(call, &vnode->fid);1290 afs_make_op_call(op, call, GFP_NOFS);
1411 afs_set_fc_call(call, fc);
1412 afs_make_call(&fc->ac, call, GFP_NOFS);
1413 return afs_wait_for_call_to_complete(call, &fc->ac);
1414}1291}
1415 1292
1416/*1293/*
1417 * set the attributes on a file, using FS.StoreData if there's a change in file1294 * set the attributes on a file, using FS.StoreData if there's a change in file
1418 * size, and FS.StoreStatus otherwise1295 * size, and FS.StoreStatus otherwise
1419 */1296 */
1420int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr,1297void afs_fs_setattr(struct afs_operation *op)
1421 struct afs_status_cb *scb)
1422{1298{
1423 struct afs_vnode *vnode = fc->vnode;1299 struct afs_vnode_param *vp = &op->file[0];
1424 struct afs_call *call;1300 struct afs_call *call;
1425 struct afs_net *net = afs_v2net(vnode);1301 struct iattr *attr = op->setattr.attr;
1426 __be32 *bp;1302 __be32 *bp;
1427 1303
1428 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1429 return yfs_fs_setattr(fc, attr, scb);
1430
1431 if (attr->ia_valid & ATTR_SIZE)1304 if (attr->ia_valid & ATTR_SIZE)
1432 return afs_fs_setattr_size(fc, attr, scb);1305 return afs_fs_setattr_size(op);
1433 1306
1434 _enter(",%x,{%llx:%llu},,",1307 _enter(",%x,{%llx:%llu},,",
1435 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1308 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1436 1309
1437 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,1310 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreStatus,
1438 (4 + 6) * 4,1311 (4 + 6) * 4,
1439 (21 + 6) * 4);1312 (21 + 6) * 4);
1440 if (!call)1313 if (!call)
1441 return -ENOMEM;1314 return afs_op_nomem(op);
1442
1443 call->key = fc->key;
1444 call->out_scb = scb;
1445 1315
1446 /* marshall the parameters */1316 /* marshall the parameters */
1447 bp = call->request;1317 bp = call->request;
1448 *bp++ = htonl(FSSTORESTATUS);1318 *bp++ = htonl(FSSTORESTATUS);
1449 *bp++ = htonl(vnode->fid.vid);1319 *bp++ = htonl(vp->fid.vid);
1450 *bp++ = htonl(vnode->fid.vnode);1320 *bp++ = htonl(vp->fid.vnode);
1451 *bp++ = htonl(vnode->fid.unique);1321 *bp++ = htonl(vp->fid.unique);
1452 1322
1453 xdr_encode_AFS_StoreStatus(&bp, attr);1323 xdr_encode_AFS_StoreStatus(&bp, op->setattr.attr);
1454 1324
1455 afs_use_fs_server(call, fc->cbi);1325 trace_afs_make_fs_call(call, &vp->fid);
1456 trace_afs_make_fs_call(call, &vnode->fid);1326 afs_make_op_call(op, call, GFP_NOFS);
1457 afs_set_fc_call(call, fc);
1458 afs_make_call(&fc->ac, call, GFP_NOFS);
1459 return afs_wait_for_call_to_complete(call, &fc->ac);
1460}1327}
1461 1328
1462/*1329/*
@@ -1464,6 +1331,7 @@ int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr, · 1 unmodified line
1464 */1331 */
1465static int afs_deliver_fs_get_volume_status(struct afs_call *call)1332static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1466{1333{
1334 struct afs_operation *op = call->op;
1467 const __be32 *bp;1335 const __be32 *bp;
1468 char *p;1336 char *p;
1469 u32 size;1337 u32 size;
@@ -1485,7 +1353,7 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call) · 15 unmodified lines
1485 return ret;1353 return ret;
1486 1354
1487 bp = call->buffer;1355 bp = call->buffer;
1488 xdr_decode_AFSFetchVolumeStatus(&bp, call->out_volstatus);1356 xdr_decode_AFSFetchVolumeStatus(&bp, &op->volstatus.vs);
1489 call->unmarshall++;1357 call->unmarshall++;
1490 afs_extract_to_tmp(call);1358 afs_extract_to_tmp(call);
1491 /* Fall through */1359 /* Fall through */
@@ -1499,8 +1367,7 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call) · 7 unmodified lines
1499 call->count = ntohl(call->tmp);1367 call->count = ntohl(call->tmp);
1500 _debug("volname length: %u", call->count);1368 _debug("volname length: %u", call->count);
1501 if (call->count >= AFSNAMEMAX)1369 if (call->count >= AFSNAMEMAX)
1502 return afs_protocol_error(call, -EBADMSG,1370 return afs_protocol_error(call, afs_eproto_volname_len);
1503 afs_eproto_volname_len);
1504 size = (call->count + 3) & ~3; /* It's padded */1371 size = (call->count + 3) & ~3; /* It's padded */
1505 afs_extract_to_buf(call, size);1372 afs_extract_to_buf(call, size);
1506 call->unmarshall++;1373 call->unmarshall++;
@@ -1529,8 +1396,7 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call) · 22 unmodified lines
1529 call->count = ntohl(call->tmp);1396 call->count = ntohl(call->tmp);
1530 _debug("offline msg length: %u", call->count);1397 _debug("offline msg length: %u", call->count);
1531 if (call->count >= AFSNAMEMAX)1398 if (call->count >= AFSNAMEMAX)
1532 return afs_protocol_error(call, -EBADMSG,1399 return afs_protocol_error(call, afs_eproto_offline_msg_len);
1533 afs_eproto_offline_msg_len);
1534 size = (call->count + 3) & ~3; /* It's padded */1400 size = (call->count + 3) & ~3; /* It's padded */
1535 afs_extract_to_buf(call, size);1401 afs_extract_to_buf(call, size);
1536 call->unmarshall++;1402 call->unmarshall++;
@@ -1560,8 +1426,7 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call) · 23 unmodified lines
1560 call->count = ntohl(call->tmp);1426 call->count = ntohl(call->tmp);
1561 _debug("motd length: %u", call->count);1427 _debug("motd length: %u", call->count);
1562 if (call->count >= AFSNAMEMAX)1428 if (call->count >= AFSNAMEMAX)
1563 return afs_protocol_error(call, -EBADMSG,1429 return afs_protocol_error(call, afs_eproto_motd_len);
1564 afs_eproto_motd_len);
1565 size = (call->count + 3) & ~3; /* It's padded */1430 size = (call->count + 3) & ~3; /* It's padded */
1566 afs_extract_to_buf(call, size);1431 afs_extract_to_buf(call, size);
1567 call->unmarshall++;1432 call->unmarshall++;
@@ -1601,37 +1466,26 @@ static const struct afs_call_type afs_RXFSGetVolumeStatus = { · 33 unmodified lines
1601/*1466/*
1602 * fetch the status of a volume1467 * fetch the status of a volume
1603 */1468 */
1604int afs_fs_get_volume_status(struct afs_fs_cursor *fc,1469void afs_fs_get_volume_status(struct afs_operation *op)
1605 struct afs_volume_status *vs)
1606{1470{
1607 struct afs_vnode *vnode = fc->vnode;1471 struct afs_vnode_param *vp = &op->file[0];
1608 struct afs_call *call;1472 struct afs_call *call;
1609 struct afs_net *net = afs_v2net(vnode);
1610 __be32 *bp;1473 __be32 *bp;
1611 1474
1612 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1613 return yfs_fs_get_volume_status(fc, vs);
1614
1615 _enter("");1475 _enter("");
1616 1476
1617 call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4,1477 call = afs_alloc_flat_call(op->net, &afs_RXFSGetVolumeStatus, 2 * 4,
1618 max(12 * 4, AFSOPAQUEMAX + 1));1478 max(12 * 4, AFSOPAQUEMAX + 1));
1619 if (!call)1479 if (!call)
1620 return -ENOMEM;1480 return afs_op_nomem(op);
1621
1622 call->key = fc->key;
1623 call->out_volstatus = vs;
1624 1481
1625 /* marshall the parameters */1482 /* marshall the parameters */
1626 bp = call->request;1483 bp = call->request;
1627 bp[0] = htonl(FSGETVOLUMESTATUS);1484 bp[0] = htonl(FSGETVOLUMESTATUS);
1628 bp[1] = htonl(vnode->fid.vid);1485 bp[1] = htonl(vp->fid.vid);
1629 1486
1630 afs_use_fs_server(call, fc->cbi);1487 trace_afs_make_fs_call(call, &vp->fid);
1631 trace_afs_make_fs_call(call, &vnode->fid);1488 afs_make_op_call(op, call, GFP_NOFS);
1632 afs_set_fc_call(call, fc);
1633 afs_make_call(&fc->ac, call, GFP_NOFS);
1634 return afs_wait_for_call_to_complete(call, &fc->ac);
1635}1489}
1636 1490
1637/*1491/*
@@ -1639,6 +1493,7 @@ int afs_fs_get_volume_status(struct afs_fs_cursor *fc, · 1 unmodified line
1639 */1493 */
1640static int afs_deliver_fs_xxxx_lock(struct afs_call *call)1494static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
1641{1495{
1496 struct afs_operation *op = call->op;
1642 const __be32 *bp;1497 const __be32 *bp;
1643 int ret;1498 int ret;
1644 1499
@@ -1650,7 +1505,7 @@ static int afs_deliver_fs_xxxx_lock(struct afs_call *call) · 5 unmodified lines
1650 1505
1651 /* unmarshall the reply once we've received all of it */1506 /* unmarshall the reply once we've received all of it */
1652 bp = call->buffer;1507 bp = call->buffer;
1653 xdr_decode_AFSVolSync(&bp, call->out_volsync);1508 xdr_decode_AFSVolSync(&bp, &op->volsync);
1654 1509
1655 _leave(" = 0 [done]");1510 _leave(" = 0 [done]");
1656 return 0;1511 return 0;
@@ -1691,114 +1546,80 @@ static const struct afs_call_type afs_RXFSReleaseLock = { · 34 unmodified lines
1691/*1546/*
1692 * Set a lock on a file1547 * Set a lock on a file
1693 */1548 */
1694int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,1549void afs_fs_set_lock(struct afs_operation *op)
1695 struct afs_status_cb *scb)
1696{1550{
1697 struct afs_vnode *vnode = fc->vnode;1551 struct afs_vnode_param *vp = &op->file[0];
1698 struct afs_call *call;1552 struct afs_call *call;
1699 struct afs_net *net = afs_v2net(vnode);
1700 __be32 *bp;1553 __be32 *bp;
1701 1554
1702 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1703 return yfs_fs_set_lock(fc, type, scb);
1704
1705 _enter("");1555 _enter("");
1706 1556
1707 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);1557 call = afs_alloc_flat_call(op->net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
1708 if (!call)1558 if (!call)
1709 return -ENOMEM;1559 return afs_op_nomem(op);
1710
1711 call->key = fc->key;
1712 call->lvnode = vnode;
1713 call->out_scb = scb;
1714 1560
1715 /* marshall the parameters */1561 /* marshall the parameters */
1716 bp = call->request;1562 bp = call->request;
1717 *bp++ = htonl(FSSETLOCK);1563 *bp++ = htonl(FSSETLOCK);
1718 *bp++ = htonl(vnode->fid.vid);1564 *bp++ = htonl(vp->fid.vid);
1719 *bp++ = htonl(vnode->fid.vnode);1565 *bp++ = htonl(vp->fid.vnode);
1720 *bp++ = htonl(vnode->fid.unique);1566 *bp++ = htonl(vp->fid.unique);
1721 *bp++ = htonl(type);1567 *bp++ = htonl(op->lock.type);
1722 1568
1723 afs_use_fs_server(call, fc->cbi);1569 trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);
1724 trace_afs_make_fs_calli(call, &vnode->fid, type);1570 afs_make_op_call(op, call, GFP_NOFS);
1725 afs_set_fc_call(call, fc);
1726 afs_make_call(&fc->ac, call, GFP_NOFS);
1727 return afs_wait_for_call_to_complete(call, &fc->ac);
1728}1571}
1729 1572
1730/*1573/*
1731 * extend a lock on a file1574 * extend a lock on a file
1732 */1575 */
1733int afs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)1576void afs_fs_extend_lock(struct afs_operation *op)
1734{1577{
1735 struct afs_vnode *vnode = fc->vnode;1578 struct afs_vnode_param *vp = &op->file[0];
1736 struct afs_call *call;1579 struct afs_call *call;
1737 struct afs_net *net = afs_v2net(vnode);
1738 __be32 *bp;1580 __be32 *bp;
1739 1581
1740 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1741 return yfs_fs_extend_lock(fc, scb);
1742
1743 _enter("");1582 _enter("");
1744 1583
1745 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);1584 call = afs_alloc_flat_call(op->net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
1746 if (!call)1585 if (!call)
1747 return -ENOMEM;1586 return afs_op_nomem(op);
1748
1749 call->key = fc->key;
1750 call->lvnode = vnode;
1751 call->out_scb = scb;
1752 1587
1753 /* marshall the parameters */1588 /* marshall the parameters */
1754 bp = call->request;1589 bp = call->request;
1755 *bp++ = htonl(FSEXTENDLOCK);1590 *bp++ = htonl(FSEXTENDLOCK);
1756 *bp++ = htonl(vnode->fid.vid);1591 *bp++ = htonl(vp->fid.vid);
1757 *bp++ = htonl(vnode->fid.vnode);1592 *bp++ = htonl(vp->fid.vnode);
1758 *bp++ = htonl(vnode->fid.unique);1593 *bp++ = htonl(vp->fid.unique);
1759 1594
1760 afs_use_fs_server(call, fc->cbi);1595 trace_afs_make_fs_call(call, &vp->fid);
1761 trace_afs_make_fs_call(call, &vnode->fid);1596 afs_make_op_call(op, call, GFP_NOFS);
1762 afs_set_fc_call(call, fc);
1763 afs_make_call(&fc->ac, call, GFP_NOFS);
1764 return afs_wait_for_call_to_complete(call, &fc->ac);
1765}1597}
1766 1598
1767/*1599/*
1768 * release a lock on a file1600 * release a lock on a file
1769 */1601 */
1770int afs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)1602void afs_fs_release_lock(struct afs_operation *op)
1771{1603{
1772 struct afs_vnode *vnode = fc->vnode;1604 struct afs_vnode_param *vp = &op->file[0];
1773 struct afs_call *call;1605 struct afs_call *call;
1774 struct afs_net *net = afs_v2net(vnode);
1775 __be32 *bp;1606 __be32 *bp;
1776 1607
1777 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1778 return yfs_fs_release_lock(fc, scb);
1779
1780 _enter("");1608 _enter("");
1781 1609
1782 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);1610 call = afs_alloc_flat_call(op->net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1783 if (!call)1611 if (!call)
1784 return -ENOMEM;1612 return afs_op_nomem(op);
1785
1786 call->key = fc->key;
1787 call->lvnode = vnode;
1788 call->out_scb = scb;
1789 1613
1790 /* marshall the parameters */1614 /* marshall the parameters */
1791 bp = call->request;1615 bp = call->request;
1792 *bp++ = htonl(FSRELEASELOCK);1616 *bp++ = htonl(FSRELEASELOCK);
1793 *bp++ = htonl(vnode->fid.vid);1617 *bp++ = htonl(vp->fid.vid);
1794 *bp++ = htonl(vnode->fid.vnode);1618 *bp++ = htonl(vp->fid.vnode);
1795 *bp++ = htonl(vnode->fid.unique);1619 *bp++ = htonl(vp->fid.unique);
1796 1620
1797 afs_use_fs_server(call, fc->cbi);1621 trace_afs_make_fs_call(call, &vp->fid);
1798 trace_afs_make_fs_call(call, &vnode->fid);1622 afs_make_op_call(op, call, GFP_NOFS);
1799 afs_set_fc_call(call, fc);
1800 afs_make_call(&fc->ac, call, GFP_NOFS);
1801 return afs_wait_for_call_to_complete(call, &fc->ac);
1802}1623}
1803 1624
1804/*1625/*
@@ -1842,7 +1663,7 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net, · 37 unmodified lines
1842 bp = call->request;1663 bp = call->request;
1843 *bp++ = htonl(FSGIVEUPALLCALLBACKS);1664 *bp++ = htonl(FSGIVEUPALLCALLBACKS);
1844 1665
1845 /* Can't take a ref on server */1666 call->server = afs_use_server(server, afs_server_trace_give_up_cb);
1846 afs_make_call(ac, call, GFP_NOFS);1667 afs_make_call(ac, call, GFP_NOFS);
1847 return afs_wait_for_call_to_complete(call, ac);1668 return afs_wait_for_call_to_complete(call, ac);
1848}1669}
@@ -1905,14 +1726,13 @@ static const struct afs_call_type afs_RXFSGetCapabilities = { · 56 unmodified lines
1905};1726};
1906 1727
1907/*1728/*
1908 * Probe a fileserver for the capabilities that it supports. This can1729 * Probe a fileserver for the capabilities that it supports. This RPC can
1909 * return up to 196 words.1730 * reply with up to 196 words. The operation is asynchronous and if we managed
1731 * to allocate a call, true is returned the result is delivered through the
1732 * ->done() - otherwise we return false to indicate we didn't even try.
1910 */1733 */
1911struct afs_call *afs_fs_get_capabilities(struct afs_net *net,1734bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server,
1912 struct afs_server *server,1735 struct afs_addr_cursor *ac, struct key *key)
1913 struct afs_addr_cursor *ac,
1914 struct key *key,
1915 unsigned int server_index)
1916{1736{
1917 struct afs_call *call;1737 struct afs_call *call;
1918 __be32 *bp;1738 __be32 *bp;
@@ -1921,11 +1741,10 @@ struct afs_call *afs_fs_get_capabilities(struct afs_net *net, · 2 unmodified lines
1921 1741
1922 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);1742 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
1923 if (!call)1743 if (!call)
1924 return ERR_PTR(-ENOMEM);1744 return false;
1925 1745
1926 call->key = key;1746 call->key = key;
1927 call->server = afs_get_server(server, afs_server_trace_get_caps);1747 call->server = afs_use_server(server, afs_server_trace_get_caps);
1928 call->server_index = server_index;
1929 call->upgrade = true;1748 call->upgrade = true;
1930 call->async = true;1749 call->async = true;
1931 call->max_lifespan = AFS_PROBE_MAX_LIFESPAN;1750 call->max_lifespan = AFS_PROBE_MAX_LIFESPAN;
@@ -1934,87 +1753,10 @@ struct afs_call *afs_fs_get_capabilities(struct afs_net *net, · 2 unmodified lines
1934 bp = call->request;1753 bp = call->request;
1935 *bp++ = htonl(FSGETCAPABILITIES);1754 *bp++ = htonl(FSGETCAPABILITIES);
1936 1755
1937 /* Can't take a ref on server */
1938 trace_afs_make_fs_call(call, NULL);1756 trace_afs_make_fs_call(call, NULL);
1939 afs_make_call(ac, call, GFP_NOFS);1757 afs_make_call(ac, call, GFP_NOFS);
1940 return call;1758 afs_put_call(call);
1941}1759 return true;
1942
1943/*
1944 * Deliver reply data to an FS.FetchStatus with no vnode.
1945 */
1946static int afs_deliver_fs_fetch_status(struct afs_call *call)
1947{
1948 const __be32 *bp;
1949 int ret;
1950
1951 ret = afs_transfer_reply(call);
1952 if (ret < 0)
1953 return ret;
1954
1955 /* unmarshall the reply once we've received all of it */
1956 bp = call->buffer;
1957 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
1958 if (ret < 0)
1959 return ret;
1960 xdr_decode_AFSCallBack(&bp, call, call->out_scb);
1961 xdr_decode_AFSVolSync(&bp, call->out_volsync);
1962
1963 _leave(" = 0 [done]");
1964 return 0;
1965}
1966
1967/*
1968 * FS.FetchStatus operation type
1969 */
1970static const struct afs_call_type afs_RXFSFetchStatus = {
1971 .name = "FS.FetchStatus",
1972 .op = afs_FS_FetchStatus,
1973 .deliver = afs_deliver_fs_fetch_status,
1974 .destructor = afs_flat_call_destructor,
1975};
1976
1977/*
1978 * Fetch the status information for a fid without needing a vnode handle.
1979 */
1980int afs_fs_fetch_status(struct afs_fs_cursor *fc,
1981 struct afs_net *net,
1982 struct afs_fid *fid,
1983 struct afs_status_cb *scb,
1984 struct afs_volsync *volsync)
1985{
1986 struct afs_call *call;
1987 __be32 *bp;
1988
1989 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1990 return yfs_fs_fetch_status(fc, net, fid, scb, volsync);
1991
1992 _enter(",%x,{%llx:%llu},,",
1993 key_serial(fc->key), fid->vid, fid->vnode);
1994
1995 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
1996 if (!call) {
1997 fc->ac.error = -ENOMEM;
1998 return -ENOMEM;
1999 }
2000
2001 call->key = fc->key;
2002 call->out_fid = fid;
2003 call->out_scb = scb;
2004 call->out_volsync = volsync;
2005
2006 /* marshall the parameters */
2007 bp = call->request;
2008 bp[0] = htonl(FSFETCHSTATUS);
2009 bp[1] = htonl(fid->vid);
2010 bp[2] = htonl(fid->vnode);
2011 bp[3] = htonl(fid->unique);
2012
2013 afs_use_fs_server(call, fc->cbi);
2014 trace_afs_make_fs_call(call, fid);
2015 afs_set_fc_call(call, fc);
2016 afs_make_call(&fc->ac, call, GFP_NOFS);
2017 return afs_wait_for_call_to_complete(call, &fc->ac);
2018}1760}
2019 1761
2020/*1762/*
@@ -2022,6 +1764,7 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc, · 1 unmodified line
2022 */1764 */
2023static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)1765static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
2024{1766{
1767 struct afs_operation *op = call->op;
2025 struct afs_status_cb *scb;1768 struct afs_status_cb *scb;
2026 const __be32 *bp;1769 const __be32 *bp;
2027 u32 tmp;1770 u32 tmp;
@@ -2043,10 +1786,9 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) · 15 unmodified lines
2043 return ret;1786 return ret;
2044 1787
2045 tmp = ntohl(call->tmp);1788 tmp = ntohl(call->tmp);
2046 _debug("status count: %u/%u", tmp, call->count2);1789 _debug("status count: %u/%u", tmp, op->nr_files);
2047 if (tmp != call->count2)1790 if (tmp != op->nr_files)
2048 return afs_protocol_error(call, -EBADMSG,1791 return afs_protocol_error(call, afs_eproto_ibulkst_count);
2049 afs_eproto_ibulkst_count);
2050 1792
2051 call->count = 0;1793 call->count = 0;
2052 call->unmarshall++;1794 call->unmarshall++;
@@ -2060,14 +1802,23 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) · 7 unmodified lines
2060 if (ret < 0)1802 if (ret < 0)
2061 return ret;1803 return ret;
2062 1804
1805 switch (call->count) {
1806 case 0:
1807 scb = &op->file[0].scb;
1808 break;
1809 case 1:
1810 scb = &op->file[1].scb;
1811 break;
1812 default:
1813 scb = &op->more_files[call->count - 2].scb;
1814 break;
1815 }
1816
2063 bp = call->buffer;1817 bp = call->buffer;
2064 scb = &call->out_scb[call->count];1818 xdr_decode_AFSFetchStatus(&bp, call, scb);
2065 ret = xdr_decode_AFSFetchStatus(&bp, call, scb);
2066 if (ret < 0)
2067 return ret;
2068 1819
2069 call->count++;1820 call->count++;
2070 if (call->count < call->count2)1821 if (call->count < op->nr_files)
2071 goto more_counts;1822 goto more_counts;
2072 1823
2073 call->count = 0;1824 call->count = 0;
@@ -2084,9 +1835,8 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) · 10 unmodified lines
2084 1835
2085 tmp = ntohl(call->tmp);1836 tmp = ntohl(call->tmp);
2086 _debug("CB count: %u", tmp);1837 _debug("CB count: %u", tmp);
2087 if (tmp != call->count2)1838 if (tmp != op->nr_files)
2088 return afs_protocol_error(call, -EBADMSG,1839 return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
2089 afs_eproto_ibulkst_cb_count);
2090 call->count = 0;1840 call->count = 0;
2091 call->unmarshall++;1841 call->unmarshall++;
2092 more_cbs:1842 more_cbs:
@@ -2100,11 +1850,22 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) · 7 unmodified lines
2100 return ret;1850 return ret;
2101 1851
2102 _debug("unmarshall CB array");1852 _debug("unmarshall CB array");
1853 switch (call->count) {
1854 case 0:
1855 scb = &op->file[0].scb;
1856 break;
1857 case 1:
1858 scb = &op->file[1].scb;
1859 break;
1860 default:
1861 scb = &op->more_files[call->count - 2].scb;
1862 break;
1863 }
1864
2103 bp = call->buffer;1865 bp = call->buffer;
2104 scb = &call->out_scb[call->count];
2105 xdr_decode_AFSCallBack(&bp, call, scb);1866 xdr_decode_AFSCallBack(&bp, call, scb);
2106 call->count++;1867 call->count++;
2107 if (call->count < call->count2)1868 if (call->count < op->nr_files)
2108 goto more_cbs;1869 goto more_cbs;
2109 1870
2110 afs_extract_to_buf(call, 6 * sizeof(__be32));1871 afs_extract_to_buf(call, 6 * sizeof(__be32));
@@ -2117,7 +1878,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) · 6 unmodified lines
2117 return ret;1878 return ret;
2118 1879
2119 bp = call->buffer;1880 bp = call->buffer;
2120 xdr_decode_AFSVolSync(&bp, call->out_volsync);1881 xdr_decode_AFSVolSync(&bp, &op->volsync);
2121 1882
2122 call->unmarshall++;1883 call->unmarshall++;
2123 1884
@@ -2129,6 +1890,16 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) · 5 unmodified lines
2129 return 0;1890 return 0;
2130}1891}
2131 1892
1893static void afs_done_fs_inline_bulk_status(struct afs_call *call)
1894{
1895 if (call->error == -ECONNABORTED &&
1896 call->abort_code == RX_INVALID_OPERATION) {
1897 set_bit(AFS_SERVER_FL_NO_IBULK, &call->server->flags);
1898 if (call->op)
1899 set_bit(AFS_VOLUME_MAYBE_NO_IBULK, &call->op->volume->flags);
1900 }
1901}
1902
2132/*1903/*
2133 * FS.InlineBulkStatus operation type1904 * FS.InlineBulkStatus operation type
2134 */1905 */
@@ -2136,58 +1907,53 @@ static const struct afs_call_type afs_RXFSInlineBulkStatus = { · 1 unmodified line
2136 .name = "FS.InlineBulkStatus",1907 .name = "FS.InlineBulkStatus",
2137 .op = afs_FS_InlineBulkStatus,1908 .op = afs_FS_InlineBulkStatus,
2138 .deliver = afs_deliver_fs_inline_bulk_status,1909 .deliver = afs_deliver_fs_inline_bulk_status,
1910 .done = afs_done_fs_inline_bulk_status,
2139 .destructor = afs_flat_call_destructor,1911 .destructor = afs_flat_call_destructor,
2140};1912};
2141 1913
2142/*1914/*
2143 * Fetch the status information for up to 50 files1915 * Fetch the status information for up to 50 files
2144 */1916 */
2145int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,1917void afs_fs_inline_bulk_status(struct afs_operation *op)
2146 struct afs_net *net,
2147 struct afs_fid *fids,
2148 struct afs_status_cb *statuses,
2149 unsigned int nr_fids,
2150 struct afs_volsync *volsync)
2151{1918{
1919 struct afs_vnode_param *dvp = &op->file[0];
1920 struct afs_vnode_param *vp = &op->file[1];
2152 struct afs_call *call;1921 struct afs_call *call;
2153 __be32 *bp;1922 __be32 *bp;
2154 int i;1923 int i;
2155 1924
2156 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))1925 if (test_bit(AFS_SERVER_FL_NO_IBULK, &op->server->flags)) {
2157 return yfs_fs_inline_bulk_status(fc, net, fids, statuses,1926 op->error = -ENOTSUPP;
2158 nr_fids, volsync);1927 return;
1928 }
2159 1929
2160 _enter(",%x,{%llx:%llu},%u",1930 _enter(",%x,{%llx:%llu},%u",
2161 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);1931 key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);
2162 1932
2163 call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus,1933 call = afs_alloc_flat_call(op->net, &afs_RXFSInlineBulkStatus,
2164 (2 + nr_fids * 3) * 4,1934 (2 + op->nr_files * 3) * 4,
2165 21 * 4);1935 21 * 4);
2166 if (!call) {1936 if (!call)
2167 fc->ac.error = -ENOMEM;1937 return afs_op_nomem(op);
2168 return -ENOMEM;
2169 }
2170
2171 call->key = fc->key;
2172 call->out_scb = statuses;
2173 call->out_volsync = volsync;
2174 call->count2 = nr_fids;
2175 1938
2176 /* marshall the parameters */1939 /* marshall the parameters */
2177 bp = call->request;1940 bp = call->request;
2178 *bp++ = htonl(FSINLINEBULKSTATUS);1941 *bp++ = htonl(FSINLINEBULKSTATUS);
2179 *bp++ = htonl(nr_fids);1942 *bp++ = htonl(op->nr_files);
2180 for (i = 0; i < nr_fids; i++) {1943 *bp++ = htonl(dvp->fid.vid);
2181 *bp++ = htonl(fids[i].vid);1944 *bp++ = htonl(dvp->fid.vnode);
2182 *bp++ = htonl(fids[i].vnode);1945 *bp++ = htonl(dvp->fid.unique);
2183 *bp++ = htonl(fids[i].unique);1946 *bp++ = htonl(vp->fid.vid);
1947 *bp++ = htonl(vp->fid.vnode);
1948 *bp++ = htonl(vp->fid.unique);
1949 for (i = 0; i < op->nr_files - 2; i++) {
1950 *bp++ = htonl(op->more_files[i].fid.vid);
1951 *bp++ = htonl(op->more_files[i].fid.vnode);
1952 *bp++ = htonl(op->more_files[i].fid.unique);
2184 }1953 }
2185 1954
2186 afs_use_fs_server(call, fc->cbi);1955 trace_afs_make_fs_call(call, &vp->fid);
2187 trace_afs_make_fs_call(call, &fids[0]);1956 afs_make_op_call(op, call, GFP_NOFS);
2188 afs_set_fc_call(call, fc);
2189 afs_make_call(&fc->ac, call, GFP_NOFS);
2190 return afs_wait_for_call_to_complete(call, &fc->ac);
2191}1957}
2192 1958
2193/*1959/*
@@ -2195,6 +1961,8 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc, · 1 unmodified line
2195 */1961 */
2196static int afs_deliver_fs_fetch_acl(struct afs_call *call)1962static int afs_deliver_fs_fetch_acl(struct afs_call *call)
2197{1963{
1964 struct afs_operation *op = call->op;
1965 struct afs_vnode_param *vp = &op->file[0];
2198 struct afs_acl *acl;1966 struct afs_acl *acl;
2199 const __be32 *bp;1967 const __be32 *bp;
2200 unsigned int size;1968 unsigned int size;
@@ -2220,7 +1988,7 @@ static int afs_deliver_fs_fetch_acl(struct afs_call *call) · 19 unmodified lines
2220 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);1988 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2221 if (!acl)1989 if (!acl)
2222 return -ENOMEM;1990 return -ENOMEM;
2223 call->ret_acl = acl;1991 op->acl = acl;
2224 acl->size = call->count2;1992 acl->size = call->count2;
2225 afs_extract_begin(call, acl->data, size);1993 afs_extract_begin(call, acl->data, size);
2226 call->unmarshall++;1994 call->unmarshall++;
@@ -2243,10 +2011,8 @@ static int afs_deliver_fs_fetch_acl(struct afs_call *call) · 16 unmodified lines
2243 return ret;2011 return ret;
2244 2012
2245 bp = call->buffer;2013 bp = call->buffer;
2246 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);2014 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
2247 if (ret < 0)2015 xdr_decode_AFSVolSync(&bp, &op->volsync);
2248 return ret;
2249 xdr_decode_AFSVolSync(&bp, call->out_volsync);
2250 2016
2251 call->unmarshall++;2017 call->unmarshall++;
2252 2018
@@ -2258,12 +2024,6 @@ static int afs_deliver_fs_fetch_acl(struct afs_call *call) · 5 unmodified lines
2258 return 0;2024 return 0;
2259}2025}
2260 2026
2261static void afs_destroy_fs_fetch_acl(struct afs_call *call)
2262{
2263 kfree(call->ret_acl);
2264 afs_flat_call_destructor(call);
2265}
2266
2267/*2027/*
2268 * FS.FetchACL operation type2028 * FS.FetchACL operation type
2269 */2029 */
@@ -2271,68 +2031,33 @@ static const struct afs_call_type afs_RXFSFetchACL = { · 1 unmodified line
2271 .name = "FS.FetchACL",2031 .name = "FS.FetchACL",
2272 .op = afs_FS_FetchACL,2032 .op = afs_FS_FetchACL,
2273 .deliver = afs_deliver_fs_fetch_acl,2033 .deliver = afs_deliver_fs_fetch_acl,
2274 .destructor = afs_destroy_fs_fetch_acl,
2275};2034};
2276 2035
2277/*2036/*
2278 * Fetch the ACL for a file.2037 * Fetch the ACL for a file.
2279 */2038 */
2280struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *fc,2039void afs_fs_fetch_acl(struct afs_operation *op)
2281 struct afs_status_cb *scb)
2282{2040{
2283 struct afs_vnode *vnode = fc->vnode;2041 struct afs_vnode_param *vp = &op->file[0];
2284 struct afs_call *call;2042 struct afs_call *call;
2285 struct afs_net *net = afs_v2net(vnode);
2286 __be32 *bp;2043 __be32 *bp;
2287 2044
2288 _enter(",%x,{%llx:%llu},,",2045 _enter(",%x,{%llx:%llu},,",
2289 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);2046 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2290 2047
2291 call = afs_alloc_flat_call(net, &afs_RXFSFetchACL, 16, (21 + 6) * 4);2048 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchACL, 16, (21 + 6) * 4);
2292 if (!call) {2049 if (!call)
2293 fc->ac.error = -ENOMEM;2050 return afs_op_nomem(op);
2294 return ERR_PTR(-ENOMEM);
2295 }
2296
2297 call->key = fc->key;
2298 call->ret_acl = NULL;
2299 call->out_scb = scb;
2300 call->out_volsync = NULL;
2301 2051
2302 /* marshall the parameters */2052 /* marshall the parameters */
2303 bp = call->request;2053 bp = call->request;
2304 bp[0] = htonl(FSFETCHACL);2054 bp[0] = htonl(FSFETCHACL);
2305 bp[1] = htonl(vnode->fid.vid);2055 bp[1] = htonl(vp->fid.vid);
2306 bp[2] = htonl(vnode->fid.vnode);2056 bp[2] = htonl(vp->fid.vnode);
2307 bp[3] = htonl(vnode->fid.unique);2057 bp[3] = htonl(vp->fid.unique);
2308
2309 afs_use_fs_server(call, fc->cbi);
2310 trace_afs_make_fs_call(call, &vnode->fid);
2311 afs_make_call(&fc->ac, call, GFP_KERNEL);
2312 return (struct afs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2313}
2314
2315/*
2316 * Deliver reply data to any operation that returns file status and volume
2317 * sync.
2318 */
2319static int afs_deliver_fs_file_status_and_vol(struct afs_call *call)
2320{
2321 const __be32 *bp;
2322 int ret;
2323 2058
2324 ret = afs_transfer_reply(call);2059 trace_afs_make_fs_call(call, &vp->fid);
2325 if (ret < 0)2060 afs_make_op_call(op, call, GFP_KERNEL);
2326 return ret;
2327
2328 bp = call->buffer;
2329 ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
2330 if (ret < 0)
2331 return ret;
2332 xdr_decode_AFSVolSync(&bp, call->out_volsync);
2333
2334 _leave(" = 0 [done]");
2335 return 0;
2336}2061}
2337 2062
2338/*2063/*
@@ -2348,42 +2073,34 @@ static const struct afs_call_type afs_RXFSStoreACL = { · 9 unmodified lines
2348/*2073/*
2349 * Fetch the ACL for a file.2074 * Fetch the ACL for a file.
2350 */2075 */
2351int afs_fs_store_acl(struct afs_fs_cursor *fc, const struct afs_acl *acl,2076void afs_fs_store_acl(struct afs_operation *op)
2352 struct afs_status_cb *scb)
2353{2077{
2354 struct afs_vnode *vnode = fc->vnode;2078 struct afs_vnode_param *vp = &op->file[0];
2355 struct afs_call *call;2079 struct afs_call *call;
2356 struct afs_net *net = afs_v2net(vnode);2080 const struct afs_acl *acl = op->acl;
2357 size_t size;2081 size_t size;
2358 __be32 *bp;2082 __be32 *bp;
2359 2083
2360 _enter(",%x,{%llx:%llu},,",2084 _enter(",%x,{%llx:%llu},,",
2361 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);2085 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2362 2086
2363 size = round_up(acl->size, 4);2087 size = round_up(acl->size, 4);
2364 call = afs_alloc_flat_call(net, &afs_RXFSStoreACL,2088 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreACL,
2365 5 * 4 + size, (21 + 6) * 4);2089 5 * 4 + size, (21 + 6) * 4);
2366 if (!call) {2090 if (!call)
2367 fc->ac.error = -ENOMEM;2091 return afs_op_nomem(op);
2368 return -ENOMEM;
2369 }
2370
2371 call->key = fc->key;
2372 call->out_scb = scb;
2373 call->out_volsync = NULL;
2374 2092
2375 /* marshall the parameters */2093 /* marshall the parameters */
2376 bp = call->request;2094 bp = call->request;
2377 bp[0] = htonl(FSSTOREACL);2095 bp[0] = htonl(FSSTOREACL);
2378 bp[1] = htonl(vnode->fid.vid);2096 bp[1] = htonl(vp->fid.vid);
2379 bp[2] = htonl(vnode->fid.vnode);2097 bp[2] = htonl(vp->fid.vnode);
2380 bp[3] = htonl(vnode->fid.unique);2098 bp[3] = htonl(vp->fid.unique);
2381 bp[4] = htonl(acl->size);2099 bp[4] = htonl(acl->size);
2382 memcpy(&bp[5], acl->data, acl->size);2100 memcpy(&bp[5], acl->data, acl->size);
2383 if (acl->size != size)2101 if (acl->size != size)
2384 memset((void *)&bp[5] + acl->size, 0, size - acl->size);2102 memset((void *)&bp[5] + acl->size, 0, size - acl->size);
2385 2103
2386 trace_afs_make_fs_call(call, &vnode->fid);2104 trace_afs_make_fs_call(call, &vp->fid);
2387 afs_make_call(&fc->ac, call, GFP_KERNEL);2105 afs_make_op_call(op, call, GFP_KERNEL);
2388 return afs_wait_for_call_to_complete(call, &fc->ac);
2389}2106}
fs/afs/inode.c+224−267
@@ -67,16 +67,18 @@ static void afs_set_i_size(struct afs_vnode *vnode, u64 size) · 66 unmodified lines
67/*67/*
68 * Initialise an inode from the vnode status.68 * Initialise an inode from the vnode status.
69 */69 */
70static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key,70static int afs_inode_init_from_status(struct afs_operation *op,
71 struct afs_cb_interest *cbi,71 struct afs_vnode_param *vp,
72 struct afs_vnode *parent_vnode,72 struct afs_vnode *vnode)
73 struct afs_status_cb *scb)
74{73{
75 struct afs_cb_interest *old_cbi = NULL;74 struct afs_file_status *status = &vp->scb.status;
76 struct afs_file_status *status = &scb->status;
77 struct inode *inode = AFS_VNODE_TO_I(vnode);75 struct inode *inode = AFS_VNODE_TO_I(vnode);
78 struct timespec64 t;76 struct timespec64 t;
79 77
78 _enter("{%llx:%llu.%u} %s",
79 vp->fid.vid, vp->fid.vnode, vp->fid.unique,
80 op->type ? op->type->name : "???");
81
80 _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu",82 _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu",
81 status->type,83 status->type,
82 status->nlink,84 status->nlink,
@@ -86,12 +88,15 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key, · 3 unmodified lines
86 88
87 write_seqlock(&vnode->cb_lock);89 write_seqlock(&vnode->cb_lock);
88 90
91 vnode->cb_v_break = op->cb_v_break;
92 vnode->cb_s_break = op->cb_s_break;
89 vnode->status = *status;93 vnode->status = *status;
90 94
91 t = status->mtime_client;95 t = status->mtime_client;
92 inode->i_ctime = t;96 inode->i_ctime = t;
93 inode->i_mtime = t;97 inode->i_mtime = t;
94 inode->i_atime = t;98 inode->i_atime = t;
99 inode->i_flags |= S_NOATIME;
95 inode->i_uid = make_kuid(&init_user_ns, status->owner);100 inode->i_uid = make_kuid(&init_user_ns, status->owner);
96 inode->i_gid = make_kgid(&init_user_ns, status->group);101 inode->i_gid = make_kgid(&init_user_ns, status->group);
97 set_nlink(&vnode->vfs_inode, status->nlink);102 set_nlink(&vnode->vfs_inode, status->nlink);
@@ -128,9 +133,9 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key, · 30 unmodified lines
128 inode_nohighmem(inode);133 inode_nohighmem(inode);
129 break;134 break;
130 default:135 default:
131 dump_vnode(vnode, parent_vnode);136 dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL);
132 write_sequnlock(&vnode->cb_lock);137 write_sequnlock(&vnode->cb_lock);
133 return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type);138 return afs_protocol_error(NULL, afs_eproto_file_type);
134 }139 }
135 140
136 afs_set_i_size(vnode, status->size);141 afs_set_i_size(vnode, status->size);
@@ -138,39 +143,36 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key, · 1 unmodified line
138 vnode->invalid_before = status->data_version;143 vnode->invalid_before = status->data_version;
139 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);144 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
140 145
141 if (!scb->have_cb) {146 if (!vp->scb.have_cb) {
142 /* it's a symlink we just created (the fileserver147 /* it's a symlink we just created (the fileserver
143 * didn't give us a callback) */148 * didn't give us a callback) */
144 vnode->cb_expires_at = ktime_get_real_seconds();149 vnode->cb_expires_at = ktime_get_real_seconds();
145 } else {150 } else {
146 vnode->cb_expires_at = scb->callback.expires_at;151 vnode->cb_expires_at = vp->scb.callback.expires_at;
147 old_cbi = rcu_dereference_protected(vnode->cb_interest,152 vnode->cb_server = op->server;
148 lockdep_is_held(&vnode->cb_lock.lock));
149 if (cbi != old_cbi)
150 rcu_assign_pointer(vnode->cb_interest, afs_get_cb_interest(cbi));
151 else
152 old_cbi = NULL;
153 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);153 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
154 }154 }
155 155
156 write_sequnlock(&vnode->cb_lock);156 write_sequnlock(&vnode->cb_lock);
157 afs_put_cb_interest(afs_v2net(vnode), old_cbi);
158 return 0;157 return 0;
159}158}
160 159
161/*160/*
162 * Update the core inode struct from a returned status record.161 * Update the core inode struct from a returned status record.
163 */162 */
164static void afs_apply_status(struct afs_fs_cursor *fc,163static void afs_apply_status(struct afs_operation *op,
165 struct afs_vnode *vnode,164 struct afs_vnode_param *vp)
166 struct afs_status_cb *scb,
167 const afs_dataversion_t *expected_version)
168{165{
169 struct afs_file_status *status = &scb->status;166 struct afs_file_status *status = &vp->scb.status;
167 struct afs_vnode *vnode = vp->vnode;
170 struct timespec64 t;168 struct timespec64 t;
171 umode_t mode;169 umode_t mode;
172 bool data_changed = false;170 bool data_changed = false;
173 171
172 _enter("{%llx:%llu.%u} %s",
173 vp->fid.vid, vp->fid.vnode, vp->fid.unique,
174 op->type ? op->type->name : "???");
175
174 BUG_ON(test_bit(AFS_VNODE_UNSET, &vnode->flags));176 BUG_ON(test_bit(AFS_VNODE_UNSET, &vnode->flags));
175 177
176 if (status->type != vnode->status.type) {178 if (status->type != vnode->status.type) {
@@ -179,7 +181,7 @@ static void afs_apply_status(struct afs_fs_cursor *fc, · 2 unmodified lines
179 vnode->fid.vnode,181 vnode->fid.vnode,
180 vnode->fid.unique,182 vnode->fid.unique,
181 status->type, vnode->status.type);183 status->type, vnode->status.type);
182 afs_protocol_error(NULL, -EBADMSG, afs_eproto_bad_status);184 afs_protocol_error(NULL, afs_eproto_bad_status);
183 return;185 return;
184 }186 }
185 187
@@ -209,14 +211,13 @@ static void afs_apply_status(struct afs_fs_cursor *fc, · 23 unmodified lines
209 211
210 vnode->status = *status;212 vnode->status = *status;
211 213
212 if (expected_version &&214 if (vp->dv_before + vp->dv_delta != status->data_version) {
213 *expected_version != status->data_version) {
214 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))215 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))
215 pr_warn("kAFS: vnode modified {%llx:%llu} %llx->%llx %s\n",216 pr_warn("kAFS: vnode modified {%llx:%llu} %llx->%llx %s\n",
216 vnode->fid.vid, vnode->fid.vnode,217 vnode->fid.vid, vnode->fid.vnode,
217 (unsigned long long)*expected_version,218 (unsigned long long)vp->dv_before + vp->dv_delta,
218 (unsigned long long)status->data_version,219 (unsigned long long)status->data_version,
219 fc->type ? fc->type->name : "???");220 op->type ? op->type->name : "???");
220 221
221 vnode->invalid_before = status->data_version;222 vnode->invalid_before = status->data_version;
222 if (vnode->status.type == AFS_FTYPE_DIR) {223 if (vnode->status.type == AFS_FTYPE_DIR) {
@@ -243,22 +244,15 @@ static void afs_apply_status(struct afs_fs_cursor *fc, · 20 unmodified lines
243/*244/*
244 * Apply a callback to a vnode.245 * Apply a callback to a vnode.
245 */246 */
246static void afs_apply_callback(struct afs_fs_cursor *fc,247static void afs_apply_callback(struct afs_operation *op,
247 struct afs_vnode *vnode,248 struct afs_vnode_param *vp)
248 struct afs_status_cb *scb,
249 unsigned int cb_break)
250{249{
251 struct afs_cb_interest *old;250 struct afs_callback *cb = &vp->scb.callback;
252 struct afs_callback *cb = &scb->callback;251 struct afs_vnode *vnode = vp->vnode;
253 252
254 if (!afs_cb_is_broken(cb_break, vnode, fc->cbi)) {253 if (!afs_cb_is_broken(vp->cb_break_before, vnode)) {
255 vnode->cb_expires_at = cb->expires_at;254 vnode->cb_expires_at = cb->expires_at;
256 old = rcu_dereference_protected(vnode->cb_interest,255 vnode->cb_server = op->server;
257 lockdep_is_held(&vnode->cb_lock.lock));
258 if (old != fc->cbi) {
259 rcu_assign_pointer(vnode->cb_interest, afs_get_cb_interest(fc->cbi));
260 afs_put_cb_interest(afs_v2net(vnode), old);
261 }
262 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);256 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
263 }257 }
264}258}
@@ -267,106 +261,108 @@ static void afs_apply_callback(struct afs_fs_cursor *fc, · 2 unmodified lines
267 * Apply the received status and callback to an inode all in the same critical261 * Apply the received status and callback to an inode all in the same critical
268 * section to avoid races with afs_validate().262 * section to avoid races with afs_validate().
269 */263 */
270void afs_vnode_commit_status(struct afs_fs_cursor *fc,264void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *vp)
271 struct afs_vnode *vnode,
272 unsigned int cb_break,
273 const afs_dataversion_t *expected_version,
274 struct afs_status_cb *scb)
275{265{
276 if (fc->ac.error != 0)266 struct afs_vnode *vnode = vp->vnode;
277 return;267
268 _enter("");
269
270 ASSERTCMP(op->error, ==, 0);
278 271
279 write_seqlock(&vnode->cb_lock);272 write_seqlock(&vnode->cb_lock);
280 273
281 if (scb->have_error) {274 if (vp->scb.have_error) {
282 if (scb->status.abort_code == VNOVNODE) {275 if (vp->scb.status.abort_code == VNOVNODE) {
283 set_bit(AFS_VNODE_DELETED, &vnode->flags);276 set_bit(AFS_VNODE_DELETED, &vnode->flags);
284 clear_nlink(&vnode->vfs_inode);277 clear_nlink(&vnode->vfs_inode);
285 __afs_break_callback(vnode, afs_cb_break_for_deleted);278 __afs_break_callback(vnode, afs_cb_break_for_deleted);
286 }279 }
287 } else {280 } else {
288 if (scb->have_status)281 if (vp->scb.have_status)
289 afs_apply_status(fc, vnode, scb, expected_version);282 afs_apply_status(op, vp);
290 if (scb->have_cb)283 if (vp->scb.have_cb)
291 afs_apply_callback(fc, vnode, scb, cb_break);284 afs_apply_callback(op, vp);
292 }285 }
293 286
294 write_sequnlock(&vnode->cb_lock);287 write_sequnlock(&vnode->cb_lock);
295 288
296 if (fc->ac.error == 0 && scb->have_status)289 if (op->error == 0 && vp->scb.have_status)
297 afs_cache_permit(vnode, fc->key, cb_break, scb);290 afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
298}291}
299 292
293static void afs_fetch_status_success(struct afs_operation *op)
294{
295 struct afs_vnode_param *vp = &op->file[0];
296 struct afs_vnode *vnode = vp->vnode;
297 int ret;
298
299 if (vnode->vfs_inode.i_state & I_NEW) {
300 ret = afs_inode_init_from_status(op, vp, vnode);
301 op->error = ret;
302 if (ret == 0)
303 afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
304 } else {
305 afs_vnode_commit_status(op, vp);
306 }
307}
308
309static const struct afs_operation_ops afs_fetch_status_operation = {
310 .issue_afs_rpc = afs_fs_fetch_status,
311 .issue_yfs_rpc = yfs_fs_fetch_status,
312 .success = afs_fetch_status_success,
313};
314
300/*315/*
301 * Fetch file status from the volume.316 * Fetch file status from the volume.
302 */317 */
303int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new,318int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new,
304 afs_access_t *_caller_access)319 afs_access_t *_caller_access)
305{320{
306 struct afs_status_cb *scb;321 struct afs_operation *op;
307 struct afs_fs_cursor fc;
308 int ret;
309 322
310 _enter("%s,{%llx:%llu.%u,S=%lx}",323 _enter("%s,{%llx:%llu.%u,S=%lx}",
311 vnode->volume->name,324 vnode->volume->name,
312 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,325 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
313 vnode->flags);326 vnode->flags);
314 327
315 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);328 op = afs_alloc_operation(key, vnode->volume);
316 if (!scb)329 if (IS_ERR(op))
317 return -ENOMEM;330 return PTR_ERR(op);
318 331
319 ret = -ERESTARTSYS;332 afs_op_set_vnode(op, 0, vnode);
320 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
321 afs_dataversion_t data_version = vnode->status.data_version;
322 333
323 while (afs_select_fileserver(&fc)) {334 op->nr_files = 1;
324 fc.cb_break = afs_calc_vnode_cb_break(vnode);335 op->ops = &afs_fetch_status_operation;
325 afs_fs_fetch_file_status(&fc, scb, NULL);336 afs_begin_vnode_operation(op);
326 }337 afs_wait_for_operation(op);
327
328 if (fc.error) {
329 /* Do nothing. */
330 } else if (is_new) {
331 ret = afs_inode_init_from_status(vnode, key, fc.cbi,
332 NULL, scb);
333 fc.error = ret;
334 if (ret == 0)
335 afs_cache_permit(vnode, key, fc.cb_break, scb);
336 } else {
337 afs_vnode_commit_status(&fc, vnode, fc.cb_break,
338 &data_version, scb);
339 }
340 afs_check_for_remote_deletion(&fc, vnode);
341 ret = afs_end_vnode_operation(&fc);
342 }
343 338
344 if (ret == 0 && _caller_access)339 if (_caller_access)
345 *_caller_access = scb->status.caller_access;340 *_caller_access = op->file[0].scb.status.caller_access;
346 kfree(scb);341 return afs_put_operation(op);
347 _leave(" = %d", ret);
348 return ret;
349}342}
350 343
351/*344/*
352 * iget5() comparator345 * ilookup() comparator
353 */346 */
354int afs_iget5_test(struct inode *inode, void *opaque)347int afs_ilookup5_test_by_fid(struct inode *inode, void *opaque)
355{348{
356 struct afs_iget_data *iget_data = opaque;
357 struct afs_vnode *vnode = AFS_FS_I(inode);349 struct afs_vnode *vnode = AFS_FS_I(inode);
350 struct afs_fid *fid = opaque;
358 351
359 return memcmp(&vnode->fid, &iget_data->fid, sizeof(iget_data->fid)) == 0;352 return (fid->vnode == vnode->fid.vnode &&
353 fid->vnode_hi == vnode->fid.vnode_hi &&
354 fid->unique == vnode->fid.unique);
360}355}
361 356
362/*357/*
363 * iget5() comparator for inode created by autocell operations358 * iget5() comparator
364 *
365 * These pseudo inodes don't match anything.
366 */359 */
367static int afs_iget5_pseudo_dir_test(struct inode *inode, void *opaque)360static int afs_iget5_test(struct inode *inode, void *opaque)
368{361{
369 return 0;362 struct afs_vnode_param *vp = opaque;
363 //struct afs_vnode *vnode = AFS_FS_I(inode);
364
365 return afs_ilookup5_test_by_fid(inode, &vp->fid);
370}366}
371 367
372/*368/*
@@ -374,98 +370,21 @@ static int afs_iget5_pseudo_dir_test(struct inode *inode, void *opaque) · 1 unmodified line
374 */370 */
375static int afs_iget5_set(struct inode *inode, void *opaque)371static int afs_iget5_set(struct inode *inode, void *opaque)
376{372{
377 struct afs_iget_data *iget_data = opaque;373 struct afs_vnode_param *vp = opaque;
374 struct afs_super_info *as = AFS_FS_S(inode->i_sb);
378 struct afs_vnode *vnode = AFS_FS_I(inode);375 struct afs_vnode *vnode = AFS_FS_I(inode);
379 376
380 vnode->fid = iget_data->fid;377 vnode->volume = as->volume;
381 vnode->volume = iget_data->volume;378 vnode->fid = vp->fid;
382 vnode->cb_v_break = iget_data->cb_v_break;
383 vnode->cb_s_break = iget_data->cb_s_break;
384 379
385 /* YFS supports 96-bit vnode IDs, but Linux only supports380 /* YFS supports 96-bit vnode IDs, but Linux only supports
386 * 64-bit inode numbers.381 * 64-bit inode numbers.
387 */382 */
388 inode->i_ino = iget_data->fid.vnode;383 inode->i_ino = vnode->fid.vnode;
389 inode->i_generation = iget_data->fid.unique;384 inode->i_generation = vnode->fid.unique;
390 return 0;385 return 0;
391}386}
392 387
393/*
394 * Create an inode for a dynamic root directory or an autocell dynamic
395 * automount dir.
396 */
397struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root)
398{
399 struct afs_super_info *as;
400 struct afs_vnode *vnode;
401 struct inode *inode;
402 static atomic_t afs_autocell_ino;
403
404 struct afs_iget_data iget_data = {
405 .cb_v_break = 0,
406 .cb_s_break = 0,
407 };
408
409 _enter("");
410
411 as = sb->s_fs_info;
412 if (as->volume) {
413 iget_data.volume = as->volume;
414 iget_data.fid.vid = as->volume->vid;
415 }
416 if (root) {
417 iget_data.fid.vnode = 1;
418 iget_data.fid.unique = 1;
419 } else {
420 iget_data.fid.vnode = atomic_inc_return(&afs_autocell_ino);
421 iget_data.fid.unique = 0;
422 }
423
424 inode = iget5_locked(sb, iget_data.fid.vnode,
425 afs_iget5_pseudo_dir_test, afs_iget5_set,
426 &iget_data);
427 if (!inode) {
428 _leave(" = -ENOMEM");
429 return ERR_PTR(-ENOMEM);
430 }
431
432 _debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }",
433 inode, inode->i_ino, iget_data.fid.vid, iget_data.fid.vnode,
434 iget_data.fid.unique);
435
436 vnode = AFS_FS_I(inode);
437
438 /* there shouldn't be an existing inode */
439 BUG_ON(!(inode->i_state & I_NEW));
440
441 inode->i_size = 0;
442 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
443 if (root) {
444 inode->i_op = &afs_dynroot_inode_operations;
445 inode->i_fop = &simple_dir_operations;
446 } else {
447 inode->i_op = &afs_autocell_inode_operations;
448 }
449 set_nlink(inode, 2);
450 inode->i_uid = GLOBAL_ROOT_UID;
451 inode->i_gid = GLOBAL_ROOT_GID;
452 inode->i_ctime = inode->i_atime = inode->i_mtime = current_time(inode);
453 inode->i_blocks = 0;
454 inode_set_iversion_raw(inode, 0);
455 inode->i_generation = 0;
456
457 set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags);
458 if (!root) {
459 set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);
460 inode->i_flags |= S_AUTOMOUNT;
461 }
462
463 inode->i_flags |= S_NOATIME;
464 unlock_new_inode(inode);
465 _leave(" = %p", inode);
466 return inode;
467}
468
469/*388/*
470 * Get a cache cookie for an inode.389 * Get a cache cookie for an inode.
471 */390 */
@@ -501,58 +420,41 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) · 29 unmodified lines
501/*420/*
502 * inode retrieval421 * inode retrieval
503 */422 */
504struct inode *afs_iget(struct super_block *sb, struct key *key,423struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp)
505 struct afs_iget_data *iget_data,
506 struct afs_status_cb *scb,
507 struct afs_cb_interest *cbi,
508 struct afs_vnode *parent_vnode)
509{424{
510 struct afs_super_info *as;425 struct afs_vnode_param *dvp = &op->file[0];
426 struct super_block *sb = dvp->vnode->vfs_inode.i_sb;
511 struct afs_vnode *vnode;427 struct afs_vnode *vnode;
512 struct afs_fid *fid = &iget_data->fid;
513 struct inode *inode;428 struct inode *inode;
514 int ret;429 int ret;
515 430
516 _enter(",{%llx:%llu.%u},,", fid->vid, fid->vnode, fid->unique);431 _enter(",{%llx:%llu.%u},,", vp->fid.vid, vp->fid.vnode, vp->fid.unique);
517 432
518 as = sb->s_fs_info;433 inode = iget5_locked(sb, vp->fid.vnode, afs_iget5_test, afs_iget5_set, vp);
519 iget_data->volume = as->volume;
520
521 inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
522 iget_data);
523 if (!inode) {434 if (!inode) {
524 _leave(" = -ENOMEM");435 _leave(" = -ENOMEM");
525 return ERR_PTR(-ENOMEM);436 return ERR_PTR(-ENOMEM);
526 }437 }
527 438
528 _debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }",
529 inode, fid->vid, fid->vnode, fid->unique);
530
531 vnode = AFS_FS_I(inode);439 vnode = AFS_FS_I(inode);
532 440
441 _debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }",
442 inode, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
443
533 /* deal with an existing inode */444 /* deal with an existing inode */
534 if (!(inode->i_state & I_NEW)) {445 if (!(inode->i_state & I_NEW)) {
535 _leave(" = %p", inode);446 _leave(" = %p", inode);
536 return inode;447 return inode;
537 }448 }
538 449
539 if (!scb) {450 ret = afs_inode_init_from_status(op, vp, vnode);
540 /* it's a remotely extant inode */451 if (ret < 0)
541 ret = afs_fetch_status(vnode, key, true, NULL);452 goto bad_inode;
542 if (ret < 0)
543 goto bad_inode;
544 } else {
545 ret = afs_inode_init_from_status(vnode, key, cbi, parent_vnode,
546 scb);
547 if (ret < 0)
548 goto bad_inode;
549 }
550 453
551 afs_get_inode_cache(vnode);454 afs_get_inode_cache(vnode);
552 455
553 /* success */456 /* success */
554 clear_bit(AFS_VNODE_UNSET, &vnode->flags);457 clear_bit(AFS_VNODE_UNSET, &vnode->flags);
555 inode->i_flags |= S_NOATIME;
556 unlock_new_inode(inode);458 unlock_new_inode(inode);
557 _leave(" = %p", inode);459 _leave(" = %p", inode);
558 return inode;460 return inode;
@@ -564,6 +466,74 @@ bad_inode: · 5 unmodified lines
564 return ERR_PTR(ret);466 return ERR_PTR(ret);
565}467}
566 468
469static int afs_iget5_set_root(struct inode *inode, void *opaque)
470{
471 struct afs_super_info *as = AFS_FS_S(inode->i_sb);
472 struct afs_vnode *vnode = AFS_FS_I(inode);
473
474 vnode->volume = as->volume;
475 vnode->fid.vid = as->volume->vid,
476 vnode->fid.vnode = 1;
477 vnode->fid.unique = 1;
478 inode->i_ino = 1;
479 inode->i_generation = 1;
480 return 0;
481}
482
483/*
484 * Set up the root inode for a volume. This is always vnode 1, unique 1 within
485 * the volume.
486 */
487struct inode *afs_root_iget(struct super_block *sb, struct key *key)
488{
489 struct afs_super_info *as = AFS_FS_S(sb);
490 struct afs_operation *op;
491 struct afs_vnode *vnode;
492 struct inode *inode;
493 int ret;
494
495 _enter(",{%llx},,", as->volume->vid);
496
497 inode = iget5_locked(sb, 1, NULL, afs_iget5_set_root, NULL);
498 if (!inode) {
499 _leave(" = -ENOMEM");
500 return ERR_PTR(-ENOMEM);
501 }
502
503 _debug("GOT ROOT INODE %p { vl=%llx }", inode, as->volume->vid);
504
505 BUG_ON(!(inode->i_state & I_NEW));
506
507 vnode = AFS_FS_I(inode);
508 vnode->cb_v_break = as->volume->cb_v_break,
509
510 op = afs_alloc_operation(key, as->volume);
511 if (IS_ERR(op)) {
512 ret = PTR_ERR(op);
513 goto error;
514 }
515
516 afs_op_set_vnode(op, 0, vnode);
517
518 op->nr_files = 1;
519 op->ops = &afs_fetch_status_operation;
520 ret = afs_do_sync_operation(op);
521 if (ret < 0)
522 goto error;
523
524 afs_get_inode_cache(vnode);
525
526 clear_bit(AFS_VNODE_UNSET, &vnode->flags);
527 unlock_new_inode(inode);
528 _leave(" = %p", inode);
529 return inode;
530
531error:
532 iget_failed(inode);
533 _leave(" = %d [bad]", ret);
534 return ERR_PTR(ret);
535}
536
567/*537/*
568 * mark the data attached to an inode as obsolete due to a write on the server538 * mark the data attached to an inode as obsolete due to a write on the server
569 * - might also want to ditch all the outstanding writes and dirty pages539 * - might also want to ditch all the outstanding writes and dirty pages
@@ -585,13 +555,31 @@ void afs_zap_data(struct afs_vnode *vnode) · 15 unmodified lines
585 invalidate_inode_pages2(vnode->vfs_inode.i_mapping);555 invalidate_inode_pages2(vnode->vfs_inode.i_mapping);
586}556}
587 557
558/*
559 * Get the server reinit counter for a vnode's current server.
560 */
561static bool afs_get_s_break_rcu(struct afs_vnode *vnode, unsigned int *_s_break)
562{
563 struct afs_server_list *slist = rcu_dereference(vnode->volume->servers);
564 struct afs_server *server;
565 int i;
566
567 for (i = 0; i < slist->nr_servers; i++) {
568 server = slist->servers[i].server;
569 if (server == vnode->cb_server) {
570 *_s_break = READ_ONCE(server->cb_s_break);
571 return true;
572 }
573 }
574
575 return false;
576}
577
588/*578/*
589 * Check the validity of a vnode/inode.579 * Check the validity of a vnode/inode.
590 */580 */
591bool afs_check_validity(struct afs_vnode *vnode)581bool afs_check_validity(struct afs_vnode *vnode)
592{582{
593 struct afs_cb_interest *cbi;
594 struct afs_server *server;
595 struct afs_volume *volume = vnode->volume;583 struct afs_volume *volume = vnode->volume;
596 enum afs_cb_break_reason need_clear = afs_cb_break_no_break;584 enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
597 time64_t now = ktime_get_real_seconds();585 time64_t now = ktime_get_real_seconds();
@@ -604,11 +592,8 @@ bool afs_check_validity(struct afs_vnode *vnode) · 6 unmodified lines
604 cb_v_break = READ_ONCE(volume->cb_v_break);592 cb_v_break = READ_ONCE(volume->cb_v_break);
605 cb_break = vnode->cb_break;593 cb_break = vnode->cb_break;
606 594
607 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {595 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) &&
608 cbi = rcu_dereference(vnode->cb_interest);596 afs_get_s_break_rcu(vnode, &cb_s_break)) {
609 server = rcu_dereference(cbi->server);
610 cb_s_break = READ_ONCE(server->cb_s_break);
611
612 if (vnode->cb_s_break != cb_s_break ||597 if (vnode->cb_s_break != cb_s_break ||
613 vnode->cb_v_break != cb_v_break) {598 vnode->cb_v_break != cb_v_break) {
614 vnode->cb_s_break = cb_s_break;599 vnode->cb_s_break = cb_s_break;
@@ -755,7 +740,6 @@ int afs_drop_inode(struct inode *inode) · 140 unmodified lines
755 */740 */
756void afs_evict_inode(struct inode *inode)741void afs_evict_inode(struct inode *inode)
757{742{
758 struct afs_cb_interest *cbi;
759 struct afs_vnode *vnode;743 struct afs_vnode *vnode;
760 744
761 vnode = AFS_FS_I(inode);745 vnode = AFS_FS_I(inode);
@@ -772,15 +756,6 @@ void afs_evict_inode(struct inode *inode) · 10 unmodified lines
772 truncate_inode_pages_final(&inode->i_data);756 truncate_inode_pages_final(&inode->i_data);
773 clear_inode(inode);757 clear_inode(inode);
774 758
775 write_seqlock(&vnode->cb_lock);
776 cbi = rcu_dereference_protected(vnode->cb_interest,
777 lockdep_is_held(&vnode->cb_lock.lock));
778 if (cbi) {
779 afs_put_cb_interest(afs_i2net(inode), cbi);
780 rcu_assign_pointer(vnode->cb_interest, NULL);
781 }
782 write_sequnlock(&vnode->cb_lock);
783
784 while (!list_empty(&vnode->wb_keys)) {759 while (!list_empty(&vnode->wb_keys)) {
785 struct afs_wb_key *wbk = list_entry(vnode->wb_keys.next,760 struct afs_wb_key *wbk = list_entry(vnode->wb_keys.next,
786 struct afs_wb_key, vnode_link);761 struct afs_wb_key, vnode_link);
@@ -808,16 +783,24 @@ void afs_evict_inode(struct inode *inode) · 21 unmodified lines
808 _leave("");783 _leave("");
809}784}
810 785
786static void afs_setattr_success(struct afs_operation *op)
787{
788 afs_vnode_commit_status(op, &op->file[0]);
789}
790
791static const struct afs_operation_ops afs_setattr_operation = {
792 .issue_afs_rpc = afs_fs_setattr,
793 .issue_yfs_rpc = yfs_fs_setattr,
794 .success = afs_setattr_success,
795};
796
811/*797/*
812 * set the attributes of an inode798 * set the attributes of an inode
813 */799 */
814int afs_setattr(struct dentry *dentry, struct iattr *attr)800int afs_setattr(struct dentry *dentry, struct iattr *attr)
815{801{
816 struct afs_fs_cursor fc;802 struct afs_operation *op;
817 struct afs_status_cb *scb;
818 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));803 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
819 struct key *key;
820 int ret = -ENOMEM;
821 804
822 _enter("{%llx:%llu},{n=%pd},%x",805 _enter("{%llx:%llu},{n=%pd},%x",
823 vnode->fid.vid, vnode->fid.vnode, dentry,806 vnode->fid.vid, vnode->fid.vnode, dentry,
@@ -829,48 +812,22 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr) · 5 unmodified lines
829 return 0;812 return 0;
830 }813 }
831 814
832 scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL);
833 if (!scb)
834 goto error;
835
836 /* flush any dirty data outstanding on a regular file */815 /* flush any dirty data outstanding on a regular file */
837 if (S_ISREG(vnode->vfs_inode.i_mode))816 if (S_ISREG(vnode->vfs_inode.i_mode))
838 filemap_write_and_wait(vnode->vfs_inode.i_mapping);817 filemap_write_and_wait(vnode->vfs_inode.i_mapping);
839 818
840 if (attr->ia_valid & ATTR_FILE) {819 op = afs_alloc_operation(((attr->ia_valid & ATTR_FILE) ?
841 key = afs_file_key(attr->ia_file);820 afs_file_key(attr->ia_file) : NULL),
842 } else {821 vnode->volume);
843 key = afs_request_key(vnode->volume->cell);822 if (IS_ERR(op))
844 if (IS_ERR(key)) {823 return PTR_ERR(op);
845 ret = PTR_ERR(key);
846 goto error_scb;
847 }
848 }
849
850 ret = -ERESTARTSYS;
851 if (afs_begin_vnode_operation(&fc, vnode, key, false)) {
852 afs_dataversion_t data_version = vnode->status.data_version;
853 824
854 if (attr->ia_valid & ATTR_SIZE)825 afs_op_set_vnode(op, 0, vnode);
855 data_version++;826 op->setattr.attr = attr;
856 827
857 while (afs_select_fileserver(&fc)) {828 if (attr->ia_valid & ATTR_SIZE)
858 fc.cb_break = afs_calc_vnode_cb_break(vnode);829 op->file[0].dv_delta = 1;
859 afs_fs_setattr(&fc, attr, scb);
860 }
861
862 afs_check_for_remote_deletion(&fc, vnode);
863 afs_vnode_commit_status(&fc, vnode, fc.cb_break,
864 &data_version, scb);
865 ret = afs_end_vnode_operation(&fc);
866 }
867 830
868 if (!(attr->ia_valid & ATTR_FILE))831 op->ops = &afs_setattr_operation;
869 key_put(key);832 return afs_do_sync_operation(op);
870
871error_scb:
872 kfree(scb);
873error:
874 _leave(" = %d", ret);
875 return ret;
876}833}
fs/afs/internal.h+299−224
@@ -59,13 +59,6 @@ struct afs_fs_context { · 58 unmodified lines
59 struct key *key; /* key to use for secure mounting */59 struct key *key; /* key to use for secure mounting */
60};60};
61 61
62struct 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
69enum afs_call_state {62enum afs_call_state {
70 AFS_CALL_CL_REQUESTING, /* Client: Request is being sent */63 AFS_CALL_CL_REQUESTING, /* Client: Request is being sent */
71 AFS_CALL_CL_AWAIT_REPLY, /* Client: Awaiting reply */64 AFS_CALL_CL_AWAIT_REPLY, /* Client: Awaiting reply */
@@ -90,7 +83,6 @@ struct afs_addr_list { · 18 unmodified lines
90 unsigned char nr_ipv4; /* Number of IPv4 addresses */83 unsigned char nr_ipv4; /* Number of IPv4 addresses */
91 enum dns_record_source source:8;84 enum dns_record_source source:8;
92 enum dns_lookup_status status:8;85 enum dns_lookup_status status:8;
93 unsigned long probed; /* Mask of servers that have been probed */
94 unsigned long failed; /* Mask of addrs that failed locally/ICMP */86 unsigned long failed; /* Mask of addrs that failed locally/ICMP */
95 unsigned long responded; /* Mask of addrs that responded */87 unsigned long responded; /* Mask of addrs that responded */
96 struct sockaddr_rxrpc addrs[];88 struct sockaddr_rxrpc addrs[];
@@ -111,10 +103,7 @@ struct afs_call { · 14 unmodified lines
111 struct afs_net *net; /* The network namespace */103 struct afs_net *net; /* The network namespace */
112 struct afs_server *server; /* The fileserver record if fs op (pins ref) */104 struct afs_server *server; /* The fileserver record if fs op (pins ref) */
113 struct afs_vlserver *vlserver; /* The vlserver record if vl op */105 struct afs_vlserver *vlserver; /* The vlserver record if vl op */
114 struct afs_cb_interest *cbi; /* Callback interest for server used */
115 struct afs_vnode *lvnode; /* vnode being locked */
116 void *request; /* request data (first part) */106 void *request; /* request data (first part) */
117 struct address_space *mapping; /* Pages being written from */
118 struct iov_iter def_iter; /* Default buffer/data iterator */107 struct iov_iter def_iter; /* Default buffer/data iterator */
119 struct iov_iter *iter; /* Iterator currently in use */108 struct iov_iter *iter; /* Iterator currently in use */
120 union { /* Convenience for ->def_iter */109 union { /* Convenience for ->def_iter */
@@ -126,32 +115,19 @@ struct afs_call { · 5 unmodified lines
126 long ret0; /* Value to reply with instead of 0 */115 long ret0; /* Value to reply with instead of 0 */
127 struct afs_addr_list *ret_alist;116 struct afs_addr_list *ret_alist;
128 struct afs_vldb_entry *ret_vldb;117 struct afs_vldb_entry *ret_vldb;
129 struct afs_acl *ret_acl;118 char *ret_str;
130 };119 };
131 struct afs_fid *out_fid;120 struct afs_operation *op;
132 struct afs_status_cb *out_dir_scb;
133 struct afs_status_cb *out_scb;
134 struct yfs_acl *out_yacl;
135 struct afs_volsync *out_volsync;
136 struct afs_volume_status *out_volstatus;
137 struct afs_read *read_request;
138 unsigned int server_index;121 unsigned int server_index;
139 pgoff_t first; /* first page in mapping to deal with */
140 pgoff_t last; /* last page in mapping to deal with */
141 atomic_t usage;122 atomic_t usage;
142 enum afs_call_state state;123 enum afs_call_state state;
143 spinlock_t state_lock;124 spinlock_t state_lock;
144 int error; /* error code */125 int error; /* error code */
145 u32 abort_code; /* Remote abort ID or 0 */126 u32 abort_code; /* Remote abort ID or 0 */
146 u32 epoch;
147 unsigned int max_lifespan; /* Maximum lifespan to set if not 0 */127 unsigned int max_lifespan; /* Maximum lifespan to set if not 0 */
148 unsigned request_size; /* size of request data */128 unsigned request_size; /* size of request data */
149 unsigned reply_max; /* maximum size of reply */129 unsigned reply_max; /* maximum size of reply */
150 unsigned first_offset; /* offset into mapping[first] */130 unsigned count2; /* count used in unmarshalling */
151 union {
152 unsigned last_to; /* amount of mapping[last] */
153 unsigned count2; /* count used in unmarshalling */
154 };
155 unsigned char unmarshall; /* unmarshalling phase */131 unsigned char unmarshall; /* unmarshalling phase */
156 unsigned char addr_ix; /* Address in ->alist */132 unsigned char addr_ix; /* Address in ->alist */
157 bool drop_ref; /* T if need to drop ref for incoming call */133 bool drop_ref; /* T if need to drop ref for incoming call */
@@ -161,6 +137,7 @@ struct afs_call { · 3 unmodified lines
161 bool upgrade; /* T to request service upgrade */137 bool upgrade; /* T to request service upgrade */
162 bool have_reply_time; /* T if have got reply_time */138 bool have_reply_time; /* T if have got reply_time */
163 bool intr; /* T if interruptible */139 bool intr; /* T if interruptible */
140 bool unmarshalling_error; /* T if an unmarshalling error occurred */
164 u16 service_id; /* Actual service ID (after upgrade) */141 u16 service_id; /* Actual service ID (after upgrade) */
165 unsigned int debug_id; /* Trace ID */142 unsigned int debug_id; /* Trace ID */
166 u32 operation_ID; /* operation ID for an incoming call */143 u32 operation_ID; /* operation ID for an incoming call */
@@ -291,6 +268,7 @@ struct afs_net { · 124 unmodified lines
291 struct timer_list cells_timer;268 struct timer_list cells_timer;
292 atomic_t cells_outstanding;269 atomic_t cells_outstanding;
293 seqlock_t cells_lock;270 seqlock_t cells_lock;
271 struct mutex cells_alias_lock;
294 272
295 struct mutex proc_cells_lock;273 struct mutex proc_cells_lock;
296 struct hlist_head proc_cells;274 struct hlist_head proc_cells;
@@ -299,9 +277,10 @@ struct afs_net { · 2 unmodified lines
299 * cell, but in practice, people create aliases and subsets and there's277 * cell, but in practice, people create aliases and subsets and there's
300 * no easy way to distinguish them.278 * no easy way to distinguish them.
301 */279 */
302 seqlock_t fs_lock; /* For fs_servers */280 seqlock_t fs_lock; /* For fs_servers, fs_probe_*, fs_proc */
303 struct rb_root fs_servers; /* afs_server (by server UUID or address) */281 struct rb_root fs_servers; /* afs_server (by server UUID or address) */
304 struct list_head fs_updates; /* afs_server (by update_at) */282 struct list_head fs_probe_fast; /* List of afs_server to probe at 30s intervals */
283 struct list_head fs_probe_slow; /* List of afs_server to probe at 5m intervals */
305 struct hlist_head fs_proc; /* procfs servers list */284 struct hlist_head fs_proc; /* procfs servers list */
306 285
307 struct hlist_head fs_addresses4; /* afs_server (by lowest IPv4 addr) */286 struct hlist_head fs_addresses4; /* afs_server (by lowest IPv4 addr) */
@@ -310,6 +289,9 @@ struct afs_net { · 2 unmodified lines
310 289
311 struct work_struct fs_manager;290 struct work_struct fs_manager;
312 struct timer_list fs_timer;291 struct timer_list fs_timer;
292
293 struct work_struct fs_prober;
294 struct timer_list fs_probe_timer;
313 atomic_t servers_outstanding;295 atomic_t servers_outstanding;
314 296
315 /* File locking renewal management */297 /* File locking renewal management */
@@ -360,8 +342,10 @@ enum afs_cell_state { · 44 unmodified lines
360 * for authentication and encryption. The cell name is not typically used in342 * for authentication and encryption. The cell name is not typically used in
361 * the protocol.343 * the protocol.
362 *344 *
363 * There is no easy way to determine if two cells are aliases or one is a345 * Two cells are determined to be aliases if they have an explicit alias (YFS
364 * subset of another.346 * only), share any VL servers in common or have at least one volume in common.
347 * "In common" means that the address list of the VL servers or the fileservers
348 * share at least one endpoint.
365 */349 */
366struct afs_cell {350struct afs_cell {
367 union {351 union {
@@ -369,6 +353,8 @@ struct afs_cell { · 1 unmodified line
369 struct rb_node net_node; /* Node in net->cells */353 struct rb_node net_node; /* Node in net->cells */
370 };354 };
371 struct afs_net *net;355 struct afs_net *net;
356 struct afs_cell *alias_of; /* The cell this is an alias of */
357 struct afs_volume *root_volume; /* The root.cell volume if there is one */
372 struct key *anonymous_key; /* anonymous user key for this cell */358 struct key *anonymous_key; /* anonymous user key for this cell */
373 struct work_struct manager; /* Manager for init/deinit/dns */359 struct work_struct manager; /* Manager for init/deinit/dns */
374 struct hlist_node proc_link; /* /proc cell list link */360 struct hlist_node proc_link; /* /proc cell list link */
@@ -381,15 +367,21 @@ struct afs_cell { · 6 unmodified lines
381 unsigned long flags;367 unsigned long flags;
382#define AFS_CELL_FL_NO_GC 0 /* The cell was added manually, don't auto-gc */368#define AFS_CELL_FL_NO_GC 0 /* The cell was added manually, don't auto-gc */
383#define AFS_CELL_FL_DO_LOOKUP 1 /* DNS lookup requested */369#define AFS_CELL_FL_DO_LOOKUP 1 /* DNS lookup requested */
370#define AFS_CELL_FL_CHECK_ALIAS 2 /* Need to check for aliases */
384 enum afs_cell_state state;371 enum afs_cell_state state;
385 short error;372 short error;
386 enum dns_record_source dns_source:8; /* Latest source of data from lookup */373 enum dns_record_source dns_source:8; /* Latest source of data from lookup */
387 enum dns_lookup_status dns_status:8; /* Latest status of data from lookup */374 enum dns_lookup_status dns_status:8; /* Latest status of data from lookup */
388 unsigned int dns_lookup_count; /* Counter of DNS lookups */375 unsigned int dns_lookup_count; /* Counter of DNS lookups */
389 376
377 /* The volumes belonging to this cell */
378 struct rb_root volumes; /* Tree of volumes on this server */
379 struct hlist_head proc_volumes; /* procfs volume list */
380 seqlock_t volume_lock; /* For volumes */
381
390 /* Active fileserver interaction state. */382 /* Active fileserver interaction state. */
391 struct list_head proc_volumes; /* procfs volume list */383 struct rb_root fs_servers; /* afs_server (by server UUID) */
392 rwlock_t proc_lock;384 seqlock_t fs_lock; /* For fs_servers */
393 385
394 /* VL server list. */386 /* VL server list. */
395 rwlock_t vl_servers_lock; /* Lock on vl_servers */387 rwlock_t vl_servers_lock; /* Lock on vl_servers */
@@ -471,6 +463,7 @@ struct afs_vldb_entry { · 75 unmodified lines
471#define AFS_VLDB_QUERY_ERROR 4 /* - VL server returned error */463#define AFS_VLDB_QUERY_ERROR 4 /* - VL server returned error */
472 464
473 uuid_t fs_server[AFS_NMAXNSERVERS];465 uuid_t fs_server[AFS_NMAXNSERVERS];
466 u32 addr_version[AFS_NMAXNSERVERS]; /* Registration change counters */
474 u8 fs_mask[AFS_NMAXNSERVERS];467 u8 fs_mask[AFS_NMAXNSERVERS];
475#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */468#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */
476#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */469#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */
@@ -492,94 +485,64 @@ struct afs_server { · 15 unmodified lines
492 };485 };
493 486
494 struct afs_addr_list __rcu *addresses;487 struct afs_addr_list __rcu *addresses;
495 struct rb_node uuid_rb; /* Link in net->servers */488 struct afs_cell *cell; /* Cell to which belongs (pins ref) */
489 struct rb_node uuid_rb; /* Link in net->fs_servers */
490 struct afs_server __rcu *uuid_next; /* Next server with same UUID */
491 struct afs_server *uuid_prev; /* Previous server with same UUID */
492 struct list_head probe_link; /* Link in net->fs_probe_list */
496 struct hlist_node addr4_link; /* Link in net->fs_addresses4 */493 struct hlist_node addr4_link; /* Link in net->fs_addresses4 */
497 struct hlist_node addr6_link; /* Link in net->fs_addresses6 */494 struct hlist_node addr6_link; /* Link in net->fs_addresses6 */
498 struct hlist_node proc_link; /* Link in net->fs_proc */495 struct hlist_node proc_link; /* Link in net->fs_proc */
499 struct afs_server *gc_next; /* Next server in manager's list */496 struct afs_server *gc_next; /* Next server in manager's list */
500 time64_t put_time; /* Time at which last put */497 time64_t unuse_time; /* Time at which last unused */
501 time64_t update_at; /* Time at which to next update the record */
502 unsigned long flags;498 unsigned long flags;
503#define AFS_SERVER_FL_NOT_READY 1 /* The record is not ready for use */499#define AFS_SERVER_FL_RESPONDING 0 /* The server is responding */
504#define AFS_SERVER_FL_NOT_FOUND 2 /* VL server says no such server */500#define AFS_SERVER_FL_UPDATING 1
505#define AFS_SERVER_FL_VL_FAIL 3 /* Failed to access VL server */501#define AFS_SERVER_FL_NEEDS_UPDATE 2 /* Fileserver address list is out of date */
506#define AFS_SERVER_FL_UPDATING 4502#define AFS_SERVER_FL_NOT_READY 4 /* The record is not ready for use */
507#define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */503#define AFS_SERVER_FL_NOT_FOUND 5 /* VL server says no such server */
508#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */504#define AFS_SERVER_FL_VL_FAIL 6 /* Failed to access VL server */
509#define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */
510#define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */505#define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */
511#define AFS_SERVER_FL_IS_YFS 9 /* Server is YFS not AFS */506#define AFS_SERVER_FL_IS_YFS 16 /* Server is YFS not AFS */
512#define AFS_SERVER_FL_NO_RM2 10 /* Fileserver doesn't support YFS.RemoveFile2 */507#define AFS_SERVER_FL_NO_IBULK 17 /* Fileserver doesn't support FS.InlineBulkStatus */
513#define AFS_SERVER_FL_HAVE_EPOCH 11 /* ->epoch is valid */508#define AFS_SERVER_FL_NO_RM2 18 /* Fileserver doesn't support YFS.RemoveFile2 */
514 atomic_t usage;509 atomic_t ref; /* Object refcount */
510 atomic_t active; /* Active user count */
515 u32 addr_version; /* Address list version */511 u32 addr_version; /* Address list version */
516 u32 cm_epoch; /* Server RxRPC epoch */512 unsigned int rtt; /* Server's current RTT in uS */
517 unsigned int debug_id; /* Debugging ID for traces */513 unsigned int debug_id; /* Debugging ID for traces */
518 514
519 /* file service access */515 /* file service access */
520 rwlock_t fs_lock; /* access lock */516 rwlock_t fs_lock; /* access lock */
521 517
522 /* callback promise management */518 /* callback promise management */
523 struct hlist_head cb_volumes; /* List of volume interests on this server */
524 unsigned cb_s_break; /* Break-everything counter. */519 unsigned cb_s_break; /* Break-everything counter. */
525 rwlock_t cb_break_lock; /* Volume finding lock */
526 520
527 /* Probe state */521 /* Probe state */
522 unsigned long probed_at; /* Time last probe was dispatched (jiffies) */
528 wait_queue_head_t probe_wq;523 wait_queue_head_t probe_wq;
529 atomic_t probe_outstanding;524 atomic_t probe_outstanding;
530 spinlock_t probe_lock;525 spinlock_t probe_lock;
531 struct {526 struct {
532 unsigned int rtt; /* RTT as ktime/64 */527 unsigned int rtt; /* RTT in uS */
533 u32 abort_code;528 u32 abort_code;
534 u32 cm_epoch;
535 short error;529 short error;
536 bool responded:1;530 bool responded:1;
537 bool is_yfs:1;531 bool is_yfs:1;
538 bool not_yfs:1;532 bool not_yfs:1;
539 bool local_failure:1;533 bool local_failure:1;
540 bool cm_probed:1;
541 bool said_rebooted:1;
542 bool said_inconsistent:1;
543 } probe;534 } probe;
544};535};
545 536
546/*537/*
547 * Volume collation in the server's callback interest list.538 * Replaceable volume server list.
548 */
549struct afs_vol_interest {
550 struct hlist_node srv_link; /* Link in server->cb_volumes */
551 struct hlist_head cb_interests; /* List of callback interests on the server */
552 union {
553 struct rcu_head rcu;
554 afs_volid_t vid; /* Volume ID to match */
555 };
556 unsigned int usage;
557};
558
559/*
560 * Interest by a superblock on a server.
561 */
562struct afs_cb_interest {
563 struct hlist_node cb_vlink; /* Link in vol_interest->cb_interests */
564 struct afs_vol_interest *vol_interest;
565 struct afs_server *server; /* Server on which this interest resides */
566 struct super_block *sb; /* Superblock on which inodes reside */
567 union {
568 struct rcu_head rcu;
569 afs_volid_t vid; /* Volume ID to match */
570 };
571 refcount_t usage;
572};
573
574/*
575 * Replaceable server list.
576 */539 */
577struct afs_server_entry {540struct afs_server_entry {
578 struct afs_server *server;541 struct afs_server *server;
579 struct afs_cb_interest *cb_interest;
580};542};
581 543
582struct afs_server_list {544struct afs_server_list {
545 afs_volid_t vids[AFS_MAXTYPES]; /* Volume IDs */
583 refcount_t usage;546 refcount_t usage;
584 unsigned char nr_servers;547 unsigned char nr_servers;
585 unsigned char preferred; /* Preferred server */548 unsigned char preferred; /* Preferred server */
@@ -593,11 +556,16 @@ struct afs_server_list { · 7 unmodified lines
593 * Live AFS volume management.556 * Live AFS volume management.
594 */557 */
595struct afs_volume {558struct afs_volume {
596 afs_volid_t vid; /* volume ID */559 union {
560 struct rcu_head rcu;
561 afs_volid_t vid; /* volume ID */
562 };
597 atomic_t usage;563 atomic_t usage;
598 time64_t update_at; /* Time at which to next update */564 time64_t update_at; /* Time at which to next update */
599 struct afs_cell *cell; /* Cell to which belongs (pins ref) */565 struct afs_cell *cell; /* Cell to which belongs (pins ref) */
600 struct list_head proc_link; /* Link in cell->vl_proc */566 struct rb_node cell_node; /* Link in cell->volumes */
567 struct hlist_node proc_link; /* Link in cell->proc_volumes */
568 struct super_block __rcu *sb; /* Superblock on which inodes reside */
601 unsigned long flags;569 unsigned long flags;
602#define AFS_VOLUME_NEEDS_UPDATE 0 /* - T if an update needs performing */570#define AFS_VOLUME_NEEDS_UPDATE 0 /* - T if an update needs performing */
603#define AFS_VOLUME_UPDATING 1 /* - T if an update is in progress */571#define AFS_VOLUME_UPDATING 1 /* - T if an update is in progress */
@@ -605,10 +573,11 @@ struct afs_volume { · 1 unmodified line
605#define AFS_VOLUME_DELETED 3 /* - T if volume appears deleted */573#define AFS_VOLUME_DELETED 3 /* - T if volume appears deleted */
606#define AFS_VOLUME_OFFLINE 4 /* - T if volume offline notice given */574#define AFS_VOLUME_OFFLINE 4 /* - T if volume offline notice given */
607#define AFS_VOLUME_BUSY 5 /* - T if volume busy notice given */575#define AFS_VOLUME_BUSY 5 /* - T if volume busy notice given */
576#define AFS_VOLUME_MAYBE_NO_IBULK 6 /* - T if some servers don't have InlineBulkStatus */
608#ifdef CONFIG_AFS_FSCACHE577#ifdef CONFIG_AFS_FSCACHE
609 struct fscache_cookie *cache; /* caching cookie */578 struct fscache_cookie *cache; /* caching cookie */
610#endif579#endif
611 struct afs_server_list *servers; /* List of servers on which volume resides */580 struct afs_server_list __rcu *servers; /* List of servers on which volume resides */
612 rwlock_t servers_lock; /* Lock for ->servers */581 rwlock_t servers_lock; /* Lock for ->servers */
613 unsigned int servers_seq; /* Incremented each time ->servers changes */582 unsigned int servers_seq; /* Incremented each time ->servers changes */
614 583
@@ -616,7 +585,6 @@ struct afs_volume { · 1 unmodified line
616 rwlock_t cb_v_break_lock;585 rwlock_t cb_v_break_lock;
617 586
618 afs_voltype_t type; /* type of volume */587 afs_voltype_t type; /* type of volume */
619 short error;
620 char type_force; /* force volume type (suppress R/O -> R/W) */588 char type_force; /* force volume type (suppress R/O -> R/W) */
621 u8 name_len;589 u8 name_len;
622 u8 name[AFS_MAXVOLNAME + 1]; /* NUL-padded volume name */590 u8 name[AFS_MAXVOLNAME + 1]; /* NUL-padded volume name */
@@ -677,11 +645,11 @@ struct afs_vnode { · 54 unmodified lines
677 afs_lock_type_t lock_type : 8;645 afs_lock_type_t lock_type : 8;
678 646
679 /* outstanding callback notification on this file */647 /* outstanding callback notification on this file */
680 struct afs_cb_interest __rcu *cb_interest; /* Server on which this resides */648 void *cb_server; /* Server with callback/filelock */
681 unsigned int cb_s_break; /* Mass break counter on ->server */649 unsigned int cb_s_break; /* Mass break counter on ->server */
682 unsigned int cb_v_break; /* Mass break counter on ->volume */650 unsigned int cb_v_break; /* Mass break counter on ->volume */
683 unsigned int cb_break; /* Break counter on vnode */651 unsigned int cb_break; /* Break counter on vnode */
684 seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */652 seqlock_t cb_lock; /* Lock for ->cb_server, ->status, ->cb_*break */
685 653
686 time64_t cb_expires_at; /* time at which callback expires */654 time64_t cb_expires_at; /* time at which callback expires */
687};655};
@@ -758,29 +726,118 @@ struct afs_vl_cursor { · 70 unmodified lines
758};726};
759 727
760/*728/*
761 * Cursor for iterating over a set of fileservers.729 * Fileserver operation methods.
730 */
731struct afs_operation_ops {
732 void (*issue_afs_rpc)(struct afs_operation *op);
733 void (*issue_yfs_rpc)(struct afs_operation *op);
734 void (*success)(struct afs_operation *op);
735 void (*aborted)(struct afs_operation *op);
736 void (*edit_dir)(struct afs_operation *op);
737 void (*put)(struct afs_operation *op);
738};
739
740struct afs_vnode_param {
741 struct afs_vnode *vnode;
742 struct afs_fid fid; /* Fid to access */
743 struct afs_status_cb scb; /* Returned status and callback promise */
744 afs_dataversion_t dv_before; /* Data version before the call */
745 unsigned int cb_break_before; /* cb_break + cb_s_break before the call */
746 u8 dv_delta; /* Expected change in data version */
747 bool put_vnode; /* T if we have a ref on the vnode */
748 bool need_io_lock; /* T if we need the I/O lock on this */
749};
750
751/*
752 * Fileserver operation wrapper, handling server and address rotation
753 * asynchronously. May make simultaneous calls to multiple servers.
762 */754 */
763struct afs_fs_cursor {755struct afs_operation {
756 struct afs_net *net; /* Network namespace */
757 struct key *key; /* Key for the cell */
764 const struct afs_call_type *type; /* Type of call done */758 const struct afs_call_type *type; /* Type of call done */
759 const struct afs_operation_ops *ops;
760
761 /* Parameters/results for the operation */
762 struct afs_volume *volume; /* Volume being accessed */
763 struct afs_vnode_param file[2];
764 struct afs_vnode_param *more_files;
765 struct afs_volsync volsync;
766 struct dentry *dentry; /* Dentry to be altered */
767 struct dentry *dentry_2; /* Second dentry to be altered */
768 struct timespec64 mtime; /* Modification time to record */
769 short nr_files; /* Number of entries in file[], more_files */
770 short error;
771 unsigned int abort_code;
772 unsigned int debug_id;
773
774 unsigned int cb_v_break; /* Volume break counter before op */
775 unsigned int cb_s_break; /* Server break counter before op */
776
777 union {
778 struct {
779 int which; /* Which ->file[] to fetch for */
780 } fetch_status;
781 struct {
782 int reason; /* enum afs_edit_dir_reason */
783 mode_t mode;
784 const char *symlink;
785 } create;
786 struct {
787 bool need_rehash;
788 } unlink;
789 struct {
790 struct dentry *rehash;
791 struct dentry *tmp;
792 bool new_negative;
793 } rename;
794 struct {
795 struct afs_read *req;
796 } fetch;
797 struct {
798 struct afs_vnode *lvnode; /* vnode being locked */
799 afs_lock_type_t type;
800 } lock;
801 struct {
802 struct address_space *mapping; /* Pages being written from */
803 pgoff_t first; /* first page in mapping to deal with */
804 pgoff_t last; /* last page in mapping to deal with */
805 unsigned first_offset; /* offset into mapping[first] */
806 unsigned last_to; /* amount of mapping[last] */
807 } store;
808 struct {
809 struct iattr *attr;
810 } setattr;
811 struct afs_acl *acl;
812 struct yfs_acl *yacl;
813 struct {
814 struct afs_volume_status vs;
815 struct kstatfs *buf;
816 } volstatus;
817 };
818
819 /* Fileserver iteration state */
765 struct afs_addr_cursor ac;820 struct afs_addr_cursor ac;
766 struct afs_vnode *vnode;
767 struct afs_server_list *server_list; /* Current server list (pins ref) */821 struct afs_server_list *server_list; /* Current server list (pins ref) */
768 struct afs_cb_interest *cbi; /* Server on which this resides (pins ref) */822 struct afs_server *server; /* Server we're using (ref pinned by server_list) */
769 struct key *key; /* Key for the server */823 struct afs_call *call;
770 unsigned long untried; /* Bitmask of untried servers */824 unsigned long untried; /* Bitmask of untried servers */
771 unsigned int cb_break; /* cb_break + cb_s_break before the call */
772 unsigned int cb_break_2; /* cb_break + cb_s_break (2nd vnode) */
773 short index; /* Current server */825 short index; /* Current server */
774 short error;
775 unsigned short flags;
776#define AFS_FS_CURSOR_STOP 0x0001 /* Set to cease iteration */
777#define AFS_FS_CURSOR_VBUSY 0x0002 /* Set if seen VBUSY */
778#define AFS_FS_CURSOR_VMOVED 0x0004 /* Set if seen VMOVED */
779#define AFS_FS_CURSOR_VNOVOL 0x0008 /* Set if seen VNOVOL */
780#define AFS_FS_CURSOR_CUR_ONLY 0x0010 /* Set if current server only (file lock held) */
781#define AFS_FS_CURSOR_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */
782#define AFS_FS_CURSOR_INTR 0x0040 /* Set if op is interruptible */
783 unsigned short nr_iterations; /* Number of server iterations */826 unsigned short nr_iterations; /* Number of server iterations */
827
828 unsigned int flags;
829#define AFS_OPERATION_STOP 0x0001 /* Set to cease iteration */
830#define AFS_OPERATION_VBUSY 0x0002 /* Set if seen VBUSY */
831#define AFS_OPERATION_VMOVED 0x0004 /* Set if seen VMOVED */
832#define AFS_OPERATION_VNOVOL 0x0008 /* Set if seen VNOVOL */
833#define AFS_OPERATION_CUR_ONLY 0x0010 /* Set if current server only (file lock held) */
834#define AFS_OPERATION_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */
835#define AFS_OPERATION_UNINTR 0x0040 /* Set if op is uninterruptible */
836#define AFS_OPERATION_DOWNGRADE 0x0080 /* Set to retry with downgraded opcode */
837#define AFS_OPERATION_LOCK_0 0x0100 /* Set if have io_lock on file[0] */
838#define AFS_OPERATION_LOCK_1 0x0200 /* Set if have io_lock on file[1] */
839#define AFS_OPERATION_TRIED_ALL 0x0400 /* Set if we've tried all the fileservers */
840#define AFS_OPERATION_RETRY_SERVER 0x0800 /* Set if we should retry the current server */
784};841};
785 842
786/*843/*
@@ -838,29 +895,15 @@ extern void __afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason); · 51 unmodified lines
838extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);895extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);
839extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break *);896extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break *);
840 897
841extern int afs_register_server_cb_interest(struct afs_vnode *,
842 struct afs_server_list *, unsigned int);
843extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *);
844extern void afs_clear_callback_interests(struct afs_net *, struct afs_server_list *);
845
846static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi)
847{
848 if (cbi)
849 refcount_inc(&cbi->usage);
850 return cbi;
851}
852
853static inline unsigned int afs_calc_vnode_cb_break(struct afs_vnode *vnode)898static inline unsigned int afs_calc_vnode_cb_break(struct afs_vnode *vnode)
854{899{
855 return vnode->cb_break + vnode->cb_v_break;900 return vnode->cb_break + vnode->cb_v_break;
856}901}
857 902
858static inline bool afs_cb_is_broken(unsigned int cb_break,903static inline bool afs_cb_is_broken(unsigned int cb_break,
859 const struct afs_vnode *vnode,904 const struct afs_vnode *vnode)
860 const struct afs_cb_interest *cbi)
861{905{
862 return !cbi || cb_break != (vnode->cb_break +906 return cb_break != (vnode->cb_break + vnode->volume->cb_v_break);
863 vnode->volume->cb_v_break);
864}907}
865 908
866/*909/*
@@ -952,71 +995,81 @@ extern int afs_flock(struct file *, int, struct file_lock *); · 85 unmodified lines
952/*995/*
953 * fsclient.c996 * fsclient.c
954 */997 */
955extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_status_cb *,998extern void afs_fs_fetch_status(struct afs_operation *);
956 struct afs_volsync *);999extern void afs_fs_fetch_data(struct afs_operation *);
957extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *);1000extern void afs_fs_create_file(struct afs_operation *);
958extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_status_cb *, struct afs_read *);1001extern void afs_fs_make_dir(struct afs_operation *);
959extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t,1002extern void afs_fs_remove_file(struct afs_operation *);
960 struct afs_status_cb *, struct afs_fid *, struct afs_status_cb *);1003extern void afs_fs_remove_dir(struct afs_operation *);
961extern int afs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool,1004extern void afs_fs_link(struct afs_operation *);
962 struct afs_status_cb *);1005extern void afs_fs_symlink(struct afs_operation *);
963extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *,1006extern void afs_fs_rename(struct afs_operation *);
964 struct afs_status_cb *, struct afs_status_cb *);1007extern void afs_fs_store_data(struct afs_operation *);
965extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *,1008extern void afs_fs_setattr(struct afs_operation *);
966 struct afs_status_cb *, struct afs_fid *, struct afs_status_cb *);1009extern void afs_fs_get_volume_status(struct afs_operation *);
967extern int afs_fs_rename(struct afs_fs_cursor *, const char *,1010extern void afs_fs_set_lock(struct afs_operation *);
968 struct afs_vnode *, const char *,1011extern void afs_fs_extend_lock(struct afs_operation *);
969 struct afs_status_cb *, struct afs_status_cb *);1012extern void afs_fs_release_lock(struct afs_operation *);
970extern int afs_fs_store_data(struct afs_fs_cursor *, struct address_space *,
971 pgoff_t, pgoff_t, unsigned, unsigned, struct afs_status_cb *);
972extern int afs_fs_setattr(struct afs_fs_cursor *, struct iattr *, struct afs_status_cb *);
973extern int afs_fs_get_volume_status(struct afs_fs_cursor *, struct afs_volume_status *);
974extern int afs_fs_set_lock(struct afs_fs_cursor *, afs_lock_type_t, struct afs_status_cb *);
975extern int afs_fs_extend_lock(struct afs_fs_cursor *, struct afs_status_cb *);
976extern int afs_fs_release_lock(struct afs_fs_cursor *, struct afs_status_cb *);
977extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *,1013extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *,
978 struct afs_addr_cursor *, struct key *);1014 struct afs_addr_cursor *, struct key *);
979extern struct afs_call *afs_fs_get_capabilities(struct afs_net *, struct afs_server *,1015extern bool afs_fs_get_capabilities(struct afs_net *, struct afs_server *,
980 struct afs_addr_cursor *, struct key *,1016 struct afs_addr_cursor *, struct key *);
981 unsigned int);1017extern void afs_fs_inline_bulk_status(struct afs_operation *);
982extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *,
983 struct afs_fid *, struct afs_status_cb *,
984 unsigned int, struct afs_volsync *);
985extern int afs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *,
986 struct afs_fid *, struct afs_status_cb *,
987 struct afs_volsync *);
988 1018
989struct afs_acl {1019struct afs_acl {
990 u32 size;1020 u32 size;
991 u8 data[];1021 u8 data[];
992};1022};
993 1023
994extern struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *, struct afs_status_cb *);1024extern void afs_fs_fetch_acl(struct afs_operation *);
995extern int afs_fs_store_acl(struct afs_fs_cursor *, const struct afs_acl *,1025extern void afs_fs_store_acl(struct afs_operation *);
996 struct afs_status_cb *);1026
1027/*
1028 * fs_operation.c
1029 */
1030extern struct afs_operation *afs_alloc_operation(struct key *, struct afs_volume *);
1031extern int afs_put_operation(struct afs_operation *);
1032extern bool afs_begin_vnode_operation(struct afs_operation *);
1033extern void afs_wait_for_operation(struct afs_operation *);
1034extern int afs_do_sync_operation(struct afs_operation *);
1035
1036static inline void afs_op_nomem(struct afs_operation *op)
1037{
1038 op->error = -ENOMEM;
1039}
1040
1041static inline void afs_op_set_vnode(struct afs_operation *op, unsigned int n,
1042 struct afs_vnode *vnode)
1043{
1044 op->file[n].vnode = vnode;
1045 op->file[n].need_io_lock = true;
1046}
1047
1048static inline void afs_op_set_fid(struct afs_operation *op, unsigned int n,
1049 const struct afs_fid *fid)
1050{
1051 op->file[n].fid = *fid;
1052}
997 1053
998/*1054/*
999 * fs_probe.c1055 * fs_probe.c
1000 */1056 */
1001extern void afs_fileserver_probe_result(struct afs_call *);1057extern void afs_fileserver_probe_result(struct afs_call *);
1002extern int afs_probe_fileservers(struct afs_net *, struct key *, struct afs_server_list *);1058extern void afs_fs_probe_fileserver(struct afs_net *, struct afs_server *, struct key *, bool);
1003extern int afs_wait_for_fs_probes(struct afs_server_list *, unsigned long);1059extern int afs_wait_for_fs_probes(struct afs_server_list *, unsigned long);
1060extern void afs_probe_fileserver(struct afs_net *, struct afs_server *);
1061extern void afs_fs_probe_dispatcher(struct work_struct *);
1062extern int afs_wait_for_one_fs_probe(struct afs_server *, bool);
1004 1063
1005/*1064/*
1006 * inode.c1065 * inode.c
1007 */1066 */
1008extern void afs_vnode_commit_status(struct afs_fs_cursor *,1067extern void afs_vnode_commit_status(struct afs_operation *, struct afs_vnode_param *);
1009 struct afs_vnode *,
1010 unsigned int,
1011 const afs_dataversion_t *,
1012 struct afs_status_cb *);
1013extern int afs_fetch_status(struct afs_vnode *, struct key *, bool, afs_access_t *);1068extern int afs_fetch_status(struct afs_vnode *, struct key *, bool, afs_access_t *);
1014extern int afs_iget5_test(struct inode *, void *);1069extern int afs_ilookup5_test_by_fid(struct inode *, void *);
1015extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool);1070extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool);
1016extern struct inode *afs_iget(struct super_block *, struct key *,1071extern struct inode *afs_iget(struct afs_operation *, struct afs_vnode_param *);
1017 struct afs_iget_data *, struct afs_status_cb *,1072extern struct inode *afs_root_iget(struct super_block *, struct key *);
1018 struct afs_cb_interest *,
1019 struct afs_vnode *);
1020extern void afs_zap_data(struct afs_vnode *);1073extern void afs_zap_data(struct afs_vnode *);
1021extern bool afs_check_validity(struct afs_vnode *);1074extern bool afs_check_validity(struct afs_vnode *);
1022extern int afs_validate(struct afs_vnode *, struct key *);1075extern int afs_validate(struct afs_vnode *, struct key *);
@@ -1104,11 +1157,8 @@ static inline void afs_put_sysnames(struct afs_sysnames *sysnames) {} · 81 unmodified lines
1104/*1157/*
1105 * rotate.c1158 * rotate.c
1106 */1159 */
1107extern bool afs_begin_vnode_operation(struct afs_fs_cursor *, struct afs_vnode *,1160extern bool afs_select_fileserver(struct afs_operation *);
1108 struct key *, bool);1161extern void afs_dump_edestaddrreq(const struct afs_operation *);
1109extern bool afs_select_fileserver(struct afs_fs_cursor *);
1110extern bool afs_select_current_fileserver(struct afs_fs_cursor *);
1111extern int afs_end_vnode_operation(struct afs_fs_cursor *);
1112 1162
1113/*1163/*
1114 * rxrpc.c1164 * rxrpc.c
@@ -1128,12 +1178,17 @@ extern void afs_flat_call_destructor(struct afs_call *); · 13 unmodified lines
1128extern void afs_send_empty_reply(struct afs_call *);1178extern void afs_send_empty_reply(struct afs_call *);
1129extern void afs_send_simple_reply(struct afs_call *, const void *, size_t);1179extern void afs_send_simple_reply(struct afs_call *, const void *, size_t);
1130extern int afs_extract_data(struct afs_call *, bool);1180extern int afs_extract_data(struct afs_call *, bool);
1131extern int afs_protocol_error(struct afs_call *, int, enum afs_eproto_cause);1181extern int afs_protocol_error(struct afs_call *, enum afs_eproto_cause);
1132 1182
1133static inline void afs_set_fc_call(struct afs_call *call, struct afs_fs_cursor *fc)1183static inline void afs_make_op_call(struct afs_operation *op, struct afs_call *call,
1184 gfp_t gfp)
1134{1185{
1135 call->intr = fc->flags & AFS_FS_CURSOR_INTR;1186 op->call = call;
1136 fc->type = call->type;1187 op->type = call->type;
1188 call->op = op;
1189 call->key = op->key;
1190 call->intr = !(op->flags & AFS_OPERATION_UNINTR);
1191 afs_make_call(&op->ac, call, gfp);
1137}1192}
1138 1193
1139static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t size)1194static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t size)
@@ -1241,13 +1296,33 @@ extern spinlock_t afs_server_peer_lock; · 101 unmodified lines
1241extern struct afs_server *afs_find_server(struct afs_net *,1296extern struct afs_server *afs_find_server(struct afs_net *,
1242 const struct sockaddr_rxrpc *);1297 const struct sockaddr_rxrpc *);
1243extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);1298extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);
1244extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *);1299extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *, u32);
1245extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace);1300extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace);
1301extern struct afs_server *afs_use_server(struct afs_server *, enum afs_server_trace);
1302extern void afs_unuse_server(struct afs_net *, struct afs_server *, enum afs_server_trace);
1303extern void afs_unuse_server_notime(struct afs_net *, struct afs_server *, enum afs_server_trace);
1246extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace);1304extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace);
1247extern void afs_manage_servers(struct work_struct *);1305extern void afs_manage_servers(struct work_struct *);
1248extern void afs_servers_timer(struct timer_list *);1306extern void afs_servers_timer(struct timer_list *);
1307extern void afs_fs_probe_timer(struct timer_list *);
1249extern void __net_exit afs_purge_servers(struct afs_net *);1308extern void __net_exit afs_purge_servers(struct afs_net *);
1250extern bool afs_check_server_record(struct afs_fs_cursor *, struct afs_server *);1309extern bool afs_check_server_record(struct afs_operation *, struct afs_server *);
1310
1311static inline void afs_inc_servers_outstanding(struct afs_net *net)
1312{
1313 atomic_inc(&net->servers_outstanding);
1314}
1315
1316static inline void afs_dec_servers_outstanding(struct afs_net *net)
1317{
1318 if (atomic_dec_and_test(&net->servers_outstanding))
1319 wake_up_var(&net->servers_outstanding);
1320}
1321
1322static inline bool afs_is_probing_server(struct afs_server *server)
1323{
1324 return list_empty(&server->probe_link);
1325}
1251 1326
1252/*1327/*
1253 * server_list.c1328 * server_list.c
@@ -1279,6 +1354,12 @@ extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *, const uu · 25 unmodified lines
1279extern struct afs_call *afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *,1354extern struct afs_call *afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *,
1280 struct key *, struct afs_vlserver *, unsigned int);1355 struct key *, struct afs_vlserver *, unsigned int);
1281extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *);1356extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *);
1357extern char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *);
1358
1359/*
1360 * vl_alias.c
1361 */
1362extern int afs_cell_detect_alias(struct afs_cell *, struct key *);
1282 1363
1283/*1364/*
1284 * vl_probe.c1365 * vl_probe.c
@@ -1322,18 +1403,12 @@ extern struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *, · 37 unmodified lines
1322/*1403/*
1323 * volume.c1404 * volume.c
1324 */1405 */
1325static inline struct afs_volume *__afs_get_volume(struct afs_volume *volume)
1326{
1327 if (volume)
1328 atomic_inc(&volume->usage);
1329 return volume;
1330}
1331
1332extern struct afs_volume *afs_create_volume(struct afs_fs_context *);1406extern struct afs_volume *afs_create_volume(struct afs_fs_context *);
1333extern void afs_activate_volume(struct afs_volume *);1407extern void afs_activate_volume(struct afs_volume *);
1334extern void afs_deactivate_volume(struct afs_volume *);1408extern void afs_deactivate_volume(struct afs_volume *);
1335extern void afs_put_volume(struct afs_cell *, struct afs_volume *);1409extern struct afs_volume *afs_get_volume(struct afs_volume *, enum afs_volume_trace);
1336extern int afs_check_volume_status(struct afs_volume *, struct afs_fs_cursor *);1410extern void afs_put_volume(struct afs_net *, struct afs_volume *, enum afs_volume_trace);
1411extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *);
1337 1412
1338/*1413/*
1339 * write.c1414 * write.c
@@ -1362,36 +1437,24 @@ extern ssize_t afs_listxattr(struct dentry *, char *, size_t); · 22 unmodified lines
1362/*1437/*
1363 * yfsclient.c1438 * yfsclient.c
1364 */1439 */
1365extern int yfs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_status_cb *,1440extern void yfs_fs_fetch_file_status(struct afs_operation *);
1366 struct afs_volsync *);1441extern void yfs_fs_fetch_data(struct afs_operation *);
1367extern int yfs_fs_fetch_data(struct afs_fs_cursor *, struct afs_status_cb *, struct afs_read *);1442extern void yfs_fs_create_file(struct afs_operation *);
1368extern int yfs_fs_create_file(struct afs_fs_cursor *, const char *, umode_t, struct afs_status_cb *,1443extern void yfs_fs_make_dir(struct afs_operation *);
1369 struct afs_fid *, struct afs_status_cb *);1444extern void yfs_fs_remove_file2(struct afs_operation *);
1370extern int yfs_fs_make_dir(struct afs_fs_cursor *, const char *, umode_t, struct afs_status_cb *,1445extern void yfs_fs_remove_file(struct afs_operation *);
1371 struct afs_fid *, struct afs_status_cb *);1446extern void yfs_fs_remove_dir(struct afs_operation *);
1372extern int yfs_fs_remove_file2(struct afs_fs_cursor *, struct afs_vnode *, const char *,1447extern void yfs_fs_link(struct afs_operation *);
1373 struct afs_status_cb *, struct afs_status_cb *);1448extern void yfs_fs_symlink(struct afs_operation *);
1374extern int yfs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool,1449extern void yfs_fs_rename(struct afs_operation *);
1375 struct afs_status_cb *);1450extern void yfs_fs_store_data(struct afs_operation *);
1376extern int yfs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *,1451extern void yfs_fs_setattr(struct afs_operation *);
1377 struct afs_status_cb *, struct afs_status_cb *);1452extern void yfs_fs_get_volume_status(struct afs_operation *);
1378extern int yfs_fs_symlink(struct afs_fs_cursor *, const char *, const char *,1453extern void yfs_fs_set_lock(struct afs_operation *);
1379 struct afs_status_cb *, struct afs_fid *, struct afs_status_cb *);1454extern void yfs_fs_extend_lock(struct afs_operation *);
1380extern int yfs_fs_rename(struct afs_fs_cursor *, const char *, struct afs_vnode *, const char *,1455extern void yfs_fs_release_lock(struct afs_operation *);
1381 struct afs_status_cb *, struct afs_status_cb *);1456extern void yfs_fs_fetch_status(struct afs_operation *);
1382extern int yfs_fs_store_data(struct afs_fs_cursor *, struct address_space *,1457extern void yfs_fs_inline_bulk_status(struct afs_operation *);
1383 pgoff_t, pgoff_t, unsigned, unsigned, struct afs_status_cb *);
1384extern int yfs_fs_setattr(struct afs_fs_cursor *, struct iattr *, struct afs_status_cb *);
1385extern int yfs_fs_get_volume_status(struct afs_fs_cursor *, struct afs_volume_status *);
1386extern int yfs_fs_set_lock(struct afs_fs_cursor *, afs_lock_type_t, struct afs_status_cb *);
1387extern int yfs_fs_extend_lock(struct afs_fs_cursor *, struct afs_status_cb *);
1388extern int yfs_fs_release_lock(struct afs_fs_cursor *, struct afs_status_cb *);
1389extern int yfs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *,
1390 struct afs_fid *, struct afs_status_cb *,
1391 struct afs_volsync *);
1392extern int yfs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *,
1393 struct afs_fid *, struct afs_status_cb *,
1394 unsigned int, struct afs_volsync *);
1395 1458
1396struct yfs_acl {1459struct yfs_acl {
1397 struct afs_acl *acl; /* Dir/file/symlink ACL */1460 struct afs_acl *acl; /* Dir/file/symlink ACL */
@@ -1404,10 +1467,8 @@ struct yfs_acl { · 6 unmodified lines
1404};1467};
1405 1468
1406extern void yfs_free_opaque_acl(struct yfs_acl *);1469extern void yfs_free_opaque_acl(struct yfs_acl *);
1407extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, struct yfs_acl *,1470extern void yfs_fs_fetch_opaque_acl(struct afs_operation *);
1408 struct afs_status_cb *);1471extern void yfs_fs_store_opaque_acl2(struct afs_operation *);
1409extern int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *, const struct afs_acl *,
1410 struct afs_status_cb *);
1411 1472
1412/*1473/*
1413 * Miscellaneous inline functions.1474 * Miscellaneous inline functions.
@@ -1422,15 +1483,29 @@ static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode) · 8 unmodified lines
1422 return &vnode->vfs_inode;1483 return &vnode->vfs_inode;
1423}1484}
1424 1485
1425static inline void afs_check_for_remote_deletion(struct afs_fs_cursor *fc,1486static inline void afs_check_for_remote_deletion(struct afs_operation *op,
1426 struct afs_vnode *vnode)1487 struct afs_vnode *vnode)
1427{1488{
1428 if (fc->ac.error == -ENOENT) {1489 if (op->error == -ENOENT) {
1429 set_bit(AFS_VNODE_DELETED, &vnode->flags);1490 set_bit(AFS_VNODE_DELETED, &vnode->flags);
1430 afs_break_callback(vnode, afs_cb_break_for_deleted);1491 afs_break_callback(vnode, afs_cb_break_for_deleted);
1431 }1492 }
1432}1493}
1433 1494
1495/*
1496 * Note that a dentry got changed. We need to set d_fsdata to the data version
1497 * number derived from the result of the operation. It doesn't matter if
1498 * d_fsdata goes backwards as we'll just revalidate.
1499 */
1500static inline void afs_update_dentry_version(struct afs_operation *op,
1501 struct afs_vnode_param *dir_vp,
1502 struct dentry *dentry)
1503{
1504 if (!op->error)
1505 dentry->d_fsdata =
1506 (void *)(unsigned long)dir_vp->scb.status.data_version;
1507}
1508
1434static inline int afs_io_error(struct afs_call *call, enum afs_io_error where)1509static inline int afs_io_error(struct afs_call *call, enum afs_io_error where)
1435{1510{
1436 trace_afs_io_error(call->debug_id, -EIO, where);1511 trace_afs_io_error(call->debug_id, -EIO, where);
fs/afs/main.c+5−1
@@ -82,12 +82,14 @@ static int __net_init afs_net_init(struct net *net_ns) · 81 unmodified lines
82 INIT_WORK(&net->cells_manager, afs_manage_cells);82 INIT_WORK(&net->cells_manager, afs_manage_cells);
83 timer_setup(&net->cells_timer, afs_cells_timer, 0);83 timer_setup(&net->cells_timer, afs_cells_timer, 0);
84 84
85 mutex_init(&net->cells_alias_lock);
85 mutex_init(&net->proc_cells_lock);86 mutex_init(&net->proc_cells_lock);
86 INIT_HLIST_HEAD(&net->proc_cells);87 INIT_HLIST_HEAD(&net->proc_cells);
87 88
88 seqlock_init(&net->fs_lock);89 seqlock_init(&net->fs_lock);
89 net->fs_servers = RB_ROOT;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 INIT_HLIST_HEAD(&net->fs_proc);93 INIT_HLIST_HEAD(&net->fs_proc);
92 94
93 INIT_HLIST_HEAD(&net->fs_addresses4);95 INIT_HLIST_HEAD(&net->fs_addresses4);
@@ -96,6 +98,8 @@ static int __net_init afs_net_init(struct net *net_ns) · 2 unmodified lines
96 98
97 INIT_WORK(&net->fs_manager, afs_manage_servers);99 INIT_WORK(&net->fs_manager, afs_manage_servers);
98 timer_setup(&net->fs_timer, afs_servers_timer, 0);100 timer_setup(&net->fs_timer, afs_servers_timer, 0);
101 INIT_WORK(&net->fs_prober, afs_fs_probe_dispatcher);
102 timer_setup(&net->fs_probe_timer, afs_fs_probe_timer, 0);
99 103
100 ret = -ENOMEM;104 ret = -ENOMEM;
101 sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);105 sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);
fs/afs/proc.c+23−19
@@ -38,7 +38,7 @@ static int afs_proc_cells_show(struct seq_file *m, void *v) · 37 unmodified lines
38 38
39 if (v == SEQ_START_TOKEN) {39 if (v == SEQ_START_TOKEN) {
40 /* display header on line 1 */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 return 0;42 return 0;
43 }43 }
44 44
@@ -46,10 +46,11 @@ static int afs_proc_cells_show(struct seq_file *m, void *v) · 1 unmodified line
46 vllist = rcu_dereference(cell->vl_servers);46 vllist = rcu_dereference(cell->vl_servers);
47 47
48 /* display one cell per line on subsequent lines */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 atomic_read(&cell->usage),50 atomic_read(&cell->usage),
51 cell->dns_expiry - ktime_get_real_seconds(),51 cell->dns_expiry - ktime_get_real_seconds(),
52 vllist->nr_servers,52 vllist->nr_servers,
53 cell->state,
53 cell->name);54 cell->name);
54 return 0;55 return 0;
55}56}
@@ -208,11 +209,10 @@ static const char afs_vol_types[3][3] = { · 152 unmodified lines
208 */209 */
209static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)210static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)
210{211{
211 struct afs_cell *cell = PDE_DATA(file_inode(m->file));212 struct afs_volume *vol = hlist_entry(v, struct afs_volume, proc_link);
212 struct afs_volume *vol = list_entry(v, struct afs_volume, proc_link);
213 213
214 /* Display header on line 1 */214 /* Display header on line 1 */
215 if (v == &cell->proc_volumes) {215 if (v == SEQ_START_TOKEN) {
216 seq_puts(m, "USE VID TY NAME\n");216 seq_puts(m, "USE VID TY NAME\n");
217 return 0;217 return 0;
218 }218 }
@@ -230,8 +230,8 @@ static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) · 11 unmodified lines
230{230{
231 struct afs_cell *cell = PDE_DATA(file_inode(m->file));231 struct afs_cell *cell = PDE_DATA(file_inode(m->file));
232 232
233 read_lock(&cell->proc_lock);233 rcu_read_lock();
234 return seq_list_start_head(&cell->proc_volumes, *_pos);234 return seq_hlist_start_head_rcu(&cell->proc_volumes, *_pos);
235}235}
236 236
237static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v,237static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v,
@@ -239,15 +239,13 @@ static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v, · 1 unmodified line
239{239{
240 struct afs_cell *cell = PDE_DATA(file_inode(m->file));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
245static void afs_proc_cell_volumes_stop(struct seq_file *m, void *v)245static void afs_proc_cell_volumes_stop(struct seq_file *m, void *v)
246 __releases(cell->proc_lock)246 __releases(cell->proc_lock)
247{247{
248 struct afs_cell *cell = PDE_DATA(file_inode(m->file));248 rcu_read_unlock();
249
250 read_unlock(&cell->proc_lock);
251}249}
252 250
253static const struct seq_operations afs_proc_cell_volumes_ops = {251static const struct seq_operations afs_proc_cell_volumes_ops = {
@@ -378,20 +376,26 @@ static int afs_proc_servers_show(struct seq_file *m, void *v) · 124 unmodified lines
378 int i;376 int i;
379 377
380 if (v == SEQ_START_TOKEN) {378 if (v == SEQ_START_TOKEN) {
381 seq_puts(m, "UUID USE ADDR\n");379 seq_puts(m, "UUID REF ACT\n");
382 return 0;380 return 0;
383 }381 }
384 382
385 server = list_entry(v, struct afs_server, proc_link);383 server = list_entry(v, struct afs_server, proc_link);
386 alist = rcu_dereference(server->addresses);384 alist = rcu_dereference(server->addresses);
387 seq_printf(m, "%pU %3d %pISpc%s\n",385 seq_printf(m, "%pU %3d %3d\n",
388 &server->uuid,386 &server->uuid,
389 atomic_read(&server->usage),387 atomic_read(&server->ref),
390 &alist->addrs[0].transport,388 atomic_read(&server->active));
391 alist->preferred == 0 ? "*" : "");389 seq_printf(m, " - info: fl=%lx rtt=%u brk=%x\n",
392 for (i = 1; i < alist->nr_addrs; i++)390 server->flags, server->rtt, server->cb_s_break);
393 seq_printf(m, " %pISpc%s\n",391 seq_printf(m, " - probe: last=%d out=%d\n",
394 &alist->addrs[i].transport,392 (int)(jiffies - server->probed_at) / HZ,
393 atomic_read(&server->probe_outstanding));
394 seq_printf(m, " - ALIST v=%u rsp=%lx f=%lx\n",
395 alist->version, alist->responded, alist->failed);
396 for (i = 0; i < alist->nr_addrs; i++)
397 seq_printf(m, " [%x] %pISpc%s\n",
398 i, &alist->addrs[i].transport,
395 alist->preferred == i ? "*" : "");399 alist->preferred == i ? "*" : "");
396 return 0;400 return 0;
397}401}
fs/afs/protocol_yfs.h+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
8#define YFS_FS_SERVICE 25008#define YFS_FS_SERVICE 2500
9#define YFS_CM_SERVICE 25019#define YFS_CM_SERVICE 2501
10 10
11#define YFSCBMAX 102411#define YFSCBMAX 1024
12 12
13enum YFS_CM_Operations {13enum YFS_CM_Operations {
14 YFSCBProbe = 206, /* probe client */14 YFSCBProbe = 206, /* probe client */
fs/afs/rotate.c+162−285
@@ -14,61 +14,33 @@ · 13 unmodified lines
14#include "internal.h"14#include "internal.h"
15#include "afs_fs.h"15#include "afs_fs.h"
16 16
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 */
23bool 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/*17/*
49 * Begin iteration through a server list, starting with the vnode's last used18 * Begin iteration through a server list, starting with the vnode's last used
50 * server if possible, or the last recorded good server if not.19 * server if possible, or the last recorded good server if not.
51 */20 */
52static bool afs_start_fs_iteration(struct afs_fs_cursor *fc,21static bool afs_start_fs_iteration(struct afs_operation *op,
53 struct afs_vnode *vnode)22 struct afs_vnode *vnode)
54{23{
55 struct afs_cb_interest *cbi;24 struct afs_server *server;
25 void *cb_server;
56 int i;26 int i;
57 27
58 read_lock(&vnode->volume->servers_lock);28 read_lock(&op->volume->servers_lock);
59 fc->server_list = afs_get_serverlist(vnode->volume->servers);29 op->server_list = afs_get_serverlist(
60 read_unlock(&vnode->volume->servers_lock);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;34 op->untried = (1UL << op->server_list->nr_servers) - 1;
63 fc->index = READ_ONCE(fc->server_list->preferred);35 op->index = READ_ONCE(op->server_list->preferred);
64 36
65 cbi = rcu_dereference_protected(vnode->cb_interest,37 cb_server = vnode->cb_server;
66 lockdep_is_held(&vnode->io_lock));38 if (cb_server) {
67 if (cbi) {
68 /* See if the vnode's preferred record is still available */39 /* See if the vnode's preferred record is still available */
69 for (i = 0; i < fc->server_list->nr_servers; i++) {40 for (i = 0; i < op->server_list->nr_servers; i++) {
70 if (fc->server_list->servers[i].cb_interest == cbi) {41 server = op->server_list->servers[i].server;
71 fc->index = i;42 if (server == cb_server) {
43 op->index = i;
72 goto found_interest;44 goto found_interest;
73 }45 }
74 }46 }
@@ -77,21 +49,18 @@ static bool afs_start_fs_iteration(struct afs_fs_cursor *fc, · 2 unmodified lines
77 * serving this vnode, then we can't switch to another server49 * serving this vnode, then we can't switch to another server
78 * and have to return an error.50 * and have to return an error.
79 */51 */
80 if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {52 if (op->flags & AFS_OPERATION_CUR_ONLY) {
81 fc->error = -ESTALE;53 op->error = -ESTALE;
82 return false;54 return false;
83 }55 }
84 56
85 /* Note that the callback promise is effectively broken */57 /* Note that the callback promise is effectively broken */
86 write_seqlock(&vnode->cb_lock);58 write_seqlock(&vnode->cb_lock);
87 ASSERTCMP(cbi, ==, rcu_access_pointer(vnode->cb_interest));59 ASSERTCMP(cb_server, ==, vnode->cb_server);
88 rcu_assign_pointer(vnode->cb_interest, NULL);60 vnode->cb_server = NULL;
89 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))61 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))
90 vnode->cb_break++;62 vnode->cb_break++;
91 write_sequnlock(&vnode->cb_lock);63 write_sequnlock(&vnode->cb_lock);
92
93 afs_put_cb_interest(afs_v2net(vnode), cbi);
94 cbi = NULL;
95 }64 }
96 65
97found_interest:66found_interest:
@@ -118,12 +87,12 @@ static void afs_busy(struct afs_volume *volume, u32 abort_code) · 20 unmodified lines
118/*87/*
119 * Sleep and retry the operation to the same fileserver.88 * Sleep and retry the operation to the same fileserver.
120 */89 */
121static bool afs_sleep_and_retry(struct afs_fs_cursor *fc)90static bool afs_sleep_and_retry(struct afs_operation *op)
122{91{
123 if (fc->flags & AFS_FS_CURSOR_INTR) {92 if (!(op->flags & AFS_OPERATION_UNINTR)) {
124 msleep_interruptible(1000);93 msleep_interruptible(1000);
125 if (signal_pending(current)) {94 if (signal_pending(current)) {
126 fc->error = -ERESTARTSYS;95 op->error = -ERESTARTSYS;
127 return false;96 return false;
128 }97 }
129 } else {98 } else {
@@ -137,26 +106,26 @@ static bool afs_sleep_and_retry(struct afs_fs_cursor *fc) · 7 unmodified lines
137 * Select the fileserver to use. May be called multiple times to rotate106 * Select the fileserver to use. May be called multiple times to rotate
138 * through the fileservers.107 * through the fileservers.
139 */108 */
140bool afs_select_fileserver(struct afs_fs_cursor *fc)109bool afs_select_fileserver(struct afs_operation *op)
141{110{
142 struct afs_addr_list *alist;111 struct afs_addr_list *alist;
143 struct afs_server *server;112 struct afs_server *server;
144 struct afs_vnode *vnode = fc->vnode;113 struct afs_vnode *vnode = op->file[0].vnode;
145 struct afs_error e;114 struct afs_error e;
146 u32 rtt;115 u32 rtt;
147 int error = fc->ac.error, i;116 int error = op->ac.error, i;
148 117
149 _enter("%lx[%d],%lx[%d],%d,%d",118 _enter("%lx[%d],%lx[%d],%d,%d",
150 fc->untried, fc->index,119 op->untried, op->index,
151 fc->ac.tried, fc->ac.index,120 op->ac.tried, op->ac.index,
152 error, fc->ac.abort_code);121 error, op->ac.abort_code);
153 122
154 if (fc->flags & AFS_FS_CURSOR_STOP) {123 if (op->flags & AFS_OPERATION_STOP) {
155 _leave(" = f [stopped]");124 _leave(" = f [stopped]");
156 return false;125 return false;
157 }126 }
158 127
159 fc->nr_iterations++;128 op->nr_iterations++;
160 129
161 /* Evaluate the result of the previous operation, if there was one. */130 /* Evaluate the result of the previous operation, if there was one. */
162 switch (error) {131 switch (error) {
@@ -166,8 +135,8 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 3 unmodified lines
166 case 0:135 case 0:
167 default:136 default:
168 /* Success or local failure. Stop. */137 /* Success or local failure. Stop. */
169 fc->error = error;138 op->error = error;
170 fc->flags |= AFS_FS_CURSOR_STOP;139 op->flags |= AFS_OPERATION_STOP;
171 _leave(" = f [okay/local %d]", error);140 _leave(" = f [okay/local %d]", error);
172 return false;141 return false;
173 142
@@ -175,42 +144,42 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 1 unmodified line
175 /* The far side rejected the operation on some grounds. This144 /* The far side rejected the operation on some grounds. This
176 * might involve the server being busy or the volume having been moved.145 * might involve the server being busy or the volume having been moved.
177 */146 */
178 switch (fc->ac.abort_code) {147 switch (op->ac.abort_code) {
179 case VNOVOL:148 case VNOVOL:
180 /* This fileserver doesn't know about the volume.149 /* This fileserver doesn't know about the volume.
181 * - May indicate that the VL is wrong - retry once and compare150 * - May indicate that the VL is wrong - retry once and compare
182 * the results.151 * the results.
183 * - May indicate that the fileserver couldn't attach to the vol.152 * - May indicate that the fileserver couldn't attach to the vol.
184 */153 */
185 if (fc->flags & AFS_FS_CURSOR_VNOVOL) {154 if (op->flags & AFS_OPERATION_VNOVOL) {
186 fc->error = -EREMOTEIO;155 op->error = -EREMOTEIO;
187 goto next_server;156 goto next_server;
188 }157 }
189 158
190 write_lock(&vnode->volume->servers_lock);159 write_lock(&op->volume->servers_lock);
191 fc->server_list->vnovol_mask |= 1 << fc->index;160 op->server_list->vnovol_mask |= 1 << op->index;
192 write_unlock(&vnode->volume->servers_lock);161 write_unlock(&op->volume->servers_lock);
193 162
194 set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);163 set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags);
195 error = afs_check_volume_status(vnode->volume, fc);164 error = afs_check_volume_status(op->volume, op);
196 if (error < 0)165 if (error < 0)
197 goto failed_set_error;166 goto failed_set_error;
198 167
199 if (test_bit(AFS_VOLUME_DELETED, &vnode->volume->flags)) {168 if (test_bit(AFS_VOLUME_DELETED, &op->volume->flags)) {
200 fc->error = -ENOMEDIUM;169 op->error = -ENOMEDIUM;
201 goto failed;170 goto failed;
202 }171 }
203 172
204 /* If the server list didn't change, then assume that173 /* If the server list didn't change, then assume that
205 * it's the fileserver having trouble.174 * it's the fileserver having trouble.
206 */175 */
207 if (vnode->volume->servers == fc->server_list) {176 if (rcu_access_pointer(op->volume->servers) == op->server_list) {
208 fc->error = -EREMOTEIO;177 op->error = -EREMOTEIO;
209 goto next_server;178 goto next_server;
210 }179 }
211 180
212 /* Try again */181 /* Try again */
213 fc->flags |= AFS_FS_CURSOR_VNOVOL;182 op->flags |= AFS_OPERATION_VNOVOL;
214 _leave(" = t [vnovol]");183 _leave(" = t [vnovol]");
215 return true;184 return true;
216 185
@@ -220,20 +189,20 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 3 unmodified lines
220 case VONLINE:189 case VONLINE:
221 case VDISKFULL:190 case VDISKFULL:
222 case VOVERQUOTA:191 case VOVERQUOTA:
223 fc->error = afs_abort_to_error(fc->ac.abort_code);192 op->error = afs_abort_to_error(op->ac.abort_code);
224 goto next_server;193 goto next_server;
225 194
226 case VOFFLINE:195 case VOFFLINE:
227 if (!test_and_set_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags)) {196 if (!test_and_set_bit(AFS_VOLUME_OFFLINE, &op->volume->flags)) {
228 afs_busy(vnode->volume, fc->ac.abort_code);197 afs_busy(op->volume, op->ac.abort_code);
229 clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);198 clear_bit(AFS_VOLUME_BUSY, &op->volume->flags);
230 }199 }
231 if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {200 if (op->flags & AFS_OPERATION_NO_VSLEEP) {
232 fc->error = -EADV;201 op->error = -EADV;
233 goto failed;202 goto failed;
234 }203 }
235 if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {204 if (op->flags & AFS_OPERATION_CUR_ONLY) {
236 fc->error = -ESTALE;205 op->error = -ESTALE;
237 goto failed;206 goto failed;
238 }207 }
239 goto busy;208 goto busy;
@@ -244,17 +213,17 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 4 unmodified lines
244 /* Retry after going round all the servers unless we213 /* Retry after going round all the servers unless we
245 * have a file lock we need to maintain.214 * have a file lock we need to maintain.
246 */215 */
247 if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {216 if (op->flags & AFS_OPERATION_NO_VSLEEP) {
248 fc->error = -EBUSY;217 op->error = -EBUSY;
249 goto failed;218 goto failed;
250 }219 }
251 if (!test_and_set_bit(AFS_VOLUME_BUSY, &vnode->volume->flags)) {220 if (!test_and_set_bit(AFS_VOLUME_BUSY, &op->volume->flags)) {
252 afs_busy(vnode->volume, fc->ac.abort_code);221 afs_busy(op->volume, op->ac.abort_code);
253 clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags);222 clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags);
254 }223 }
255 busy:224 busy:
256 if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {225 if (op->flags & AFS_OPERATION_CUR_ONLY) {
257 if (!afs_sleep_and_retry(fc))226 if (!afs_sleep_and_retry(op))
258 goto failed;227 goto failed;
259 228
260 /* Retry with same server & address */229 /* Retry with same server & address */
@@ -262,7 +231,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 1 unmodified line
262 return true;231 return true;
263 }232 }
264 233
265 fc->flags |= AFS_FS_CURSOR_VBUSY;234 op->flags |= AFS_OPERATION_VBUSY;
266 goto next_server;235 goto next_server;
267 236
268 case VMOVED:237 case VMOVED:
@@ -273,15 +242,15 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 4 unmodified lines
273 * We also limit the number of VMOVED hops we will242 * We also limit the number of VMOVED hops we will
274 * honour, just in case someone sets up a loop.243 * honour, just in case someone sets up a loop.
275 */244 */
276 if (fc->flags & AFS_FS_CURSOR_VMOVED) {245 if (op->flags & AFS_OPERATION_VMOVED) {
277 fc->error = -EREMOTEIO;246 op->error = -EREMOTEIO;
278 goto failed;247 goto failed;
279 }248 }
280 fc->flags |= AFS_FS_CURSOR_VMOVED;249 op->flags |= AFS_OPERATION_VMOVED;
281 250
282 set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags);251 set_bit(AFS_VOLUME_WAIT, &op->volume->flags);
283 set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);252 set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags);
284 error = afs_check_volume_status(vnode->volume, fc);253 error = afs_check_volume_status(op->volume, op);
285 if (error < 0)254 if (error < 0)
286 goto failed_set_error;255 goto failed_set_error;
287 256
@@ -294,23 +263,23 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 6 unmodified lines
294 *263 *
295 * TODO: Retry a few times with sleeps.264 * TODO: Retry a few times with sleeps.
296 */265 */
297 if (vnode->volume->servers == fc->server_list) {266 if (rcu_access_pointer(op->volume->servers) == op->server_list) {
298 fc->error = -ENOMEDIUM;267 op->error = -ENOMEDIUM;
299 goto failed;268 goto failed;
300 }269 }
301 270
302 goto restart_from_beginning;271 goto restart_from_beginning;
303 272
304 default:273 default:
305 clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags);274 clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags);
306 clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);275 clear_bit(AFS_VOLUME_BUSY, &op->volume->flags);
307 fc->error = afs_abort_to_error(fc->ac.abort_code);276 op->error = afs_abort_to_error(op->ac.abort_code);
308 goto failed;277 goto failed;
309 }278 }
310 279
311 case -ETIMEDOUT:280 case -ETIMEDOUT:
312 case -ETIME:281 case -ETIME:
313 if (fc->error != -EDESTADDRREQ)282 if (op->error != -EDESTADDRREQ)
314 goto iterate_address;283 goto iterate_address;
315 /* Fall through */284 /* Fall through */
316 case -ERFKILL:285 case -ERFKILL:
@@ -320,103 +289,94 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc) · 3 unmodified lines
320 case -EHOSTDOWN:289 case -EHOSTDOWN:
321 case -ECONNREFUSED:290 case -ECONNREFUSED:
322 _debug("no conn");291 _debug("no conn");
323 fc->error = error;292 op->error = error;
324 goto iterate_address;293 goto iterate_address;
325 294
326 case -ECONNRESET:295 case -ECONNRESET:
327 _debug("call reset");296 _debug("call reset");
328 fc->error = error;297 op->error = error;
329 goto failed;298 goto failed;
330 }299 }
331 300
332restart_from_beginning:301restart_from_beginning:
333 _debug("restart");302 _debug("restart");
334 afs_end_cursor(&fc->ac);303 afs_end_cursor(&op->ac);
335 afs_put_cb_interest(afs_v2net(vnode), fc->cbi);304 op->server = NULL;
336 fc->cbi = NULL;305 afs_put_serverlist(op->net, op->server_list);
337 afs_put_serverlist(afs_v2net(vnode), fc->server_list);306 op->server_list = NULL;
338 fc->server_list = NULL;
339start:307start:
340 _debug("start");308 _debug("start");
341 /* See if we need to do an update of the volume record. Note that the309 /* See if we need to do an update of the volume record. Note that the
342 * volume may have moved or even have been deleted.310 * volume may have moved or even have been deleted.
343 */311 */
344 error = afs_check_volume_status(vnode->volume, fc);312 error = afs_check_volume_status(op->volume, op);
345 if (error < 0)313 if (error < 0)
346 goto failed_set_error;314 goto failed_set_error;
347 315
348 if (!afs_start_fs_iteration(fc, vnode))316 if (!afs_start_fs_iteration(op, vnode))
349 goto failed;317 goto failed;
350 318
351 _debug("__ VOL %llx __", vnode->volume->vid);319 _debug("__ VOL %llx __", op->volume->vid);
352 error = afs_probe_fileservers(afs_v2net(vnode), fc->key, fc->server_list);
353 if (error < 0)
354 goto failed_set_error;
355 320
356pick_server:321pick_server:
357 _debug("pick [%lx]", fc->untried);322 _debug("pick [%lx]", op->untried);
358 323
359 error = afs_wait_for_fs_probes(fc->server_list, fc->untried);324 error = afs_wait_for_fs_probes(op->server_list, op->untried);
360 if (error < 0)325 if (error < 0)
361 goto failed_set_error;326 goto failed_set_error;
362 327
363 /* Pick the untried server with the lowest RTT. If we have outstanding328 /* Pick the untried server with the lowest RTT. If we have outstanding
364 * callbacks, we stick with the server we're already using if we can.329 * callbacks, we stick with the server we're already using if we can.
365 */330 */
366 if (fc->cbi) {331 if (op->server) {
367 _debug("cbi %u", fc->index);332 _debug("server %u", op->index);
368 if (test_bit(fc->index, &fc->untried))333 if (test_bit(op->index, &op->untried))
369 goto selected_server;334 goto selected_server;
370 afs_put_cb_interest(afs_v2net(vnode), fc->cbi);335 op->server = NULL;
371 fc->cbi = NULL;336 _debug("no server");
372 _debug("nocbi");
373 }337 }
374 338
375 fc->index = -1;339 op->index = -1;
376 rtt = U32_MAX;340 rtt = U32_MAX;
377 for (i = 0; i < fc->server_list->nr_servers; i++) {341 for (i = 0; i < op->server_list->nr_servers; i++) {
378 struct afs_server *s = fc->server_list->servers[i].server;342 struct afs_server *s = op->server_list->servers[i].server;
379 343
380 if (!test_bit(i, &fc->untried) || !s->probe.responded)344 if (!test_bit(i, &op->untried) ||
345 !test_bit(AFS_SERVER_FL_RESPONDING, &s->flags))
381 continue;346 continue;
382 if (s->probe.rtt < rtt) {347 if (s->probe.rtt < rtt) {
383 fc->index = i;348 op->index = i;
384 rtt = s->probe.rtt;349 rtt = s->probe.rtt;
385 }350 }
386 }351 }
387 352
388 if (fc->index == -1)353 if (op->index == -1)
389 goto no_more_servers;354 goto no_more_servers;
390 355
391selected_server:356selected_server:
392 _debug("use %d", fc->index);357 _debug("use %d", op->index);
393 __clear_bit(fc->index, &fc->untried);358 __clear_bit(op->index, &op->untried);
394 359
395 /* We're starting on a different fileserver from the list. We need to360 /* We're starting on a different fileserver from the list. We need to
396 * check it, create a callback intercept, find its address list and361 * check it, create a callback intercept, find its address list and
397 * probe its capabilities before we use it.362 * probe its capabilities before we use it.
398 */363 */
399 ASSERTCMP(fc->ac.alist, ==, NULL);364 ASSERTCMP(op->ac.alist, ==, NULL);
400 server = fc->server_list->servers[fc->index].server;365 server = op->server_list->servers[op->index].server;
401 366
402 if (!afs_check_server_record(fc, server))367 if (!afs_check_server_record(op, server))
403 goto failed;368 goto failed;
404 369
405 _debug("USING SERVER: %pU", &server->uuid);370 _debug("USING SERVER: %pU", &server->uuid);
406 371
407 /* Make sure we've got a callback interest record for this server. We372 op->flags |= AFS_OPERATION_RETRY_SERVER;
408 * have to link it in before we send the request as we can be sent a373 op->server = server;
409 * break request before we've finished decoding the reply and374 if (vnode->cb_server != server) {
410 * installing the vnode.375 vnode->cb_server = server;
411 */376 vnode->cb_s_break = server->cb_s_break;
412 error = afs_register_server_cb_interest(vnode, fc->server_list,377 vnode->cb_v_break = vnode->volume->cb_v_break;
413 fc->index);378 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
414 if (error < 0)379 }
415 goto failed_set_error;
416
417 fc->cbi = afs_get_cb_interest(
418 rcu_dereference_protected(vnode->cb_interest,
419 lockdep_is_held(&vnode->io_lock)));
420 380
421 read_lock(&server->fs_lock);381 read_lock(&server->fs_lock);
422 alist = rcu_dereference_protected(server->addresses,382 alist = rcu_dereference_protected(server->addresses,
@@ -424,44 +384,68 @@ selected_server: · 1 unmodified line
424 afs_get_addrlist(alist);384 afs_get_addrlist(alist);
425 read_unlock(&server->fs_lock);385 read_unlock(&server->fs_lock);
426 386
427 memset(&fc->ac, 0, sizeof(fc->ac));387retry_server:
388 memset(&op->ac, 0, sizeof(op->ac));
428 389
429 if (!fc->ac.alist)390 if (!op->ac.alist)
430 fc->ac.alist = alist;391 op->ac.alist = alist;
431 else392 else
432 afs_put_addrlist(alist);393 afs_put_addrlist(alist);
433 394
434 fc->ac.index = -1;395 op->ac.index = -1;
435 396
436iterate_address:397iterate_address:
437 ASSERT(fc->ac.alist);398 ASSERT(op->ac.alist);
438 /* Iterate over the current server's address list to try and find an399 /* Iterate over the current server's address list to try and find an
439 * address on which it will respond to us.400 * address on which it will respond to us.
440 */401 */
441 if (!afs_iterate_addresses(&fc->ac))402 if (!afs_iterate_addresses(&op->ac))
442 goto next_server;403 goto out_of_addresses;
443 404
444 _debug("address [%u] %u/%u", fc->index, fc->ac.index, fc->ac.alist->nr_addrs);405 _debug("address [%u] %u/%u %pISp",
406 op->index, op->ac.index, op->ac.alist->nr_addrs,
407 &op->ac.alist->addrs[op->ac.index].transport);
445 408
446 _leave(" = t");409 _leave(" = t");
447 return true;410 return true;
448 411
412out_of_addresses:
413 /* We've now had a failure to respond on all of a server's addresses -
414 * immediately probe them again and consider retrying the server.
415 */
416 afs_probe_fileserver(op->net, op->server);
417 if (op->flags & AFS_OPERATION_RETRY_SERVER) {
418 alist = op->ac.alist;
419 error = afs_wait_for_one_fs_probe(
420 op->server, !(op->flags & AFS_OPERATION_UNINTR));
421 switch (error) {
422 case 0:
423 op->flags &= ~AFS_OPERATION_RETRY_SERVER;
424 goto retry_server;
425 case -ERESTARTSYS:
426 goto failed_set_error;
427 case -ETIME:
428 case -EDESTADDRREQ:
429 goto next_server;
430 }
431 }
432
449next_server:433next_server:
450 _debug("next");434 _debug("next");
451 afs_end_cursor(&fc->ac);435 afs_end_cursor(&op->ac);
452 goto pick_server;436 goto pick_server;
453 437
454no_more_servers:438no_more_servers:
455 /* That's all the servers poked to no good effect. Try again if some439 /* That's all the servers poked to no good effect. Try again if some
456 * of them were busy.440 * of them were busy.
457 */441 */
458 if (fc->flags & AFS_FS_CURSOR_VBUSY)442 if (op->flags & AFS_OPERATION_VBUSY)
459 goto restart_from_beginning;443 goto restart_from_beginning;
460 444
461 e.error = -EDESTADDRREQ;445 e.error = -EDESTADDRREQ;
462 e.responded = false;446 e.responded = false;
463 for (i = 0; i < fc->server_list->nr_servers; i++) {447 for (i = 0; i < op->server_list->nr_servers; i++) {
464 struct afs_server *s = fc->server_list->servers[i].server;448 struct afs_server *s = op->server_list->servers[i].server;
465 449
466 afs_prioritise_error(&e, READ_ONCE(s->probe.error),450 afs_prioritise_error(&e, READ_ONCE(s->probe.error),
467 s->probe.abort_code);451 s->probe.abort_code);
@@ -470,101 +454,18 @@ no_more_servers: · 2 unmodified lines
470 error = e.error;454 error = e.error;
471 455
472failed_set_error:456failed_set_error:
473 fc->error = error;457 op->error = error;
474failed:458failed:
475 fc->flags |= AFS_FS_CURSOR_STOP;459 op->flags |= AFS_OPERATION_STOP;
476 afs_end_cursor(&fc->ac);460 afs_end_cursor(&op->ac);
477 _leave(" = f [failed %d]", fc->error);461 _leave(" = f [failed %d]", op->error);
478 return false;
479}
480
481/*
482 * Select the same fileserver we used for a vnode before and only that
483 * fileserver. We use this when we have a lock on that file, which is backed
484 * only by the fileserver we obtained it from.
485 */
486bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
487{
488 struct afs_vnode *vnode = fc->vnode;
489 struct afs_cb_interest *cbi;
490 struct afs_addr_list *alist;
491 int error = fc->ac.error;
492
493 _enter("");
494
495 cbi = rcu_dereference_protected(vnode->cb_interest,
496 lockdep_is_held(&vnode->io_lock));
497
498 switch (error) {
499 case SHRT_MAX:
500 if (!cbi) {
501 fc->error = -ESTALE;
502 fc->flags |= AFS_FS_CURSOR_STOP;
503 return false;
504 }
505
506 fc->cbi = afs_get_cb_interest(cbi);
507
508 read_lock(&cbi->server->fs_lock);
509 alist = rcu_dereference_protected(cbi->server->addresses,
510 lockdep_is_held(&cbi->server->fs_lock));
511 afs_get_addrlist(alist);
512 read_unlock(&cbi->server->fs_lock);
513 if (!alist) {
514 fc->error = -ESTALE;
515 fc->flags |= AFS_FS_CURSOR_STOP;
516 return false;
517 }
518
519 memset(&fc->ac, 0, sizeof(fc->ac));
520 fc->ac.alist = alist;
521 fc->ac.index = -1;
522 goto iterate_address;
523
524 case 0:
525 default:
526 /* Success or local failure. Stop. */
527 fc->error = error;
528 fc->flags |= AFS_FS_CURSOR_STOP;
529 _leave(" = f [okay/local %d]", error);
530 return false;
531
532 case -ECONNABORTED:
533 fc->error = afs_abort_to_error(fc->ac.abort_code);
534 fc->flags |= AFS_FS_CURSOR_STOP;
535 _leave(" = f [abort]");
536 return false;
537
538 case -ERFKILL:
539 case -EADDRNOTAVAIL:
540 case -ENETUNREACH:
541 case -EHOSTUNREACH:
542 case -EHOSTDOWN:
543 case -ECONNREFUSED:
544 case -ETIMEDOUT:
545 case -ETIME:
546 _debug("no conn");
547 fc->error = error;
548 goto iterate_address;
549 }
550
551iterate_address:
552 /* Iterate over the current server's address list to try and find an
553 * address on which it will respond to us.
554 */
555 if (afs_iterate_addresses(&fc->ac)) {
556 _leave(" = t");
557 return true;
558 }
559
560 afs_end_cursor(&fc->ac);
561 return false;462 return false;
562}463}
563 464
564/*465/*
565 * Dump cursor state in the case of the error being EDESTADDRREQ.466 * Dump cursor state in the case of the error being EDESTADDRREQ.
566 */467 */
567static void afs_dump_edestaddrreq(const struct afs_fs_cursor *fc)468void afs_dump_edestaddrreq(const struct afs_operation *op)
568{469{
569 static int count;470 static int count;
570 int i;471 int i;
@@ -576,13 +477,14 @@ static void afs_dump_edestaddrreq(const struct afs_fs_cursor *fc) · 5 unmodified lines
576 rcu_read_lock();477 rcu_read_lock();
577 478
578 pr_notice("EDESTADDR occurred\n");479 pr_notice("EDESTADDR occurred\n");
579 pr_notice("FC: cbb=%x cbb2=%x fl=%hx err=%hd\n",480 pr_notice("FC: cbb=%x cbb2=%x fl=%x err=%hd\n",
580 fc->cb_break, fc->cb_break_2, fc->flags, fc->error);481 op->file[0].cb_break_before,
482 op->file[1].cb_break_before, op->flags, op->error);
581 pr_notice("FC: ut=%lx ix=%d ni=%u\n",483 pr_notice("FC: ut=%lx ix=%d ni=%u\n",
582 fc->untried, fc->index, fc->nr_iterations);484 op->untried, op->index, op->nr_iterations);
583 485
584 if (fc->server_list) {486 if (op->server_list) {
585 const struct afs_server_list *sl = fc->server_list;487 const struct afs_server_list *sl = op->server_list;
586 pr_notice("FC: SL nr=%u pr=%u vnov=%hx\n",488 pr_notice("FC: SL nr=%u pr=%u vnov=%hx\n",
587 sl->nr_servers, sl->preferred, sl->vnovol_mask);489 sl->nr_servers, sl->preferred, sl->vnovol_mask);
588 for (i = 0; i < sl->nr_servers; i++) {490 for (i = 0; i < sl->nr_servers; i++) {
@@ -596,41 +498,16 @@ static void afs_dump_edestaddrreq(const struct afs_fs_cursor *fc) · 7 unmodified lines
596 a->version,498 a->version,
597 a->nr_ipv4, a->nr_addrs, a->max_addrs,499 a->nr_ipv4, a->nr_addrs, a->max_addrs,
598 a->preferred);500 a->preferred);
599 pr_notice("FC: - pr=%lx R=%lx F=%lx\n",501 pr_notice("FC: - R=%lx F=%lx\n",
600 a->probed, a->responded, a->failed);502 a->responded, a->failed);
601 if (a == fc->ac.alist)503 if (a == op->ac.alist)
602 pr_notice("FC: - current\n");504 pr_notice("FC: - current\n");
603 }505 }
604 }506 }
605 }507 }
606 508
607 pr_notice("AC: t=%lx ax=%u ac=%d er=%d r=%u ni=%u\n",509 pr_notice("AC: t=%lx ax=%u ac=%d er=%d r=%u ni=%u\n",
608 fc->ac.tried, fc->ac.index, fc->ac.abort_code, fc->ac.error,510 op->ac.tried, op->ac.index, op->ac.abort_code, op->ac.error,
609 fc->ac.responded, fc->ac.nr_iterations);511 op->ac.responded, op->ac.nr_iterations);
610 rcu_read_unlock();512 rcu_read_unlock();
611}513}
612
613/*
614 * Tidy up a filesystem cursor and unlock the vnode.
615 */
616int afs_end_vnode_operation(struct afs_fs_cursor *fc)
617{
618 struct afs_net *net = afs_v2net(fc->vnode);
619
620 if (fc->error == -EDESTADDRREQ ||
621 fc->error == -EADDRNOTAVAIL ||
622 fc->error == -ENETUNREACH ||
623 fc->error == -EHOSTUNREACH)
624 afs_dump_edestaddrreq(fc);
625
626 mutex_unlock(&fc->vnode->io_lock);
627
628 afs_end_cursor(&fc->ac);
629 afs_put_cb_interest(net, fc->cbi);
630 afs_put_serverlist(net, fc->server_list);
631
632 if (fc->error == -ECONNABORTED)
633 fc->error = afs_abort_to_error(fc->ac.abort_code);
634
635 return fc->error;
636}
fs/afs/rxrpc.c+26−19
@@ -181,8 +181,7 @@ void afs_put_call(struct afs_call *call) · 180 unmodified lines
181 if (call->type->destructor)181 if (call->type->destructor)
182 call->type->destructor(call);182 call->type->destructor(call);
183 183
184 afs_put_server(call->net, call->server, afs_server_trace_put_call);184 afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
185 afs_put_cb_interest(call->net, call->cbi);
186 afs_put_addrlist(call->alist);185 afs_put_addrlist(call->alist);
187 kfree(call->request);186 kfree(call->request);
188 187
@@ -281,18 +280,19 @@ static void afs_load_bvec(struct afs_call *call, struct msghdr *msg, · 92 unmodified lines
281 struct bio_vec *bv, pgoff_t first, pgoff_t last,280 struct bio_vec *bv, pgoff_t first, pgoff_t last,
282 unsigned offset)281 unsigned offset)
283{282{
283 struct afs_operation *op = call->op;
284 struct page *pages[AFS_BVEC_MAX];284 struct page *pages[AFS_BVEC_MAX];
285 unsigned int nr, n, i, to, bytes = 0;285 unsigned int nr, n, i, to, bytes = 0;
286 286
287 nr = min_t(pgoff_t, last - first + 1, AFS_BVEC_MAX);287 nr = min_t(pgoff_t, last - first + 1, AFS_BVEC_MAX);
288 n = find_get_pages_contig(call->mapping, first, nr, pages);288 n = find_get_pages_contig(op->store.mapping, first, nr, pages);
289 ASSERTCMP(n, ==, nr);289 ASSERTCMP(n, ==, nr);
290 290
291 msg->msg_flags |= MSG_MORE;291 msg->msg_flags |= MSG_MORE;
292 for (i = 0; i < nr; i++) {292 for (i = 0; i < nr; i++) {
293 to = PAGE_SIZE;293 to = PAGE_SIZE;
294 if (first + i >= last) {294 if (first + i >= last) {
295 to = call->last_to;295 to = op->store.last_to;
296 msg->msg_flags &= ~MSG_MORE;296 msg->msg_flags &= ~MSG_MORE;
297 }297 }
298 bv[i].bv_page = pages[i];298 bv[i].bv_page = pages[i];
@@ -322,13 +322,14 @@ static void afs_notify_end_request_tx(struct sock *sock, · 23 unmodified lines
322 */322 */
323static int afs_send_pages(struct afs_call *call, struct msghdr *msg)323static int afs_send_pages(struct afs_call *call, struct msghdr *msg)
324{324{
325 struct afs_operation *op = call->op;
325 struct bio_vec bv[AFS_BVEC_MAX];326 struct bio_vec bv[AFS_BVEC_MAX];
326 unsigned int bytes, nr, loop, offset;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 int ret;329 int ret;
329 330
330 offset = call->first_offset;331 offset = op->store.first_offset;
331 call->first_offset = 0;332 op->store.first_offset = 0;
332 333
333 do {334 do {
334 afs_load_bvec(call, msg, bv, first, last, offset);335 afs_load_bvec(call, msg, bv, first, last, offset);
@@ -338,7 +339,7 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg) · 3 unmodified lines
338 bytes = msg->msg_iter.count;339 bytes = msg->msg_iter.count;
339 nr = msg->msg_iter.nr_segs;340 nr = msg->msg_iter.nr_segs;
340 341
341 ret = rxrpc_kernel_send_data(call->net->socket, call->rxcall, msg,342 ret = rxrpc_kernel_send_data(op->net->socket, call->rxcall, msg,
342 bytes, afs_notify_end_request_tx);343 bytes, afs_notify_end_request_tx);
343 for (loop = 0; loop < nr; loop++)344 for (loop = 0; loop < nr; loop++)
344 put_page(bv[loop].bv_page);345 put_page(bv[loop].bv_page);
@@ -348,7 +349,7 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg) · 3 unmodified lines
348 first += nr;349 first += nr;
349 } while (first <= last);350 } while (first <= last);
350 351
351 trace_afs_sent_pages(call, call->first, last, first, ret);352 trace_afs_sent_pages(call, op->store.first, last, first, ret);
352 return ret;353 return ret;
353}354}
354 355
@@ -383,16 +384,18 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) · 28 unmodified lines
383 */384 */
384 tx_total_len = call->request_size;385 tx_total_len = call->request_size;
385 if (call->send_pages) {386 if (call->send_pages) {
386 if (call->last == call->first) {387 struct afs_operation *op = call->op;
387 tx_total_len += call->last_to - call->first_offset;388
389 if (op->store.last == op->store.first) {
390 tx_total_len += op->store.last_to - op->store.first_offset;
388 } else {391 } else {
389 /* It looks mathematically like you should be able to392 /* It looks mathematically like you should be able to
390 * combine the following lines with the ones above, but393 * combine the following lines with the ones above, but
391 * unsigned arithmetic is fun when it wraps...394 * unsigned arithmetic is fun when it wraps...
392 */395 */
393 tx_total_len += PAGE_SIZE - call->first_offset;396 tx_total_len += PAGE_SIZE - op->store.first_offset;
394 tx_total_len += call->last_to;397 tx_total_len += op->store.last_to;
395 tx_total_len += (call->last - call->first - 1) * PAGE_SIZE;398 tx_total_len += (op->store.last - op->store.first - 1) * PAGE_SIZE;
396 }399 }
397 }400 }
398 401
@@ -538,13 +541,15 @@ static void afs_deliver_to_call(struct afs_call *call) · 139 unmodified lines
538 541
539 ret = call->type->deliver(call);542 ret = call->type->deliver(call);
540 state = READ_ONCE(call->state);543 state = READ_ONCE(call->state);
544 if (ret == 0 && call->unmarshalling_error)
545 ret = -EBADMSG;
541 switch (ret) {546 switch (ret) {
542 case 0:547 case 0:
543 afs_queue_call_work(call);548 afs_queue_call_work(call);
544 if (state == AFS_CALL_CL_PROC_REPLY) {549 if (state == AFS_CALL_CL_PROC_REPLY) {
545 if (call->cbi)550 if (call->op)
546 set_bit(AFS_SERVER_FL_MAY_HAVE_CB,551 set_bit(AFS_SERVER_FL_MAY_HAVE_CB,
547 &call->cbi->server->flags);552 &call->op->server->flags);
548 goto call_complete;553 goto call_complete;
549 }554 }
550 ASSERTCMP(state, >, AFS_CALL_CL_PROC_REPLY);555 ASSERTCMP(state, >, AFS_CALL_CL_PROC_REPLY);
@@ -957,9 +962,11 @@ int afs_extract_data(struct afs_call *call, bool want_more) · 406 unmodified lines
957/*962/*
958 * Log protocol error production.963 * Log protocol error production.
959 */964 */
960noinline int afs_protocol_error(struct afs_call *call, int error,965noinline int afs_protocol_error(struct afs_call *call,
961 enum afs_eproto_cause cause)966 enum afs_eproto_cause cause)
962{967{
963 trace_afs_protocol_error(call, error, cause);968 trace_afs_protocol_error(call, cause);
964 return error;969 if (call)
970 call->unmarshalling_error = true;
971 return -EBADMSG;
965}972}
fs/afs/security.c+3−5
@@ -170,8 +170,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, · 169 unmodified lines
170 break;170 break;
171 }171 }
172 172
173 if (afs_cb_is_broken(cb_break, vnode,173 if (afs_cb_is_broken(cb_break, vnode)) {
174 rcu_dereference(vnode->cb_interest))) {
175 changed = true;174 changed = true;
176 break;175 break;
177 }176 }
@@ -201,7 +200,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, · 23 unmodified lines
201 }200 }
202 }201 }
203 202
204 if (afs_cb_is_broken(cb_break, vnode, rcu_dereference(vnode->cb_interest)))203 if (afs_cb_is_broken(cb_break, vnode))
205 goto someone_else_changed_it;204 goto someone_else_changed_it;
206 205
207 /* We need a ref on any permits list we want to copy as we'll have to206 /* We need a ref on any permits list we want to copy as we'll have to
@@ -281,8 +280,7 @@ found: · 73 unmodified lines
281 rcu_read_lock();280 rcu_read_lock();
282 spin_lock(&vnode->lock);281 spin_lock(&vnode->lock);
283 zap = rcu_access_pointer(vnode->permit_cache);282 zap = rcu_access_pointer(vnode->permit_cache);
284 if (!afs_cb_is_broken(cb_break, vnode, rcu_dereference(vnode->cb_interest)) &&283 if (!afs_cb_is_broken(cb_break, vnode) && zap == permits)
285 zap == permits)
286 rcu_assign_pointer(vnode->permit_cache, replacement);284 rcu_assign_pointer(vnode->permit_cache, replacement);
287 else285 else
288 zap = replacement;286 zap = replacement;
fs/afs/server.c+197−102
@@ -12,19 +12,11 @@ · 11 unmodified lines
12#include "protocol_yfs.h"12#include "protocol_yfs.h"
13 13
14static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */14static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */
15static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */
16static atomic_t afs_server_debug_id;15static atomic_t afs_server_debug_id;
17 16
18static void afs_inc_servers_outstanding(struct afs_net *net)17static struct afs_server *afs_maybe_use_server(struct afs_server *,
19{18 enum afs_server_trace);
20 atomic_inc(&net->servers_outstanding);19static void __afs_put_server(struct afs_net *, struct afs_server *);
21}
22
23static 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}
28 20
29/*21/*
30 * Find a server by one of its addresses.22 * Find a server by one of its addresses.
@@ -41,7 +33,7 @@ struct afs_server *afs_find_server(struct afs_net *net, · 10 unmodified lines
41 33
42 do {34 do {
43 if (server)35 if (server)
44 afs_put_server(net, server, afs_server_trace_put_find_rsq);36 afs_unuse_server_notime(net, server, afs_server_trace_put_find_rsq);
45 server = NULL;37 server = NULL;
46 read_seqbegin_or_lock(&net->fs_addr_lock, &seq);38 read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
47 39
@@ -79,9 +71,9 @@ struct afs_server *afs_find_server(struct afs_net *net, · 31 unmodified lines
79 }71 }
80 72
81 server = NULL;73 server = NULL;
74 continue;
82 found:75 found:
83 if (server && !atomic_inc_not_zero(&server->usage))76 server = afs_maybe_use_server(server, afs_server_trace_get_by_addr);
84 server = NULL;
85 77
86 } while (need_seqretry(&net->fs_addr_lock, seq));78 } while (need_seqretry(&net->fs_addr_lock, seq));
87 79
@@ -92,7 +84,7 @@ struct afs_server *afs_find_server(struct afs_net *net, · 4 unmodified lines
92}84}
93 85
94/*86/*
95 * Look up a server by its UUID87 * Look up a server by its UUID and mark it active.
96 */88 */
97struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uuid)89struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uuid)
98{90{
@@ -108,7 +100,7 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu · 9 unmodified lines
108 * changes.100 * changes.
109 */101 */
110 if (server)102 if (server)
111 afs_put_server(net, server, afs_server_trace_put_uuid_rsq);103 afs_unuse_server(net, server, afs_server_trace_put_uuid_rsq);
112 server = NULL;104 server = NULL;
113 105
114 read_seqbegin_or_lock(&net->fs_lock, &seq);106 read_seqbegin_or_lock(&net->fs_lock, &seq);
@@ -123,7 +115,7 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu · 8 unmodified lines
123 } else if (diff > 0) {115 } else if (diff > 0) {
124 p = p->rb_right;116 p = p->rb_right;
125 } else {117 } else {
126 afs_get_server(server, afs_server_trace_get_by_uuid);118 afs_use_server(server, afs_server_trace_get_by_uuid);
127 break;119 break;
128 }120 }
129 121
@@ -138,13 +130,16 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu · 8 unmodified lines
138}130}
139 131
140/*132/*
141 * Install a server record in the namespace tree133 * Install a server record in the namespace tree. If there's a clash, we stick
134 * it into a list anchored on whichever afs_server struct is actually in the
135 * tree.
142 */136 */
143static struct afs_server *afs_install_server(struct afs_net *net,137static struct afs_server *afs_install_server(struct afs_cell *cell,
144 struct afs_server *candidate)138 struct afs_server *candidate)
145{139{
146 const struct afs_addr_list *alist;140 const struct afs_addr_list *alist;
147 struct afs_server *server;141 struct afs_server *server, *next;
142 struct afs_net *net = cell->net;
148 struct rb_node **pp, *p;143 struct rb_node **pp, *p;
149 int diff;144 int diff;
150 145
@@ -160,12 +155,30 @@ static struct afs_server *afs_install_server(struct afs_net *net, · 9 unmodified lines
160 _debug("- consider %p", p);155 _debug("- consider %p", p);
161 server = rb_entry(p, struct afs_server, uuid_rb);156 server = rb_entry(p, struct afs_server, uuid_rb);
162 diff = memcmp(&candidate->uuid, &server->uuid, sizeof(uuid_t));157 diff = memcmp(&candidate->uuid, &server->uuid, sizeof(uuid_t));
163 if (diff < 0)158 if (diff < 0) {
164 pp = &(*pp)->rb_left;159 pp = &(*pp)->rb_left;
165 else if (diff > 0)160 } else if (diff > 0) {
166 pp = &(*pp)->rb_right;161 pp = &(*pp)->rb_right;
167 else162 } else {
168 goto exists;163 if (server->cell == cell)
164 goto exists;
165
166 /* We have the same UUID representing servers in
167 * different cells. Append the new server to the list.
168 */
169 for (;;) {
170 next = rcu_dereference_protected(
171 server->uuid_next,
172 lockdep_is_held(&net->fs_lock.lock));
173 if (!next)
174 break;
175 server = next;
176 }
177 rcu_assign_pointer(server->uuid_next, candidate);
178 candidate->uuid_prev = server;
179 server = candidate;
180 goto added_dup;
181 }
169 }182 }
170 183
171 server = candidate;184 server = candidate;
@@ -173,6 +186,7 @@ static struct afs_server *afs_install_server(struct afs_net *net, · 1 unmodified line
173 rb_insert_color(&server->uuid_rb, &net->fs_servers);186 rb_insert_color(&server->uuid_rb, &net->fs_servers);
174 hlist_add_head_rcu(&server->proc_link, &net->fs_proc);187 hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
175 188
189added_dup:
176 write_seqlock(&net->fs_addr_lock);190 write_seqlock(&net->fs_addr_lock);
177 alist = rcu_dereference_protected(server->addresses,191 alist = rcu_dereference_protected(server->addresses,
178 lockdep_is_held(&net->fs_addr_lock.lock));192 lockdep_is_held(&net->fs_addr_lock.lock));
@@ -199,13 +213,14 @@ exists: · 20 unmodified lines
199}213}
200 214
201/*215/*
202 * allocate a new server record216 * Allocate a new server record and mark it active.
203 */217 */
204static struct afs_server *afs_alloc_server(struct afs_net *net,218static struct afs_server *afs_alloc_server(struct afs_cell *cell,
205 const uuid_t *uuid,219 const uuid_t *uuid,
206 struct afs_addr_list *alist)220 struct afs_addr_list *alist)
207{221{
208 struct afs_server *server;222 struct afs_server *server;
223 struct afs_net *net = cell->net;
209 224
210 _enter("");225 _enter("");
211 226
@@ -213,20 +228,21 @@ static struct afs_server *afs_alloc_server(struct afs_net *net, · 1 unmodified line
213 if (!server)228 if (!server)
214 goto enomem;229 goto enomem;
215 230
216 atomic_set(&server->usage, 1);231 atomic_set(&server->ref, 1);
232 atomic_set(&server->active, 1);
217 server->debug_id = atomic_inc_return(&afs_server_debug_id);233 server->debug_id = atomic_inc_return(&afs_server_debug_id);
218 RCU_INIT_POINTER(server->addresses, alist);234 RCU_INIT_POINTER(server->addresses, alist);
219 server->addr_version = alist->version;235 server->addr_version = alist->version;
220 server->uuid = *uuid;236 server->uuid = *uuid;
221 server->update_at = ktime_get_real_seconds() + afs_server_update_delay;
222 rwlock_init(&server->fs_lock);237 rwlock_init(&server->fs_lock);
223 INIT_HLIST_HEAD(&server->cb_volumes);
224 rwlock_init(&server->cb_break_lock);
225 init_waitqueue_head(&server->probe_wq);238 init_waitqueue_head(&server->probe_wq);
239 INIT_LIST_HEAD(&server->probe_link);
226 spin_lock_init(&server->probe_lock);240 spin_lock_init(&server->probe_lock);
241 server->cell = cell;
242 server->rtt = UINT_MAX;
227 243
228 afs_inc_servers_outstanding(net);244 afs_inc_servers_outstanding(net);
229 trace_afs_server(server, 1, afs_server_trace_alloc);245 trace_afs_server(server, 1, 1, afs_server_trace_alloc);
230 _leave(" = %p", server);246 _leave(" = %p", server);
231 return server;247 return server;
232 248
@@ -264,7 +280,7 @@ static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell, · 31 unmodified lines
264 * Get or create a fileserver record.280 * Get or create a fileserver record.
265 */281 */
266struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,282struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
267 const uuid_t *uuid)283 const uuid_t *uuid, u32 addr_version)
268{284{
269 struct afs_addr_list *alist;285 struct afs_addr_list *alist;
270 struct afs_server *server, *candidate;286 struct afs_server *server, *candidate;
@@ -272,26 +288,34 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key, · 1 unmodified line
272 _enter("%p,%pU", cell->net, uuid);288 _enter("%p,%pU", cell->net, uuid);
273 289
274 server = afs_find_server_by_uuid(cell->net, uuid);290 server = afs_find_server_by_uuid(cell->net, uuid);
275 if (server)291 if (server) {
292 if (server->addr_version != addr_version)
293 set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
276 return server;294 return server;
295 }
277 296
278 alist = afs_vl_lookup_addrs(cell, key, uuid);297 alist = afs_vl_lookup_addrs(cell, key, uuid);
279 if (IS_ERR(alist))298 if (IS_ERR(alist))
280 return ERR_CAST(alist);299 return ERR_CAST(alist);
281 300
282 candidate = afs_alloc_server(cell->net, uuid, alist);301 candidate = afs_alloc_server(cell, uuid, alist);
283 if (!candidate) {302 if (!candidate) {
284 afs_put_addrlist(alist);303 afs_put_addrlist(alist);
285 return ERR_PTR(-ENOMEM);304 return ERR_PTR(-ENOMEM);
286 }305 }
287 306
288 server = afs_install_server(cell->net, candidate);307 server = afs_install_server(cell, candidate);
289 if (server != candidate) {308 if (server != candidate) {
290 afs_put_addrlist(alist);309 afs_put_addrlist(alist);
291 kfree(candidate);310 kfree(candidate);
311 } else {
312 /* Immediately dispatch an asynchronous probe to each interface
313 * on the fileserver. This will make sure the repeat-probing
314 * service is started.
315 */
316 afs_fs_probe_fileserver(cell->net, server, key, true);
292 }317 }
293 318
294 _leave(" = %p{%d}", server, atomic_read(&server->usage));
295 return server;319 return server;
296}320}
297 321
@@ -327,9 +351,38 @@ void afs_servers_timer(struct timer_list *timer) · 29 unmodified lines
327struct afs_server *afs_get_server(struct afs_server *server,351struct afs_server *afs_get_server(struct afs_server *server,
328 enum afs_server_trace reason)352 enum afs_server_trace reason)
329{353{
330 unsigned int u = atomic_inc_return(&server->usage);354 unsigned int u = atomic_inc_return(&server->ref);
355
356 trace_afs_server(server, u, atomic_read(&server->active), reason);
357 return server;
358}
359
360/*
361 * Try to get a reference on a server object.
362 */
363static struct afs_server *afs_maybe_use_server(struct afs_server *server,
364 enum afs_server_trace reason)
365{
366 unsigned int r = atomic_fetch_add_unless(&server->ref, 1, 0);
367 unsigned int a;
368
369 if (r == 0)
370 return NULL;
371
372 a = atomic_inc_return(&server->active);
373 trace_afs_server(server, r, a, reason);
374 return server;
375}
376
377/*
378 * Get an active count on a server object.
379 */
380struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
381{
382 unsigned int r = atomic_inc_return(&server->ref);
383 unsigned int a = atomic_inc_return(&server->active);
331 384
332 trace_afs_server(server, u, reason);385 trace_afs_server(server, r, a, reason);
333 return server;386 return server;
334}387}
335 388
@@ -344,32 +397,57 @@ void afs_put_server(struct afs_net *net, struct afs_server *server, · 8 unmodified lines
344 if (!server)397 if (!server)
345 return;398 return;
346 399
347 server->put_time = ktime_get_real_seconds();400 usage = atomic_dec_return(&server->ref);
348 401 trace_afs_server(server, usage, atomic_read(&server->active), reason);
349 usage = atomic_dec_return(&server->usage);402 if (unlikely(usage == 0))
403 __afs_put_server(net, server);
404}
350 405
351 trace_afs_server(server, usage, reason);406/*
407 * Drop an active count on a server object without updating the last-unused
408 * time.
409 */
410void afs_unuse_server_notime(struct afs_net *net, struct afs_server *server,
411 enum afs_server_trace reason)
412{
413 if (server) {
414 unsigned int active = atomic_dec_return(&server->active);
352 415
353 if (likely(usage > 0))416 if (active == 0)
354 return;417 afs_set_server_timer(net, afs_server_gc_delay);
418 afs_put_server(net, server, reason);
419 }
420}
355 421
356 afs_set_server_timer(net, afs_server_gc_delay);422/*
423 * Drop an active count on a server object.
424 */
425void afs_unuse_server(struct afs_net *net, struct afs_server *server,
426 enum afs_server_trace reason)
427{
428 if (server) {
429 server->unuse_time = ktime_get_real_seconds();
430 afs_unuse_server_notime(net, server, reason);
431 }
357}432}
358 433
359static void afs_server_rcu(struct rcu_head *rcu)434static void afs_server_rcu(struct rcu_head *rcu)
360{435{
361 struct afs_server *server = container_of(rcu, struct afs_server, rcu);436 struct afs_server *server = container_of(rcu, struct afs_server, rcu);
362 437
363 trace_afs_server(server, atomic_read(&server->usage),438 trace_afs_server(server, atomic_read(&server->ref),
364 afs_server_trace_free);439 atomic_read(&server->active), afs_server_trace_free);
365 afs_put_addrlist(rcu_access_pointer(server->addresses));440 afs_put_addrlist(rcu_access_pointer(server->addresses));
366 kfree(server);441 kfree(server);
367}442}
368 443
369/*444static void __afs_put_server(struct afs_net *net, struct afs_server *server)
370 * destroy a dead server445{
371 */446 call_rcu(&server->rcu, afs_server_rcu);
372static void afs_destroy_server(struct afs_net *net, struct afs_server *server)447 afs_dec_servers_outstanding(net);
448}
449
450static void afs_give_up_callbacks(struct afs_net *net, struct afs_server *server)
373{451{
374 struct afs_addr_list *alist = rcu_access_pointer(server->addresses);452 struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
375 struct afs_addr_cursor ac = {453 struct afs_addr_cursor ac = {
@@ -378,19 +456,18 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server) · 2 unmodified lines
378 .error = 0,456 .error = 0,
379 };457 };
380 458
381 trace_afs_server(server, atomic_read(&server->usage),459 afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
382 afs_server_trace_give_up_cb);460}
383 461
462/*
463 * destroy a dead server
464 */
465static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
466{
384 if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))467 if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
385 afs_fs_give_up_all_callbacks(net, server, &ac, NULL);468 afs_give_up_callbacks(net, server);
386 469
387 wait_var_event(&server->probe_outstanding,470 afs_put_server(net, server, afs_server_trace_destroy);
388 atomic_read(&server->probe_outstanding) == 0);
389
390 trace_afs_server(server, atomic_read(&server->usage),
391 afs_server_trace_destroy);
392 call_rcu(&server->rcu, afs_server_rcu);
393 afs_dec_servers_outstanding(net);
394}471}
395 472
396/*473/*
@@ -398,32 +475,49 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server) · 1 unmodified line
398 */475 */
399static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)476static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
400{477{
401 struct afs_server *server;478 struct afs_server *server, *next, *prev;
402 bool deleted;479 int active;
403 int usage;
404 480
405 while ((server = gc_list)) {481 while ((server = gc_list)) {
406 gc_list = server->gc_next;482 gc_list = server->gc_next;
407 483
408 write_seqlock(&net->fs_lock);484 write_seqlock(&net->fs_lock);
409 usage = 1;
410 deleted = atomic_try_cmpxchg(&server->usage, &usage, 0);
411 trace_afs_server(server, usage, afs_server_trace_gc);
412 if (deleted) {
413 rb_erase(&server->uuid_rb, &net->fs_servers);
414 hlist_del_rcu(&server->proc_link);
415 }
416 write_sequnlock(&net->fs_lock);
417 485
418 if (deleted) {486 active = atomic_read(&server->active);
419 write_seqlock(&net->fs_addr_lock);487 if (active == 0) {
488 trace_afs_server(server, atomic_read(&server->ref),
489 active, afs_server_trace_gc);
490 next = rcu_dereference_protected(
491 server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
492 prev = server->uuid_prev;
493 if (!prev) {
494 /* The one at the front is in the tree */
495 if (!next) {
496 rb_erase(&server->uuid_rb, &net->fs_servers);
497 } else {
498 rb_replace_node_rcu(&server->uuid_rb,
499 &next->uuid_rb,
500 &net->fs_servers);
501 next->uuid_prev = NULL;
502 }
503 } else {
504 /* This server is not at the front */
505 rcu_assign_pointer(prev->uuid_next, next);
506 if (next)
507 next->uuid_prev = prev;
508 }
509
510 list_del(&server->probe_link);
511 hlist_del_rcu(&server->proc_link);
420 if (!hlist_unhashed(&server->addr4_link))512 if (!hlist_unhashed(&server->addr4_link))
421 hlist_del_rcu(&server->addr4_link);513 hlist_del_rcu(&server->addr4_link);
422 if (!hlist_unhashed(&server->addr6_link))514 if (!hlist_unhashed(&server->addr6_link))
423 hlist_del_rcu(&server->addr6_link);515 hlist_del_rcu(&server->addr6_link);
424 write_sequnlock(&net->fs_addr_lock);
425 afs_destroy_server(net, server);
426 }516 }
517 write_sequnlock(&net->fs_lock);
518
519 if (active == 0)
520 afs_destroy_server(net, server);
427 }521 }
428}522}
429 523
@@ -452,15 +546,14 @@ void afs_manage_servers(struct work_struct *work) · 22 unmodified lines
452 for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {546 for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
453 struct afs_server *server =547 struct afs_server *server =
454 rb_entry(cursor, struct afs_server, uuid_rb);548 rb_entry(cursor, struct afs_server, uuid_rb);
455 int usage = atomic_read(&server->usage);549 int active = atomic_read(&server->active);
456 550
457 _debug("manage %pU %u", &server->uuid, usage);551 _debug("manage %pU %u", &server->uuid, active);
458 552
459 ASSERTCMP(usage, >=, 1);553 ASSERTIFCMP(purging, active, ==, 0);
460 ASSERTIFCMP(purging, usage, ==, 1);
461 554
462 if (usage == 1) {555 if (active == 0) {
463 time64_t expire_at = server->put_time;556 time64_t expire_at = server->unuse_time;
464 557
465 if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) &&558 if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) &&
466 !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags))559 !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags))
@@ -525,26 +618,27 @@ void afs_purge_servers(struct afs_net *net) · 58 unmodified lines
525/*618/*
526 * Get an update for a server's address list.619 * Get an update for a server's address list.
527 */620 */
528static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct afs_server *server)621static noinline bool afs_update_server_record(struct afs_operation *op,
622 struct afs_server *server)
529{623{
530 struct afs_addr_list *alist, *discard;624 struct afs_addr_list *alist, *discard;
531 625
532 _enter("");626 _enter("");
533 627
534 trace_afs_server(server, atomic_read(&server->usage), afs_server_trace_update);628 trace_afs_server(server, atomic_read(&server->ref), atomic_read(&server->active),
629 afs_server_trace_update);
535 630
536 alist = afs_vl_lookup_addrs(fc->vnode->volume->cell, fc->key,631 alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
537 &server->uuid);
538 if (IS_ERR(alist)) {632 if (IS_ERR(alist)) {
539 if ((PTR_ERR(alist) == -ERESTARTSYS ||633 if ((PTR_ERR(alist) == -ERESTARTSYS ||
540 PTR_ERR(alist) == -EINTR) &&634 PTR_ERR(alist) == -EINTR) &&
541 !(fc->flags & AFS_FS_CURSOR_INTR) &&635 (op->flags & AFS_OPERATION_UNINTR) &&
542 server->addresses) {636 server->addresses) {
543 _leave(" = t [intr]");637 _leave(" = t [intr]");
544 return true;638 return true;
545 }639 }
546 fc->error = PTR_ERR(alist);640 op->error = PTR_ERR(alist);
547 _leave(" = f [%d]", fc->error);641 _leave(" = f [%d]", op->error);
548 return false;642 return false;
549 }643 }
550 644
@@ -558,7 +652,6 @@ static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct a · 7 unmodified lines
558 write_unlock(&server->fs_lock);652 write_unlock(&server->fs_lock);
559 }653 }
560 654
561 server->update_at = ktime_get_real_seconds() + afs_server_update_delay;
562 afs_put_addrlist(discard);655 afs_put_addrlist(discard);
563 _leave(" = t");656 _leave(" = t");
564 return true;657 return true;
@@ -567,10 +660,8 @@ static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct a · 2 unmodified lines
567/*660/*
568 * See if a server's address list needs updating.661 * See if a server's address list needs updating.
569 */662 */
570bool afs_check_server_record(struct afs_fs_cursor *fc, struct afs_server *server)663bool afs_check_server_record(struct afs_operation *op, struct afs_server *server)
571{664{
572 time64_t now = ktime_get_real_seconds();
573 long diff;
574 bool success;665 bool success;
575 int ret, retries = 0;666 int ret, retries = 0;
576 667
@@ -579,25 +670,29 @@ bool afs_check_server_record(struct afs_fs_cursor *fc, struct afs_server *server · 2 unmodified lines
579 ASSERT(server);670 ASSERT(server);
580 671
581retry:672retry:
582 diff = READ_ONCE(server->update_at) - now;673 if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
583 if (diff > 0) {674 goto wait;
584 _leave(" = t [not now %ld]", diff);675 if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
585 return true;676 goto update;
586 }677 _leave(" = t [good]");
678 return true;
587 679
680update:
588 if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {681 if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
589 success = afs_update_server_record(fc, server);682 clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
683 success = afs_update_server_record(op, server);
590 clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);684 clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
591 wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);685 wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
592 _leave(" = %d", success);686 _leave(" = %d", success);
593 return success;687 return success;
594 }688 }
595 689
690wait:
596 ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,691 ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
597 (fc->flags & AFS_FS_CURSOR_INTR) ?692 (op->flags & AFS_OPERATION_UNINTR) ?
598 TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);693 TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
599 if (ret == -ERESTARTSYS) {694 if (ret == -ERESTARTSYS) {
600 fc->error = ret;695 op->error = ret;
601 _leave(" = f [intr]");696 _leave(" = f [intr]");
602 return false;697 return false;
603 }698 }
fs/afs/server_list.c+8−32
@@ -14,11 +14,9 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist) · 13 unmodified lines
14 int i;14 int i;
15 15
16 if (slist && refcount_dec_and_test(&slist->usage)) {16 if (slist && refcount_dec_and_test(&slist->usage)) {
17 for (i = 0; i < slist->nr_servers; i++) {17 for (i = 0; i < slist->nr_servers; i++)
18 afs_put_cb_interest(net, slist->servers[i].cb_interest);18 afs_unuse_server(net, slist->servers[i].server,
19 afs_put_server(net, slist->servers[i].server,19 afs_server_trace_put_slist);
20 afs_server_trace_put_slist);
21 }
22 kfree(slist);20 kfree(slist);
23 }21 }
24}22}
@@ -46,12 +44,16 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, · 21 unmodified lines
46 refcount_set(&slist->usage, 1);44 refcount_set(&slist->usage, 1);
47 rwlock_init(&slist->lock);45 rwlock_init(&slist->lock);
48 46
47 for (i = 0; i < AFS_MAXTYPES; i++)
48 slist->vids[i] = vldb->vid[i];
49
49 /* Make sure a records exists for each server in the list. */50 /* Make sure a records exists for each server in the list. */
50 for (i = 0; i < vldb->nr_servers; i++) {51 for (i = 0; i < vldb->nr_servers; i++) {
51 if (!(vldb->fs_mask[i] & type_mask))52 if (!(vldb->fs_mask[i] & type_mask))
52 continue;53 continue;
53 54
54 server = afs_lookup_server(cell, key, &vldb->fs_server[i]);55 server = afs_lookup_server(cell, key, &vldb->fs_server[i],
56 vldb->addr_version[i]);
55 if (IS_ERR(server)) {57 if (IS_ERR(server)) {
56 ret = PTR_ERR(server);58 ret = PTR_ERR(server);
57 if (ret == -ENOENT ||59 if (ret == -ENOENT ||
@@ -123,31 +125,5 @@ changed: · 65 unmodified lines
123 }125 }
124 }126 }
125 127
126 /* Keep the old callback interest records where possible so that we
127 * maintain callback interception.
128 */
129 i = 0;
130 j = 0;
131 while (i < old->nr_servers && j < new->nr_servers) {
132 if (new->servers[j].server == old->servers[i].server) {
133 struct afs_cb_interest *cbi = old->servers[i].cb_interest;
134 if (cbi) {
135 new->servers[j].cb_interest = cbi;
136 refcount_inc(&cbi->usage);
137 }
138 i++;
139 j++;
140 continue;
141 }
142
143 if (new->servers[j].server < old->servers[i].server) {
144 j++;
145 continue;
146 }
147
148 i++;
149 continue;
150 }
151
152 return true;128 return true;
153}129}
fs/afs/super.c+59−48
@@ -352,7 +352,9 @@ static int afs_validate_fc(struct fs_context *fc) · 351 unmodified lines
352{352{
353 struct afs_fs_context *ctx = fc->fs_private;353 struct afs_fs_context *ctx = fc->fs_private;
354 struct afs_volume *volume;354 struct afs_volume *volume;
355 struct afs_cell *cell;
355 struct key *key;356 struct key *key;
357 int ret;
356 358
357 if (!ctx->dyn_root) {359 if (!ctx->dyn_root) {
358 if (ctx->no_cell) {360 if (ctx->no_cell) {
@@ -365,6 +367,7 @@ static int afs_validate_fc(struct fs_context *fc) · 6 unmodified lines
365 return -EDESTADDRREQ;367 return -EDESTADDRREQ;
366 }368 }
367 369
370 reget_key:
368 /* We try to do the mount securely. */371 /* We try to do the mount securely. */
369 key = afs_request_key(ctx->cell);372 key = afs_request_key(ctx->cell);
370 if (IS_ERR(key))373 if (IS_ERR(key))
@@ -373,10 +376,26 @@ static int afs_validate_fc(struct fs_context *fc) · 2 unmodified lines
373 ctx->key = key;376 ctx->key = key;
374 377
375 if (ctx->volume) {378 if (ctx->volume) {
376 afs_put_volume(ctx->cell, ctx->volume);379 afs_put_volume(ctx->net, ctx->volume,
380 afs_volume_trace_put_validate_fc);
377 ctx->volume = NULL;381 ctx->volume = NULL;
378 }382 }
379 383
384 if (test_bit(AFS_CELL_FL_CHECK_ALIAS, &ctx->cell->flags)) {
385 ret = afs_cell_detect_alias(ctx->cell, key);
386 if (ret < 0)
387 return ret;
388 if (ret == 1) {
389 _debug("switch to alias");
390 key_put(ctx->key);
391 ctx->key = NULL;
392 cell = afs_get_cell(ctx->cell->alias_of);
393 afs_put_cell(ctx->net, ctx->cell);
394 ctx->cell = cell;
395 goto reget_key;
396 }
397 }
398
380 volume = afs_create_volume(ctx);399 volume = afs_create_volume(ctx);
381 if (IS_ERR(volume))400 if (IS_ERR(volume))
382 return PTR_ERR(volume);401 return PTR_ERR(volume);
@@ -421,7 +440,6 @@ static int afs_set_super(struct super_block *sb, struct fs_context *fc) · 38 unmodified lines
421static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)440static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)
422{441{
423 struct afs_super_info *as = AFS_FS_S(sb);442 struct afs_super_info *as = AFS_FS_S(sb);
424 struct afs_iget_data iget_data;
425 struct inode *inode = NULL;443 struct inode *inode = NULL;
426 int ret;444 int ret;
427 445
@@ -446,13 +464,7 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) · 18 unmodified lines
446 } else {464 } else {
447 sprintf(sb->s_id, "%llu", as->volume->vid);465 sprintf(sb->s_id, "%llu", as->volume->vid);
448 afs_activate_volume(as->volume);466 afs_activate_volume(as->volume);
449 iget_data.fid.vid = as->volume->vid;467 inode = afs_root_iget(sb, ctx->key);
450 iget_data.fid.vnode = 1;
451 iget_data.fid.vnode_hi = 0;
452 iget_data.fid.unique = 1;
453 iget_data.cb_v_break = as->volume->cb_v_break;
454 iget_data.cb_s_break = 0;
455 inode = afs_iget(sb, ctx->key, &iget_data, NULL, NULL, NULL);
456 }468 }
457 469
458 if (IS_ERR(inode))470 if (IS_ERR(inode))
@@ -473,6 +485,7 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) · 14 unmodified lines
473 goto error;485 goto error;
474 } else {486 } else {
475 sb->s_d_op = &afs_fs_dentry_operations;487 sb->s_d_op = &afs_fs_dentry_operations;
488 rcu_assign_pointer(as->volume->sb, sb);
476 }489 }
477 490
478 _leave(" = 0");491 _leave(" = 0");
@@ -496,7 +509,8 @@ static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc) · 17 unmodified lines
496 as->dyn_root = true;509 as->dyn_root = true;
497 } else {510 } else {
498 as->cell = afs_get_cell(ctx->cell);511 as->cell = afs_get_cell(ctx->cell);
499 as->volume = __afs_get_volume(ctx->volume);512 as->volume = afs_get_volume(ctx->volume,
513 afs_volume_trace_get_alloc_sbi);
500 }514 }
501 }515 }
502 return as;516 return as;
@@ -505,8 +519,9 @@ static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc) · 2 unmodified lines
505static void afs_destroy_sbi(struct afs_super_info *as)519static void afs_destroy_sbi(struct afs_super_info *as)
506{520{
507 if (as) {521 if (as) {
508 afs_put_volume(as->cell, as->volume);522 struct afs_net *net = afs_net(as->net_ns);
509 afs_put_cell(afs_net(as->net_ns), as->cell);523 afs_put_volume(net, as->volume, afs_volume_trace_put_destroy_sbi);
524 afs_put_cell(net, as->cell);
510 put_net(as->net_ns);525 put_net(as->net_ns);
511 kfree(as);526 kfree(as);
512 }527 }
@@ -515,7 +530,6 @@ static void afs_destroy_sbi(struct afs_super_info *as) · 2 unmodified lines
515static void afs_kill_super(struct super_block *sb)530static void afs_kill_super(struct super_block *sb)
516{531{
517 struct afs_super_info *as = AFS_FS_S(sb);532 struct afs_super_info *as = AFS_FS_S(sb);
518 struct afs_net *net = afs_net(as->net_ns);
519 533
520 if (as->dyn_root)534 if (as->dyn_root)
521 afs_dynroot_depopulate(sb);535 afs_dynroot_depopulate(sb);
@@ -524,7 +538,7 @@ static void afs_kill_super(struct super_block *sb) · 2 unmodified lines
524 * deactivating the superblock.538 * deactivating the superblock.
525 */539 */
526 if (as->volume)540 if (as->volume)
527 afs_clear_callback_interests(net, as->volume->servers);541 rcu_assign_pointer(as->volume->sb, NULL);
528 kill_anon_super(sb);542 kill_anon_super(sb);
529 if (as->volume)543 if (as->volume)
530 afs_deactivate_volume(as->volume);544 afs_deactivate_volume(as->volume);
@@ -592,7 +606,7 @@ static void afs_free_fc(struct fs_context *fc) · 61 unmodified lines
592 struct afs_fs_context *ctx = fc->fs_private;606 struct afs_fs_context *ctx = fc->fs_private;
593 607
594 afs_destroy_sbi(fc->s_fs_info);608 afs_destroy_sbi(fc->s_fs_info);
595 afs_put_volume(ctx->cell, ctx->volume);609 afs_put_volume(ctx->net, ctx->volume, afs_volume_trace_put_free_fc);
596 afs_put_cell(ctx->net, ctx->cell);610 afs_put_cell(ctx->net, ctx->cell);
597 key_put(ctx->key);611 key_put(ctx->key);
598 kfree(ctx);612 kfree(ctx);
@@ -674,7 +688,6 @@ static struct inode *afs_alloc_inode(struct super_block *sb) · 75 unmodified lines
674 vnode->volume = NULL;688 vnode->volume = NULL;
675 vnode->lock_key = NULL;689 vnode->lock_key = NULL;
676 vnode->permit_cache = NULL;690 vnode->permit_cache = NULL;
677 RCU_INIT_POINTER(vnode->cb_interest, NULL);
678#ifdef CONFIG_AFS_FSCACHE691#ifdef CONFIG_AFS_FSCACHE
679 vnode->cache = NULL;692 vnode->cache = NULL;
680#endif693#endif
@@ -704,22 +717,38 @@ static void afs_destroy_inode(struct inode *inode) · 23 unmodified lines
704 717
705 _debug("DESTROY INODE %p", inode);718 _debug("DESTROY INODE %p", inode);
706 719
707 ASSERTCMP(rcu_access_pointer(vnode->cb_interest), ==, NULL);
708
709 atomic_dec(&afs_count_active_inodes);720 atomic_dec(&afs_count_active_inodes);
710}721}
711 722
723static void afs_get_volume_status_success(struct afs_operation *op)
724{
725 struct afs_volume_status *vs = &op->volstatus.vs;
726 struct kstatfs *buf = op->volstatus.buf;
727
728 if (vs->max_quota == 0)
729 buf->f_blocks = vs->part_max_blocks;
730 else
731 buf->f_blocks = vs->max_quota;
732
733 if (buf->f_blocks > vs->blocks_in_use)
734 buf->f_bavail = buf->f_bfree =
735 buf->f_blocks - vs->blocks_in_use;
736}
737
738static const struct afs_operation_ops afs_get_volume_status_operation = {
739 .issue_afs_rpc = afs_fs_get_volume_status,
740 .issue_yfs_rpc = yfs_fs_get_volume_status,
741 .success = afs_get_volume_status_success,
742};
743
712/*744/*
713 * return information about an AFS volume745 * return information about an AFS volume
714 */746 */
715static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)747static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)
716{748{
717 struct afs_super_info *as = AFS_FS_S(dentry->d_sb);749 struct afs_super_info *as = AFS_FS_S(dentry->d_sb);
718 struct afs_fs_cursor fc;750 struct afs_operation *op;
719 struct afs_volume_status vs;
720 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));751 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
721 struct key *key;
722 int ret;
723 752
724 buf->f_type = dentry->d_sb->s_magic;753 buf->f_type = dentry->d_sb->s_magic;
725 buf->f_bsize = AFS_BLOCK_SIZE;754 buf->f_bsize = AFS_BLOCK_SIZE;
@@ -732,31 +761,13 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf) · 6 unmodified lines
732 return 0;761 return 0;
733 }762 }
734 763
735 key = afs_request_key(vnode->volume->cell);764 op = afs_alloc_operation(NULL, as->volume);
736 if (IS_ERR(key))765 if (IS_ERR(op))
737 return PTR_ERR(key);766 return PTR_ERR(op);
738 767
739 ret = -ERESTARTSYS;768 afs_op_set_vnode(op, 0, vnode);
740 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {769 op->nr_files = 1;
741 fc.flags |= AFS_FS_CURSOR_NO_VSLEEP;770 op->volstatus.buf = buf;
742 while (afs_select_fileserver(&fc)) {771 op->ops = &afs_get_volume_status_operation;
743 fc.cb_break = afs_calc_vnode_cb_break(vnode);772 return afs_do_sync_operation(op);
744 afs_fs_get_volume_status(&fc, &vs);
745 }
746
747 afs_check_for_remote_deletion(&fc, fc.vnode);
748 ret = afs_end_vnode_operation(&fc);
749 }
750
751 key_put(key);
752
753 if (ret == 0) {
754 if (vs.max_quota == 0)
755 buf->f_blocks = vs.part_max_blocks;
756 else
757 buf->f_blocks = vs.max_quota;
758 buf->f_bavail = buf->f_bfree = buf->f_blocks - vs.blocks_in_use;
759 }
760
761 return ret;
762}773}
fs/afs/vl_alias.c+382−0
@@ -0,0 +1,382 @@
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 */
17static 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 */
38static 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
79out:
80 return diff;
81}
82
83/*
84 * Compare the address lists of a pair of fileservers.
85 */
86static 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 */
118static 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 */
155static 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
177is_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 */
186static 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 */
233static 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
267is_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 */
275static 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
301static 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
325static 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 */
360int 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}
fs/afs/vl_rotate.c+4−0
@@ -151,6 +151,10 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc) · 150 unmodified lines
151 vc->error = error;151 vc->error = error;
152 vc->flags |= AFS_VL_CURSOR_RETRY;152 vc->flags |= AFS_VL_CURSOR_RETRY;
153 goto next_server;153 goto next_server;
154
155 case -EOPNOTSUPP:
156 _debug("notsupp");
157 goto next_server;
154 }158 }
155 159
156restart_from_beginning:160restart_from_beginning:
fs/afs/vlclient.c+126−20
@@ -82,6 +82,7 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call) · 81 unmodified lines
82 for (j = 0; j < 6; j++)82 for (j = 0; j < 6; j++)
83 uuid->node[j] = (u8)ntohl(xdr->node[j]);83 uuid->node[j] = (u8)ntohl(xdr->node[j]);
84 84
85 entry->addr_version[n] = ntohl(uvldb->serverUnique[i]);
85 entry->nr_servers++;86 entry->nr_servers++;
86 }87 }
87 88
@@ -447,8 +448,7 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) · 359 unmodified lines
447 call->count2 = ntohl(*bp); /* Type or next count */448 call->count2 = ntohl(*bp); /* Type or next count */
448 449
449 if (call->count > YFS_MAXENDPOINTS)450 if (call->count > YFS_MAXENDPOINTS)
450 return afs_protocol_error(call, -EBADMSG,451 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num);
451 afs_eproto_yvl_fsendpt_num);
452 452
453 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT);453 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT);
454 if (!alist)454 if (!alist)
@@ -468,8 +468,7 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) · 13 unmodified lines
468 size = sizeof(__be32) * (1 + 4 + 1);468 size = sizeof(__be32) * (1 + 4 + 1);
469 break;469 break;
470 default:470 default:
471 return afs_protocol_error(call, -EBADMSG,471 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
472 afs_eproto_yvl_fsendpt_type);
473 }472 }
474 473
475 size += sizeof(__be32);474 size += sizeof(__be32);
@@ -487,21 +486,20 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) · 11 unmodified lines
487 switch (call->count2) {486 switch (call->count2) {
488 case YFS_ENDPOINT_IPV4:487 case YFS_ENDPOINT_IPV4:
489 if (ntohl(bp[0]) != sizeof(__be32) * 2)488 if (ntohl(bp[0]) != sizeof(__be32) * 2)
490 return afs_protocol_error(call, -EBADMSG,489 return afs_protocol_error(
491 afs_eproto_yvl_fsendpt4_len);490 call, afs_eproto_yvl_fsendpt4_len);
492 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2]));491 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2]));
493 bp += 3;492 bp += 3;
494 break;493 break;
495 case YFS_ENDPOINT_IPV6:494 case YFS_ENDPOINT_IPV6:
496 if (ntohl(bp[0]) != sizeof(__be32) * 5)495 if (ntohl(bp[0]) != sizeof(__be32) * 5)
497 return afs_protocol_error(call, -EBADMSG,496 return afs_protocol_error(
498 afs_eproto_yvl_fsendpt6_len);497 call, afs_eproto_yvl_fsendpt6_len);
499 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5]));498 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5]));
500 bp += 6;499 bp += 6;
501 break;500 break;
502 default:501 default:
503 return afs_protocol_error(call, -EBADMSG,502 return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
504 afs_eproto_yvl_fsendpt_type);
505 }503 }
506 504
507 /* Got either the type of the next entry or the count of505 /* Got either the type of the next entry or the count of
@@ -519,8 +517,7 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) · 11 unmodified lines
519 if (!call->count)517 if (!call->count)
520 goto end;518 goto end;
521 if (call->count > YFS_MAXENDPOINTS)519 if (call->count > YFS_MAXENDPOINTS)
522 return afs_protocol_error(call, -EBADMSG,520 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
523 afs_eproto_yvl_vlendpt_type);
524 521
525 afs_extract_to_buf(call, 1 * sizeof(__be32));522 afs_extract_to_buf(call, 1 * sizeof(__be32));
526 call->unmarshall = 3;523 call->unmarshall = 3;
@@ -547,8 +544,7 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) · 20 unmodified lines
547 size = sizeof(__be32) * (1 + 4 + 1);544 size = sizeof(__be32) * (1 + 4 + 1);
548 break;545 break;
549 default:546 default:
550 return afs_protocol_error(call, -EBADMSG,547 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
551 afs_eproto_yvl_vlendpt_type);
552 }548 }
553 549
554 if (call->count > 1)550 if (call->count > 1)
@@ -566,19 +562,18 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call) · 11 unmodified lines
566 switch (call->count2) {562 switch (call->count2) {
567 case YFS_ENDPOINT_IPV4:563 case YFS_ENDPOINT_IPV4:
568 if (ntohl(bp[0]) != sizeof(__be32) * 2)564 if (ntohl(bp[0]) != sizeof(__be32) * 2)
569 return afs_protocol_error(call, -EBADMSG,565 return afs_protocol_error(
570 afs_eproto_yvl_vlendpt4_len);566 call, afs_eproto_yvl_vlendpt4_len);
571 bp += 3;567 bp += 3;
572 break;568 break;
573 case YFS_ENDPOINT_IPV6:569 case YFS_ENDPOINT_IPV6:
574 if (ntohl(bp[0]) != sizeof(__be32) * 5)570 if (ntohl(bp[0]) != sizeof(__be32) * 5)
575 return afs_protocol_error(call, -EBADMSG,571 return afs_protocol_error(
576 afs_eproto_yvl_vlendpt6_len);572 call, afs_eproto_yvl_vlendpt6_len);
577 bp += 6;573 bp += 6;
578 break;574 break;
579 default:575 default:
580 return afs_protocol_error(call, -EBADMSG,576 return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
581 afs_eproto_yvl_vlendpt_type);
582 }577 }
583 578
584 /* Got either the type of the next entry or the count of579 /* Got either the type of the next entry or the count of
@@ -650,3 +645,114 @@ struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc, · 65 unmodified lines
650 afs_make_call(&vc->ac, call, GFP_KERNEL);645 afs_make_call(&vc->ac, call, GFP_KERNEL);
651 return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);646 return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
652}647}
648
649/*
650 * Deliver reply data to a YFSVL.GetCellName operation.
651 */
652static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
653{
654 char *cell_name;
655 u32 namesz, paddedsz;
656 int ret;
657
658 _enter("{%u,%zu/%u}",
659 call->unmarshall, iov_iter_count(call->iter), call->count);
660
661 switch (call->unmarshall) {
662 case 0:
663 afs_extract_to_tmp(call);
664 call->unmarshall++;
665
666 /* Fall through - and extract the cell name length */
667 case 1:
668 ret = afs_extract_data(call, true);
669 if (ret < 0)
670 return ret;
671
672 namesz = ntohl(call->tmp);
673 if (namesz > AFS_MAXCELLNAME)
674 return afs_protocol_error(call, afs_eproto_cellname_len);
675 paddedsz = (namesz + 3) & ~3;
676 call->count = namesz;
677 call->count2 = paddedsz - namesz;
678
679 cell_name = kmalloc(namesz + 1, GFP_KERNEL);
680 if (!cell_name)
681 return -ENOMEM;
682 cell_name[namesz] = 0;
683 call->ret_str = cell_name;
684
685 afs_extract_begin(call, cell_name, namesz);
686 call->unmarshall++;
687
688 /* Fall through - and extract cell name */
689 case 2:
690 ret = afs_extract_data(call, true);
691 if (ret < 0)
692 return ret;
693
694 afs_extract_discard(call, call->count2);
695 call->unmarshall++;
696
697 /* Fall through - and extract padding */
698 case 3:
699 ret = afs_extract_data(call, false);
700 if (ret < 0)
701 return ret;
702
703 call->unmarshall++;
704 break;
705 }
706
707 _leave(" = 0 [done]");
708 return 0;
709}
710
711static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call)
712{
713 kfree(call->ret_str);
714 afs_flat_call_destructor(call);
715}
716
717/*
718 * VL.GetCapabilities operation type
719 */
720static const struct afs_call_type afs_YFSVLGetCellName = {
721 .name = "YFSVL.GetCellName",
722 .op = afs_YFSVL_GetCellName,
723 .deliver = afs_deliver_yfsvl_get_cell_name,
724 .destructor = afs_destroy_yfsvl_get_cell_name,
725};
726
727/*
728 * Probe a volume server for the capabilities that it supports. This can
729 * return up to 196 words.
730 *
731 * We use this to probe for service upgrade to determine what the server at the
732 * other end supports.
733 */
734char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
735{
736 struct afs_call *call;
737 struct afs_net *net = vc->cell->net;
738 __be32 *bp;
739
740 _enter("");
741
742 call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0);
743 if (!call)
744 return ERR_PTR(-ENOMEM);
745
746 call->key = vc->key;
747 call->ret_str = NULL;
748 call->max_lifespan = AFS_VL_MAX_LIFESPAN;
749
750 /* marshall the parameters */
751 bp = call->request;
752 *bp++ = htonl(YVLGETCELLNAME);
753
754 /* Can't take a ref on server */
755 trace_afs_make_vl_call(call);
756 afs_make_call(&vc->ac, call, GFP_KERNEL);
757 return (char *)afs_wait_for_call_to_complete(call, &vc->ac);
758}
fs/afs/volume.c+119−35
@@ -12,6 +12,56 @@ · 11 unmodified lines
12unsigned __read_mostly afs_volume_gc_delay = 10;12unsigned __read_mostly afs_volume_gc_delay = 10;
13unsigned __read_mostly afs_volume_record_life = 60 * 60;13unsigned __read_mostly afs_volume_record_life = 60 * 60;
14 14
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 */
19static 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
45found:
46 write_sequnlock(&cell->volume_lock);
47 return volume;
48
49}
50
51static 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
15/*65/*
16 * Allocate a volume record and load it up from a vldb record.66 * Allocate a volume record and load it up from a vldb record.
17 */67 */
@@ -39,7 +89,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, · 21 unmodified lines
39 volume->name_len = vldb->name_len;89 volume->name_len = vldb->name_len;
40 90
41 atomic_set(&volume->usage, 1);91 atomic_set(&volume->usage, 1);
42 INIT_LIST_HEAD(&volume->proc_link);92 INIT_HLIST_NODE(&volume->proc_link);
43 rwlock_init(&volume->servers_lock);93 rwlock_init(&volume->servers_lock);
44 rwlock_init(&volume->cb_v_break_lock);94 rwlock_init(&volume->cb_v_break_lock);
45 memcpy(volume->name, vldb->name, vldb->name_len + 1);95 memcpy(volume->name, vldb->name, vldb->name_len + 1);
@@ -51,7 +101,8 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, · 5 unmodified lines
51 }101 }
52 102
53 refcount_set(&slist->usage, 1);103 refcount_set(&slist->usage, 1);
54 volume->servers = slist;104 rcu_assign_pointer(volume->servers, slist);
105 trace_afs_volume(volume->vid, 1, afs_volume_trace_alloc);
55 return volume;106 return volume;
56 107
57error_1:108error_1:
@@ -61,6 +112,25 @@ error_0: · 3 unmodified lines
61 return ERR_PTR(ret);112 return ERR_PTR(ret);
62}113}
63 114
115/*
116 * Look up or allocate a volume record.
117 */
118static struct afs_volume *afs_lookup_volume(struct afs_fs_context *params,
119 struct afs_vldb_entry *vldb,
120 unsigned long type_mask)
121{
122 struct afs_volume *candidate, *volume;
123
124 candidate = afs_alloc_volume(params, vldb, type_mask);
125 if (IS_ERR(candidate))
126 return candidate;
127
128 volume = afs_insert_volume_into_cell(params->cell, candidate);
129 if (volume != candidate)
130 afs_put_volume(params->net, candidate, afs_volume_trace_put_cell_dup);
131 return volume;
132}
133
64/*134/*
65 * Look up a VLDB record for a volume.135 * Look up a VLDB record for a volume.
66 */136 */
@@ -138,7 +208,7 @@ struct afs_volume *afs_create_volume(struct afs_fs_context *params) · 71 unmodified lines
138 }208 }
139 209
140 type_mask = 1UL << params->type;210 type_mask = 1UL << params->type;
141 volume = afs_alloc_volume(params, vldb, type_mask);211 volume = afs_lookup_volume(params, vldb, type_mask);
142 212
143error:213error:
144 kfree(vldb);214 kfree(vldb);
@@ -156,23 +226,42 @@ static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) · 11 unmodified lines
156 ASSERTCMP(volume->cache, ==, NULL);226 ASSERTCMP(volume->cache, ==, NULL);
157#endif227#endif
158 228
159 afs_put_serverlist(net, volume->servers);229 afs_remove_volume_from_cell(volume);
230 afs_put_serverlist(net, rcu_access_pointer(volume->servers));
160 afs_put_cell(net, volume->cell);231 afs_put_cell(net, volume->cell);
161 kfree(volume);232 trace_afs_volume(volume->vid, atomic_read(&volume->usage),
233 afs_volume_trace_free);
234 kfree_rcu(volume, rcu);
162 235
163 _leave(" [destroyed]");236 _leave(" [destroyed]");
164}237}
165 238
166/*239/*
167 * Drop a reference on a volume record.240 * Get a reference on a volume record.
168 */241 */
169void afs_put_volume(struct afs_cell *cell, struct afs_volume *volume)242struct afs_volume *afs_get_volume(struct afs_volume *volume,
243 enum afs_volume_trace reason)
170{244{
171 if (volume) {245 if (volume) {
172 _enter("%s", volume->name);246 int u = atomic_inc_return(&volume->usage);
247 trace_afs_volume(volume->vid, u, reason);
248 }
249 return volume;
250}
251
173 252
174 if (atomic_dec_and_test(&volume->usage))253/*
175 afs_destroy_volume(cell->net, volume);254 * Drop a reference on a volume record.
255 */
256void afs_put_volume(struct afs_net *net, struct afs_volume *volume,
257 enum afs_volume_trace reason)
258{
259 if (volume) {
260 afs_volid_t vid = volume->vid;
261 int u = atomic_dec_return(&volume->usage);
262 trace_afs_volume(vid, u, reason);
263 if (u == 0)
264 afs_destroy_volume(net, volume);
176 }265 }
177}266}
178 267
@@ -188,10 +277,6 @@ void afs_activate_volume(struct afs_volume *volume) · 9 unmodified lines
188 NULL, 0,277 NULL, 0,
189 volume, 0, true);278 volume, 0, true);
190#endif279#endif
191
192 write_lock(&volume->cell->proc_lock);
193 list_add_tail(&volume->proc_link, &volume->cell->proc_volumes);
194 write_unlock(&volume->cell->proc_lock);
195}280}
196 281
197/*282/*
@@ -201,10 +286,6 @@ void afs_deactivate_volume(struct afs_volume *volume) · 3 unmodified lines
201{286{
202 _enter("%s", volume->name);287 _enter("%s", volume->name);
203 288
204 write_lock(&volume->cell->proc_lock);
205 list_del_init(&volume->proc_link);
206 write_unlock(&volume->cell->proc_lock);
207
208#ifdef CONFIG_AFS_FSCACHE289#ifdef CONFIG_AFS_FSCACHE
209 fscache_relinquish_cookie(volume->cache, NULL,290 fscache_relinquish_cookie(volume->cache, NULL,
210 test_bit(AFS_VOLUME_DELETED, &volume->flags));291 test_bit(AFS_VOLUME_DELETED, &volume->flags));
@@ -256,17 +337,17 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) · 45 unmodified lines
256 write_lock(&volume->servers_lock);337 write_lock(&volume->servers_lock);
257 338
258 discard = new;339 discard = new;
259 old = volume->servers;340 old = rcu_dereference_protected(volume->servers,
341 lockdep_is_held(&volume->servers_lock));
260 if (afs_annotate_server_list(new, old)) {342 if (afs_annotate_server_list(new, old)) {
261 new->seq = volume->servers_seq + 1;343 new->seq = volume->servers_seq + 1;
262 volume->servers = new;344 rcu_assign_pointer(volume->servers, new);
263 smp_wmb();345 smp_wmb();
264 volume->servers_seq++;346 volume->servers_seq++;
265 discard = old;347 discard = old;
266 }348 }
267 349
268 volume->update_at = ktime_get_real_seconds() + afs_volume_record_life;350 volume->update_at = ktime_get_real_seconds() + afs_volume_record_life;
269 clear_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags);
270 write_unlock(&volume->servers_lock);351 write_unlock(&volume->servers_lock);
271 ret = 0;352 ret = 0;
272 353
@@ -281,25 +362,27 @@ error: · 8 unmodified lines
281/*362/*
282 * Make sure the volume record is up to date.363 * Make sure the volume record is up to date.
283 */364 */
284int afs_check_volume_status(struct afs_volume *volume, struct afs_fs_cursor *fc)365int afs_check_volume_status(struct afs_volume *volume, struct afs_operation *op)
285{366{
286 time64_t now = ktime_get_real_seconds();
287 int ret, retries = 0;367 int ret, retries = 0;
288 368
289 _enter("");369 _enter("");
290 370
291 if (volume->update_at <= now)
292 set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags);
293
294retry:371retry:
295 if (!test_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags) &&372 if (test_bit(AFS_VOLUME_WAIT, &volume->flags))
296 !test_bit(AFS_VOLUME_WAIT, &volume->flags)) {373 goto wait;
297 _leave(" = 0");374 if (volume->update_at <= ktime_get_real_seconds() ||
298 return 0;375 test_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags))
299 }376 goto update;
300 377 _leave(" = 0");
378 return 0;
379
380update:
301 if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) {381 if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) {
302 ret = afs_update_volume_status(volume, fc->key);382 clear_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags);
383 ret = afs_update_volume_status(volume, op->key);
384 if (ret < 0)
385 set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags);
303 clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags);386 clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags);
304 clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags);387 clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags);
305 wake_up_bit(&volume->flags, AFS_VOLUME_WAIT);388 wake_up_bit(&volume->flags, AFS_VOLUME_WAIT);
@@ -307,14 +390,15 @@ retry: · 1 unmodified line
307 return ret;390 return ret;
308 }391 }
309 392
393wait:
310 if (!test_bit(AFS_VOLUME_WAIT, &volume->flags)) {394 if (!test_bit(AFS_VOLUME_WAIT, &volume->flags)) {
311 _leave(" = 0 [no wait]");395 _leave(" = 0 [no wait]");
312 return 0;396 return 0;
313 }397 }
314 398
315 ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT,399 ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT,
316 (fc->flags & AFS_FS_CURSOR_INTR) ?400 (op->flags & AFS_OPERATION_UNINTR) ?
317 TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);401 TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
318 if (ret == -ERESTARTSYS) {402 if (ret == -ERESTARTSYS) {
319 _leave(" = %d", ret);403 _leave(" = %d", ret);
320 return ret;404 return ret;
fs/afs/write.c+90−58
@@ -349,82 +349,111 @@ static void afs_pages_written_back(struct afs_vnode *vnode, · 348 unmodified lines
349}349}
350 350
351/*351/*
352 * write to a file352 * 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.
353 */355 */
354static int afs_store_data(struct address_space *mapping,356static int afs_get_writeback_key(struct afs_vnode *vnode,
355 pgoff_t first, pgoff_t last,357 struct afs_wb_key **_wbk)
356 unsigned offset, unsigned to)
357{358{
358 struct afs_vnode *vnode = AFS_FS_I(mapping->host);
359 struct afs_fs_cursor fc;
360 struct afs_status_cb *scb;
361 struct afs_wb_key *wbk = NULL;359 struct afs_wb_key *wbk = NULL;
362 struct list_head *p;360 struct list_head *p;
363 int ret = -ENOKEY, ret2;361 int ret = -ENOKEY, ret2;
364 362
365 _enter("%s{%llx:%llu.%u},%lx,%lx,%x,%x",
366 vnode->volume->name,
367 vnode->fid.vid,
368 vnode->fid.vnode,
369 vnode->fid.unique,
370 first, last, offset, to);
371
372 scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS);
373 if (!scb)
374 return -ENOMEM;
375
376 spin_lock(&vnode->wb_lock);363 spin_lock(&vnode->wb_lock);
377 p = vnode->wb_keys.next;364 if (*_wbk)
365 p = (*_wbk)->vnode_link.next;
366 else
367 p = vnode->wb_keys.next;
378 368
379 /* Iterate through the list looking for a valid key to use. */
380try_next_key:
381 while (p != &vnode->wb_keys) {369 while (p != &vnode->wb_keys) {
382 wbk = list_entry(p, struct afs_wb_key, vnode_link);370 wbk = list_entry(p, struct afs_wb_key, vnode_link);
383 _debug("wbk %u", key_serial(wbk->key));371 _debug("wbk %u", key_serial(wbk->key));
384 ret2 = key_validate(wbk->key);372 ret2 = key_validate(wbk->key);
385 if (ret2 == 0)373 if (ret2 == 0) {
386 goto found_key;374 refcount_inc(&wbk->usage);
375 _debug("USE WB KEY %u", key_serial(wbk->key));
376 break;
377 }
378
379 wbk = NULL;
387 if (ret == -ENOKEY)380 if (ret == -ENOKEY)
388 ret = ret2;381 ret = ret2;
389 p = p->next;382 p = p->next;
390 }383 }
391 384
392 spin_unlock(&vnode->wb_lock);385 spin_unlock(&vnode->wb_lock);
393 afs_put_wb_key(wbk);386 if (*_wbk)
394 kfree(scb);387 afs_put_wb_key(*_wbk);
395 _leave(" = %d [no keys]", ret);388 *_wbk = wbk;
396 return ret;389 return 0;
390}
397 391
398found_key:392static void afs_store_data_success(struct afs_operation *op)
399 refcount_inc(&wbk->usage);393{
400 spin_unlock(&vnode->wb_lock);394 struct afs_vnode *vnode = op->file[0].vnode;
401 395
402 _debug("USE WB KEY %u", key_serial(wbk->key));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}
403 405
404 ret = -ERESTARTSYS;406static const struct afs_operation_ops afs_store_data_operation = {
405 if (afs_begin_vnode_operation(&fc, vnode, wbk->key, false)) {407 .issue_afs_rpc = afs_fs_store_data,
406 afs_dataversion_t data_version = vnode->status.data_version + 1;408 .issue_yfs_rpc = yfs_fs_store_data,
409 .success = afs_store_data_success,
410};
407 411
408 while (afs_select_fileserver(&fc)) {412/*
409 fc.cb_break = afs_calc_vnode_cb_break(vnode);413 * write to a file
410 afs_fs_store_data(&fc, mapping, first, last, offset, to, scb);414 */
411 }415static int afs_store_data(struct address_space *mapping,
416 pgoff_t first, pgoff_t last,
417 unsigned offset, unsigned to)
418{
419 struct afs_vnode *vnode = AFS_FS_I(mapping->host);
420 struct afs_operation *op;
421 struct afs_wb_key *wbk = NULL;
422 int ret;
412 423
413 afs_check_for_remote_deletion(&fc, vnode);424 _enter("%s{%llx:%llu.%u},%lx,%lx,%x,%x",
414 afs_vnode_commit_status(&fc, vnode, fc.cb_break,425 vnode->volume->name,
415 &data_version, scb);426 vnode->fid.vid,
416 if (fc.ac.error == 0)427 vnode->fid.vnode,
417 afs_pages_written_back(vnode, first, last);428 vnode->fid.unique,
418 ret = afs_end_vnode_operation(&fc);429 first, last, offset, to);
430
431 ret = afs_get_writeback_key(vnode, &wbk);
432 if (ret) {
433 _leave(" = %d [no keys]", ret);
434 return ret;
419 }435 }
420 436
421 switch (ret) {437 op = afs_alloc_operation(wbk->key, vnode->volume);
422 case 0:438 if (IS_ERR(op)) {
423 afs_stat_v(vnode, n_stores);439 afs_put_wb_key(wbk);
424 atomic_long_add((last * PAGE_SIZE + to) -440 return -ENOMEM;
425 (first * PAGE_SIZE + offset),441 }
426 &afs_v2net(vnode)->n_store_bytes);442
427 break;443 afs_op_set_vnode(op, 0, vnode);
444 op->file[0].dv_delta = 1;
445 op->store.mapping = mapping;
446 op->store.first = first;
447 op->store.last = last;
448 op->store.first_offset = offset;
449 op->store.last_to = to;
450 op->ops = &afs_store_data_operation;
451
452try_next_key:
453 afs_begin_vnode_operation(op);
454 afs_wait_for_operation(op);
455
456 switch (op->error) {
428 case -EACCES:457 case -EACCES:
429 case -EPERM:458 case -EPERM:
430 case -ENOKEY:459 case -ENOKEY:
@@ -432,16 +461,19 @@ found_key: · 1 unmodified line
432 case -EKEYREJECTED:461 case -EKEYREJECTED:
433 case -EKEYREVOKED:462 case -EKEYREVOKED:
434 _debug("next");463 _debug("next");
435 spin_lock(&vnode->wb_lock);464
436 p = wbk->vnode_link.next;465 ret = afs_get_writeback_key(vnode, &wbk);
437 afs_put_wb_key(wbk);466 if (ret == 0) {
438 goto try_next_key;467 key_put(op->key);
468 op->key = key_get(wbk->key);
469 goto try_next_key;
470 }
471 break;
439 }472 }
440 473
441 afs_put_wb_key(wbk);474 afs_put_wb_key(wbk);
442 kfree(scb);475 _leave(" = %d", op->error);
443 _leave(" = %d", ret);476 return afs_put_operation(op);
444 return ret;
445}477}
446 478
447/*479/*
fs/afs/xattr.c+127−173
@@ -34,6 +34,25 @@ ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size) · 33 unmodified lines
34 return sizeof(afs_xattr_list);34 return sizeof(afs_xattr_list);
35}35}
36 36
37/*
38 * Deal with the result of a successful fetch ACL operation.
39 */
40static void afs_acl_success(struct afs_operation *op)
41{
42 afs_vnode_commit_status(op, &op->file[0]);
43}
44
45static void afs_acl_put(struct afs_operation *op)
46{
47 kfree(op->acl);
48}
49
50static 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
37/*56/*
38 * Get a file's ACL.57 * Get a file's ACL.
39 */58 */
@@ -42,37 +61,23 @@ static int afs_xattr_get_acl(const struct xattr_handler *handler, · 2 unmodified lines
42 struct inode *inode, const char *name,61 struct inode *inode, const char *name,
43 void *buffer, size_t size)62 void *buffer, size_t size)
44{63{
45 struct afs_fs_cursor fc;64 struct afs_operation *op;
46 struct afs_status_cb *scb;
47 struct afs_vnode *vnode = AFS_FS_I(inode);65 struct afs_vnode *vnode = AFS_FS_I(inode);
48 struct afs_acl *acl = NULL;66 struct afs_acl *acl = NULL;
49 struct key *key;67 int ret;
50 int ret = -ENOMEM;
51 68
52 scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS);69 op = afs_alloc_operation(NULL, vnode->volume);
53 if (!scb)70 if (IS_ERR(op))
54 goto error;71 return -ENOMEM;
55
56 key = afs_request_key(vnode->volume->cell);
57 if (IS_ERR(key)) {
58 ret = PTR_ERR(key);
59 goto error_scb;
60 }
61 72
62 ret = -ERESTARTSYS;73 afs_op_set_vnode(op, 0, vnode);
63 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {74 op->ops = &afs_fetch_acl_operation;
64 afs_dataversion_t data_version = vnode->status.data_version;
65
66 while (afs_select_fileserver(&fc)) {
67 fc.cb_break = afs_calc_vnode_cb_break(vnode);
68 acl = afs_fs_fetch_acl(&fc, scb);
69 }
70 75
71 afs_check_for_remote_deletion(&fc, fc.vnode);76 afs_begin_vnode_operation(op);
72 afs_vnode_commit_status(&fc, vnode, fc.cb_break,77 afs_wait_for_operation(op);
73 &data_version, scb);78 acl = op->acl;
74 ret = afs_end_vnode_operation(&fc);79 op->acl = NULL;
75 }80 ret = afs_put_operation(op);
76 81
77 if (ret == 0) {82 if (ret == 0) {
78 ret = acl->size;83 ret = acl->size;
@@ -80,18 +85,37 @@ static int afs_xattr_get_acl(const struct xattr_handler *handler, · 1 unmodified line
80 if (acl->size <= size)85 if (acl->size <= size)
81 memcpy(buffer, acl->data, acl->size);86 memcpy(buffer, acl->data, acl->size);
82 else87 else
83 ret = -ERANGE;88 op->error = -ERANGE;
84 }89 }
85 kfree(acl);
86 }90 }
87 91
88 key_put(key);92 kfree(acl);
89error_scb:
90 kfree(scb);
91error:
92 return ret;93 return ret;
93}94}
94 95
96static bool afs_make_acl(struct afs_operation *op,
97 const void *buffer, size_t size)
98{
99 struct afs_acl *acl;
100
101 acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
102 if (!acl) {
103 afs_op_nomem(op);
104 return false;
105 }
106
107 acl->size = size;
108 memcpy(acl->data, buffer, size);
109 op->acl = acl;
110 return true;
111}
112
113static const struct afs_operation_ops afs_store_acl_operation = {
114 .issue_afs_rpc = afs_fs_store_acl,
115 .success = afs_acl_success,
116 .put = afs_acl_put,
117};
118
95/*119/*
96 * Set a file's AFS3 ACL.120 * Set a file's AFS3 ACL.
97 */121 */
@@ -100,55 +124,22 @@ static int afs_xattr_set_acl(const struct xattr_handler *handler, · 2 unmodified lines
100 struct inode *inode, const char *name,124 struct inode *inode, const char *name,
101 const void *buffer, size_t size, int flags)125 const void *buffer, size_t size, int flags)
102{126{
103 struct afs_fs_cursor fc;127 struct afs_operation *op;
104 struct afs_status_cb *scb;
105 struct afs_vnode *vnode = AFS_FS_I(inode);128 struct afs_vnode *vnode = AFS_FS_I(inode);
106 struct afs_acl *acl = NULL;
107 struct key *key;
108 int ret = -ENOMEM;
109 129
110 if (flags == XATTR_CREATE)130 if (flags == XATTR_CREATE)
111 return -EINVAL;131 return -EINVAL;
112 132
113 scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS);133 op = afs_alloc_operation(NULL, vnode->volume);
114 if (!scb)134 if (IS_ERR(op))
115 goto error;135 return -ENOMEM;
116
117 acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
118 if (!acl)
119 goto error_scb;
120
121 key = afs_request_key(vnode->volume->cell);
122 if (IS_ERR(key)) {
123 ret = PTR_ERR(key);
124 goto error_acl;
125 }
126
127 acl->size = size;
128 memcpy(acl->data, buffer, size);
129
130 ret = -ERESTARTSYS;
131 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
132 afs_dataversion_t data_version = vnode->status.data_version;
133 136
134 while (afs_select_fileserver(&fc)) {137 afs_op_set_vnode(op, 0, vnode);
135 fc.cb_break = afs_calc_vnode_cb_break(vnode);138 if (!afs_make_acl(op, buffer, size))
136 afs_fs_store_acl(&fc, acl, scb);139 return afs_put_operation(op);
137 }
138 140
139 afs_check_for_remote_deletion(&fc, fc.vnode);141 op->ops = &afs_store_acl_operation;
140 afs_vnode_commit_status(&fc, vnode, fc.cb_break,142 return afs_do_sync_operation(op);
141 &data_version, scb);
142 ret = afs_end_vnode_operation(&fc);
143 }
144
145 key_put(key);
146error_acl:
147 kfree(acl);
148error_scb:
149 kfree(scb);
150error:
151 return ret;
152}143}
153 144
154static const struct xattr_handler afs_xattr_afs_acl_handler = {145static const struct xattr_handler afs_xattr_afs_acl_handler = {
@@ -157,6 +148,17 @@ static const struct xattr_handler afs_xattr_afs_acl_handler = { · 2 unmodified lines
157 .set = afs_xattr_set_acl,148 .set = afs_xattr_set_acl,
158};149};
159 150
151static void yfs_acl_put(struct afs_operation *op)
152{
153 yfs_free_opaque_acl(op->yacl);
154}
155
156static const struct afs_operation_ops yfs_fetch_opaque_acl_operation = {
157 .issue_yfs_rpc = yfs_fs_fetch_opaque_acl,
158 .success = afs_acl_success,
159 /* Don't free op->yacl in .put here */
160};
161
160/*162/*
161 * Get a file's YFS ACL.163 * Get a file's YFS ACL.
162 */164 */
@@ -165,11 +167,9 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, · 2 unmodified lines
165 struct inode *inode, const char *name,167 struct inode *inode, const char *name,
166 void *buffer, size_t size)168 void *buffer, size_t size)
167{169{
168 struct afs_fs_cursor fc;170 struct afs_operation *op;
169 struct afs_status_cb *scb;
170 struct afs_vnode *vnode = AFS_FS_I(inode);171 struct afs_vnode *vnode = AFS_FS_I(inode);
171 struct yfs_acl *yacl = NULL;172 struct yfs_acl *yacl = NULL;
172 struct key *key;
173 char buf[16], *data;173 char buf[16], *data;
174 int which = 0, dsize, ret = -ENOMEM;174 int which = 0, dsize, ret = -ENOMEM;
175 175
@@ -193,75 +193,62 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, · 17 unmodified lines
193 else if (which == 3)193 else if (which == 3)
194 yacl->flags |= YFS_ACL_WANT_VOL_ACL;194 yacl->flags |= YFS_ACL_WANT_VOL_ACL;
195 195
196 scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS);196 op = afs_alloc_operation(NULL, vnode->volume);
197 if (!scb)197 if (IS_ERR(op))
198 goto error_yacl;198 goto error_yacl;
199 199
200 key = afs_request_key(vnode->volume->cell);200 afs_op_set_vnode(op, 0, vnode);
201 if (IS_ERR(key)) {201 op->yacl = yacl;
202 ret = PTR_ERR(key);202 op->ops = &yfs_fetch_opaque_acl_operation;
203 goto error_scb;
204 }
205 203
206 ret = -ERESTARTSYS;204 afs_begin_vnode_operation(op);
207 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {205 afs_wait_for_operation(op);
208 afs_dataversion_t data_version = vnode->status.data_version;206 ret = afs_put_operation(op);
209 207
210 while (afs_select_fileserver(&fc)) {208 if (ret == 0) {
211 fc.cb_break = afs_calc_vnode_cb_break(vnode);209 switch (which) {
212 yfs_fs_fetch_opaque_acl(&fc, yacl, scb);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);231 ret = dsize;
216 afs_vnode_commit_status(&fc, vnode, fc.cb_break,232 if (size > 0) {
217 &data_version, scb);233 if (dsize <= size)
218 ret = afs_end_vnode_operation(&fc);234 memcpy(buffer, data, dsize);
219 }235 else
220 236 ret = -ERANGE;
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;
251 }237 }
252 memcpy(buffer, data, dsize);
253 }238 }
254 239
255error_key:
256 key_put(key);
257error_scb:
258 kfree(scb);
259error_yacl:240error_yacl:
260 yfs_free_opaque_acl(yacl);241 yfs_free_opaque_acl(yacl);
261error:242error:
262 return ret;243 return ret;
263}244}
264 245
246static 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};
251
265/*252/*
266 * Set a file's YFS ACL.253 * Set a file's YFS ACL.
267 */254 */
@@ -270,56 +257,23 @@ static int afs_xattr_set_yfs(const struct xattr_handler *handler, · 2 unmodified lines
270 struct inode *inode, const char *name,257 struct inode *inode, const char *name,
271 const void *buffer, size_t size, int flags)258 const void *buffer, size_t size, int flags)
272{259{
273 struct afs_fs_cursor fc;260 struct afs_operation *op;
274 struct afs_status_cb *scb;
275 struct afs_vnode *vnode = AFS_FS_I(inode);261 struct afs_vnode *vnode = AFS_FS_I(inode);
276 struct afs_acl *acl = NULL;
277 struct key *key;
278 int ret = -ENOMEM;
279 262
280 if (flags == XATTR_CREATE ||263 if (flags == XATTR_CREATE ||
281 strcmp(name, "acl") != 0)264 strcmp(name, "acl") != 0)
282 return -EINVAL;265 return -EINVAL;
283 266
284 scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS);267 op = afs_alloc_operation(NULL, vnode->volume);
285 if (!scb)268 if (IS_ERR(op))
286 goto error;269 return -ENOMEM;
287
288 acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
289 if (!acl)
290 goto error_scb;
291 270
292 acl->size = size;271 afs_op_set_vnode(op, 0, vnode);
293 memcpy(acl->data, buffer, size);272 if (!afs_make_acl(op, buffer, size))
273 return afs_put_operation(op);
294 274
295 key = afs_request_key(vnode->volume->cell);275 op->ops = &yfs_store_opaque_acl2_operation;
296 if (IS_ERR(key)) {276 return afs_do_sync_operation(op);
297 ret = PTR_ERR(key);
298 goto error_acl;
299 }
300
301 ret = -ERESTARTSYS;
302 if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
303 afs_dataversion_t data_version = vnode->status.data_version;
304
305 while (afs_select_fileserver(&fc)) {
306 fc.cb_break = afs_calc_vnode_cb_break(vnode);
307 yfs_fs_store_opaque_acl2(&fc, acl, scb);
308 }
309
310 afs_check_for_remote_deletion(&fc, fc.vnode);
311 afs_vnode_commit_status(&fc, vnode, fc.cb_break,
312 &data_version, scb);
313 ret = afs_end_vnode_operation(&fc);
314 }
315
316error_acl:
317 kfree(acl);
318 key_put(key);
319error_scb:
320 kfree(scb);
321error:
322 return ret;
323}277}
324 278
325static const struct xattr_handler afs_xattr_yfs_handler = {279static const struct xattr_handler afs_xattr_yfs_handler = {
fs/afs/yfsclient.c+375−539
@@ -17,11 +17,6 @@ · 16 unmodified lines
17 17
18static const struct afs_fid afs_zero_fid;18static const struct afs_fid afs_zero_fid;
19 19
20static 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#define xdr_size(x) (sizeof(*x) / sizeof(__be32))20#define xdr_size(x) (sizeof(*x) / sizeof(__be32))
26 21
27static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)22static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
@@ -79,6 +74,11 @@ static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len) · 51 unmodified lines
79 return bp + len / sizeof(__be32);74 return bp + len / sizeof(__be32);
80}75}
81 76
77static __be32 *xdr_encode_name(__be32 *bp, const struct qstr *p)
78{
79 return xdr_encode_string(bp, p->name, p->len);
80}
81
82static s64 linux_to_yfs_time(const struct timespec64 *t)82static s64 linux_to_yfs_time(const struct timespec64 *t)
83{83{
84 /* Convert to 100ns intervals. */84 /* Convert to 100ns intervals. */
@@ -179,21 +179,20 @@ static void xdr_dump_bad(const __be32 *bp) · 94 unmodified lines
179/*179/*
180 * Decode a YFSFetchStatus block180 * Decode a YFSFetchStatus block
181 */181 */
182static int xdr_decode_YFSFetchStatus(const __be32 **_bp,182static void xdr_decode_YFSFetchStatus(const __be32 **_bp,
183 struct afs_call *call,183 struct afs_call *call,
184 struct afs_status_cb *scb)184 struct afs_status_cb *scb)
185{185{
186 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;186 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
187 struct afs_file_status *status = &scb->status;187 struct afs_file_status *status = &scb->status;
188 u32 type;188 u32 type;
189 int ret;
190 189
191 status->abort_code = ntohl(xdr->abort_code);190 status->abort_code = ntohl(xdr->abort_code);
192 if (status->abort_code != 0) {191 if (status->abort_code != 0) {
193 if (status->abort_code == VNOVNODE)192 if (status->abort_code == VNOVNODE)
194 status->nlink = 0;193 status->nlink = 0;
195 scb->have_error = true;194 scb->have_error = true;
196 goto good;195 goto advance;
197 }196 }
198 197
199 type = ntohl(xdr->type);198 type = ntohl(xdr->type);
@@ -221,15 +220,13 @@ static int xdr_decode_YFSFetchStatus(const __be32 **_bp, · 21 unmodified lines
221 status->size = xdr_to_u64(xdr->size);220 status->size = xdr_to_u64(xdr->size);
222 status->data_version = xdr_to_u64(xdr->data_version);221 status->data_version = xdr_to_u64(xdr->data_version);
223 scb->have_status = true;222 scb->have_status = true;
224good:
225 ret = 0;
226advance:223advance:
227 *_bp += xdr_size(xdr);224 *_bp += xdr_size(xdr);
228 return ret;225 return;
229 226
230bad:227bad:
231 xdr_dump_bad(*_bp);228 xdr_dump_bad(*_bp);
232 ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);229 afs_protocol_error(call, afs_eproto_bad_status);
233 goto advance;230 goto advance;
234}231}
235 232
@@ -339,6 +336,7 @@ static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp, · 103 unmodified lines
339 */336 */
340static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call)337static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call)
341{338{
339 struct afs_operation *op = call->op;
342 const __be32 *bp;340 const __be32 *bp;
343 int ret;341 int ret;
344 342
@@ -348,11 +346,9 @@ static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call) · 3 unmodified lines
348 346
349 /* unmarshall the reply once we've received all of it */347 /* unmarshall the reply once we've received all of it */
350 bp = call->buffer;348 bp = call->buffer;
351 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);349 xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb);
352 if (ret < 0)350 xdr_decode_YFSCallBack(&bp, call, &op->file[0].scb);
353 return ret;351 xdr_decode_YFSVolSync(&bp, &op->volsync);
354 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
355 xdr_decode_YFSVolSync(&bp, call->out_volsync);
356 352
357 _leave(" = 0 [done]");353 _leave(" = 0 [done]");
358 return 0;354 return 0;
@@ -364,6 +360,7 @@ static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call) · 5 unmodified lines
364 */360 */
365static int yfs_deliver_status_and_volsync(struct afs_call *call)361static int yfs_deliver_status_and_volsync(struct afs_call *call)
366{362{
363 struct afs_operation *op = call->op;
367 const __be32 *bp;364 const __be32 *bp;
368 int ret;365 int ret;
369 366
@@ -372,10 +369,8 @@ static int yfs_deliver_status_and_volsync(struct afs_call *call) · 2 unmodified lines
372 return ret;369 return ret;
373 370
374 bp = call->buffer;371 bp = call->buffer;
375 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);372 xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb);
376 if (ret < 0)373 xdr_decode_YFSVolSync(&bp, &op->volsync);
377 return ret;
378 xdr_decode_YFSVolSync(&bp, call->out_volsync);
379 374
380 _leave(" = 0 [done]");375 _leave(" = 0 [done]");
381 return 0;376 return 0;
@@ -394,44 +389,33 @@ static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = { · 12 unmodified lines
394/*389/*
395 * Fetch the status information for a file.390 * Fetch the status information for a file.
396 */391 */
397int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb,392void yfs_fs_fetch_file_status(struct afs_operation *op)
398 struct afs_volsync *volsync)
399{393{
400 struct afs_vnode *vnode = fc->vnode;394 struct afs_vnode_param *vp = &op->file[0];
401 struct afs_call *call;395 struct afs_call *call;
402 struct afs_net *net = afs_v2net(vnode);
403 __be32 *bp;396 __be32 *bp;
404 397
405 _enter(",%x,{%llx:%llu},,",398 _enter(",%x,{%llx:%llu},,",
406 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);399 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
407 400
408 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode,401 call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus_vnode,
409 sizeof(__be32) * 2 +402 sizeof(__be32) * 2 +
410 sizeof(struct yfs_xdr_YFSFid),403 sizeof(struct yfs_xdr_YFSFid),
411 sizeof(struct yfs_xdr_YFSFetchStatus) +404 sizeof(struct yfs_xdr_YFSFetchStatus) +
412 sizeof(struct yfs_xdr_YFSCallBack) +405 sizeof(struct yfs_xdr_YFSCallBack) +
413 sizeof(struct yfs_xdr_YFSVolSync));406 sizeof(struct yfs_xdr_YFSVolSync));
414 if (!call) {407 if (!call)
415 fc->ac.error = -ENOMEM;408 return afs_op_nomem(op);
416 return -ENOMEM;
417 }
418
419 call->key = fc->key;
420 call->out_scb = scb;
421 call->out_volsync = volsync;
422 409
423 /* marshall the parameters */410 /* marshall the parameters */
424 bp = call->request;411 bp = call->request;
425 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);412 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
426 bp = xdr_encode_u32(bp, 0); /* RPC flags */413 bp = xdr_encode_u32(bp, 0); /* RPC flags */
427 bp = xdr_encode_YFSFid(bp, &vnode->fid);414 bp = xdr_encode_YFSFid(bp, &vp->fid);
428 yfs_check_req(call, bp);415 yfs_check_req(call, bp);
429 416
430 afs_use_fs_server(call, fc->cbi);417 trace_afs_make_fs_call(call, &vp->fid);
431 trace_afs_make_fs_call(call, &vnode->fid);418 afs_make_op_call(op, call, GFP_NOFS);
432 afs_set_fc_call(call, fc);
433 afs_make_call(&fc->ac, call, GFP_NOFS);
434 return afs_wait_for_call_to_complete(call, &fc->ac);
435}419}
436 420
437/*421/*
@@ -439,7 +423,9 @@ int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb · 1 unmodified line
439 */423 */
440static int yfs_deliver_fs_fetch_data64(struct afs_call *call)424static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
441{425{
442 struct afs_read *req = call->read_request;426 struct afs_operation *op = call->op;
427 struct afs_vnode_param *vp = &op->file[0];
428 struct afs_read *req = op->fetch.req;
443 const __be32 *bp;429 const __be32 *bp;
444 unsigned int size;430 unsigned int size;
445 int ret;431 int ret;
@@ -534,14 +520,12 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) · 88 unmodified lines
534 return ret;520 return ret;
535 521
536 bp = call->buffer;522 bp = call->buffer;
537 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);523 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
538 if (ret < 0)524 xdr_decode_YFSCallBack(&bp, call, &vp->scb);
539 return ret;525 xdr_decode_YFSVolSync(&bp, &op->volsync);
540 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
541 xdr_decode_YFSVolSync(&bp, call->out_volsync);
542 526
543 req->data_version = call->out_scb->status.data_version;527 req->data_version = vp->scb.status.data_version;
544 req->file_size = call->out_scb->status.size;528 req->file_size = vp->scb.status.size;
545 529
546 call->unmarshall++;530 call->unmarshall++;
547 /* Fall through */531 /* Fall through */
@@ -565,12 +549,6 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call) · 17 unmodified lines
565 return 0;549 return 0;
566}550}
567 551
568static void yfs_fetch_data_destructor(struct afs_call *call)
569{
570 afs_put_read(call->read_request);
571 afs_flat_call_destructor(call);
572}
573
574/*552/*
575 * YFS.FetchData64 operation type553 * YFS.FetchData64 operation type
576 */554 */
@@ -578,25 +556,24 @@ static const struct afs_call_type yfs_RXYFSFetchData64 = { · 1 unmodified line
578 .name = "YFS.FetchData64",556 .name = "YFS.FetchData64",
579 .op = yfs_FS_FetchData64,557 .op = yfs_FS_FetchData64,
580 .deliver = yfs_deliver_fs_fetch_data64,558 .deliver = yfs_deliver_fs_fetch_data64,
581 .destructor = yfs_fetch_data_destructor,559 .destructor = afs_flat_call_destructor,
582};560};
583 561
584/*562/*
585 * Fetch data from a file.563 * Fetch data from a file.
586 */564 */
587int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb,565void yfs_fs_fetch_data(struct afs_operation *op)
588 struct afs_read *req)
589{566{
590 struct afs_vnode *vnode = fc->vnode;567 struct afs_vnode_param *vp = &op->file[0];
568 struct afs_read *req = op->fetch.req;
591 struct afs_call *call;569 struct afs_call *call;
592 struct afs_net *net = afs_v2net(vnode);
593 __be32 *bp;570 __be32 *bp;
594 571
595 _enter(",%x,{%llx:%llu},%llx,%llx",572 _enter(",%x,{%llx:%llu},%llx,%llx",
596 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,573 key_serial(op->key), vp->fid.vid, vp->fid.vnode,
597 req->pos, req->len);574 req->pos, req->len);
598 575
599 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,576 call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchData64,
600 sizeof(__be32) * 2 +577 sizeof(__be32) * 2 +
601 sizeof(struct yfs_xdr_YFSFid) +578 sizeof(struct yfs_xdr_YFSFid) +
602 sizeof(struct yfs_xdr_u64) * 2,579 sizeof(struct yfs_xdr_u64) * 2,
@@ -604,27 +581,19 @@ int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb, · 1 unmodified line
604 sizeof(struct yfs_xdr_YFSCallBack) +581 sizeof(struct yfs_xdr_YFSCallBack) +
605 sizeof(struct yfs_xdr_YFSVolSync));582 sizeof(struct yfs_xdr_YFSVolSync));
606 if (!call)583 if (!call)
607 return -ENOMEM;584 return afs_op_nomem(op);
608
609 call->key = fc->key;
610 call->out_scb = scb;
611 call->out_volsync = NULL;
612 call->read_request = afs_get_read(req);
613 585
614 /* marshall the parameters */586 /* marshall the parameters */
615 bp = call->request;587 bp = call->request;
616 bp = xdr_encode_u32(bp, YFSFETCHDATA64);588 bp = xdr_encode_u32(bp, YFSFETCHDATA64);
617 bp = xdr_encode_u32(bp, 0); /* RPC flags */589 bp = xdr_encode_u32(bp, 0); /* RPC flags */
618 bp = xdr_encode_YFSFid(bp, &vnode->fid);590 bp = xdr_encode_YFSFid(bp, &vp->fid);
619 bp = xdr_encode_u64(bp, req->pos);591 bp = xdr_encode_u64(bp, req->pos);
620 bp = xdr_encode_u64(bp, req->len);592 bp = xdr_encode_u64(bp, req->len);
621 yfs_check_req(call, bp);593 yfs_check_req(call, bp);
622 594
623 afs_use_fs_server(call, fc->cbi);595 trace_afs_make_fs_call(call, &vp->fid);
624 trace_afs_make_fs_call(call, &vnode->fid);596 afs_make_op_call(op, call, GFP_NOFS);
625 afs_set_fc_call(call, fc);
626 afs_make_call(&fc->ac, call, GFP_NOFS);
627 return afs_wait_for_call_to_complete(call, &fc->ac);
628}597}
629 598
630/*599/*
@@ -632,6 +601,9 @@ int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb, · 1 unmodified line
632 */601 */
633static int yfs_deliver_fs_create_vnode(struct afs_call *call)602static int yfs_deliver_fs_create_vnode(struct afs_call *call)
634{603{
604 struct afs_operation *op = call->op;
605 struct afs_vnode_param *dvp = &op->file[0];
606 struct afs_vnode_param *vp = &op->file[1];
635 const __be32 *bp;607 const __be32 *bp;
636 int ret;608 int ret;
637 609
@@ -643,15 +615,11 @@ static int yfs_deliver_fs_create_vnode(struct afs_call *call) · 5 unmodified lines
643 615
644 /* unmarshall the reply once we've received all of it */616 /* unmarshall the reply once we've received all of it */
645 bp = call->buffer;617 bp = call->buffer;
646 xdr_decode_YFSFid(&bp, call->out_fid);618 xdr_decode_YFSFid(&bp, &op->file[1].fid);
647 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);619 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
648 if (ret < 0)620 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
649 return ret;621 xdr_decode_YFSCallBack(&bp, call, &vp->scb);
650 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);622 xdr_decode_YFSVolSync(&bp, &op->volsync);
651 if (ret < 0)
652 return ret;
653 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
654 xdr_decode_YFSVolSync(&bp, call->out_volsync);
655 623
656 _leave(" = 0 [done]");624 _leave(" = 0 [done]");
657 return 0;625 return 0;
@@ -670,26 +638,20 @@ static const struct afs_call_type afs_RXFSCreateFile = { · 12 unmodified lines
670/*638/*
671 * Create a file.639 * Create a file.
672 */640 */
673int yfs_fs_create_file(struct afs_fs_cursor *fc,641void yfs_fs_create_file(struct afs_operation *op)
674 const char *name,
675 umode_t mode,
676 struct afs_status_cb *dvnode_scb,
677 struct afs_fid *newfid,
678 struct afs_status_cb *new_scb)
679{642{
680 struct afs_vnode *dvnode = fc->vnode;643 const struct qstr *name = &op->dentry->d_name;
644 struct afs_vnode_param *dvp = &op->file[0];
681 struct afs_call *call;645 struct afs_call *call;
682 struct afs_net *net = afs_v2net(dvnode);646 size_t reqsz, rplsz;
683 size_t namesz, reqsz, rplsz;
684 __be32 *bp;647 __be32 *bp;
685 648
686 _enter("");649 _enter("");
687 650
688 namesz = strlen(name);
689 reqsz = (sizeof(__be32) +651 reqsz = (sizeof(__be32) +
690 sizeof(__be32) +652 sizeof(__be32) +
691 sizeof(struct yfs_xdr_YFSFid) +653 sizeof(struct yfs_xdr_YFSFid) +
692 xdr_strlen(namesz) +654 xdr_strlen(name->len) +
693 sizeof(struct yfs_xdr_YFSStoreStatus) +655 sizeof(struct yfs_xdr_YFSStoreStatus) +
694 sizeof(__be32));656 sizeof(__be32));
695 rplsz = (sizeof(struct yfs_xdr_YFSFid) +657 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
@@ -698,30 +660,22 @@ int yfs_fs_create_file(struct afs_fs_cursor *fc, · 2 unmodified lines
698 sizeof(struct yfs_xdr_YFSCallBack) +660 sizeof(struct yfs_xdr_YFSCallBack) +
699 sizeof(struct yfs_xdr_YFSVolSync));661 sizeof(struct yfs_xdr_YFSVolSync));
700 662
701 call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);663 call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, reqsz, rplsz);
702 if (!call)664 if (!call)
703 return -ENOMEM;665 return afs_op_nomem(op);
704
705 call->key = fc->key;
706 call->out_dir_scb = dvnode_scb;
707 call->out_fid = newfid;
708 call->out_scb = new_scb;
709 666
710 /* marshall the parameters */667 /* marshall the parameters */
711 bp = call->request;668 bp = call->request;
712 bp = xdr_encode_u32(bp, YFSCREATEFILE);669 bp = xdr_encode_u32(bp, YFSCREATEFILE);
713 bp = xdr_encode_u32(bp, 0); /* RPC flags */670 bp = xdr_encode_u32(bp, 0); /* RPC flags */
714 bp = xdr_encode_YFSFid(bp, &dvnode->fid);671 bp = xdr_encode_YFSFid(bp, &dvp->fid);
715 bp = xdr_encode_string(bp, name, namesz);672 bp = xdr_encode_name(bp, name);
716 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);673 bp = xdr_encode_YFSStoreStatus_mode(bp, op->create.mode);
717 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */674 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
718 yfs_check_req(call, bp);675 yfs_check_req(call, bp);
719 676
720 afs_use_fs_server(call, fc->cbi);677 trace_afs_make_fs_call1(call, &dvp->fid, name);
721 trace_afs_make_fs_call1(call, &dvnode->fid, name);678 afs_make_op_call(op, call, GFP_NOFS);
722 afs_set_fc_call(call, fc);
723 afs_make_call(&fc->ac, call, GFP_NOFS);
724 return afs_wait_for_call_to_complete(call, &fc->ac);
725}679}
726 680
727static const struct afs_call_type yfs_RXFSMakeDir = {681static const struct afs_call_type yfs_RXFSMakeDir = {
@@ -734,26 +688,20 @@ static const struct afs_call_type yfs_RXFSMakeDir = { · 6 unmodified lines
734/*688/*
735 * Make a directory.689 * Make a directory.
736 */690 */
737int yfs_fs_make_dir(struct afs_fs_cursor *fc,691void yfs_fs_make_dir(struct afs_operation *op)
738 const char *name,
739 umode_t mode,
740 struct afs_status_cb *dvnode_scb,
741 struct afs_fid *newfid,
742 struct afs_status_cb *new_scb)
743{692{
744 struct afs_vnode *dvnode = fc->vnode;693 const struct qstr *name = &op->dentry->d_name;
694 struct afs_vnode_param *dvp = &op->file[0];
745 struct afs_call *call;695 struct afs_call *call;
746 struct afs_net *net = afs_v2net(dvnode);696 size_t reqsz, rplsz;
747 size_t namesz, reqsz, rplsz;
748 __be32 *bp;697 __be32 *bp;
749 698
750 _enter("");699 _enter("");
751 700
752 namesz = strlen(name);
753 reqsz = (sizeof(__be32) +701 reqsz = (sizeof(__be32) +
754 sizeof(struct yfs_xdr_RPCFlags) +702 sizeof(struct yfs_xdr_RPCFlags) +
755 sizeof(struct yfs_xdr_YFSFid) +703 sizeof(struct yfs_xdr_YFSFid) +
756 xdr_strlen(namesz) +704 xdr_strlen(name->len) +
757 sizeof(struct yfs_xdr_YFSStoreStatus));705 sizeof(struct yfs_xdr_YFSStoreStatus));
758 rplsz = (sizeof(struct yfs_xdr_YFSFid) +706 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
759 sizeof(struct yfs_xdr_YFSFetchStatus) +707 sizeof(struct yfs_xdr_YFSFetchStatus) +
@@ -761,29 +709,21 @@ int yfs_fs_make_dir(struct afs_fs_cursor *fc, · 1 unmodified line
761 sizeof(struct yfs_xdr_YFSCallBack) +709 sizeof(struct yfs_xdr_YFSCallBack) +
762 sizeof(struct yfs_xdr_YFSVolSync));710 sizeof(struct yfs_xdr_YFSVolSync));
763 711
764 call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);712 call = afs_alloc_flat_call(op->net, &yfs_RXFSMakeDir, reqsz, rplsz);
765 if (!call)713 if (!call)
766 return -ENOMEM;714 return afs_op_nomem(op);
767
768 call->key = fc->key;
769 call->out_dir_scb = dvnode_scb;
770 call->out_fid = newfid;
771 call->out_scb = new_scb;
772 715
773 /* marshall the parameters */716 /* marshall the parameters */
774 bp = call->request;717 bp = call->request;
775 bp = xdr_encode_u32(bp, YFSMAKEDIR);718 bp = xdr_encode_u32(bp, YFSMAKEDIR);
776 bp = xdr_encode_u32(bp, 0); /* RPC flags */719 bp = xdr_encode_u32(bp, 0); /* RPC flags */
777 bp = xdr_encode_YFSFid(bp, &dvnode->fid);720 bp = xdr_encode_YFSFid(bp, &dvp->fid);
778 bp = xdr_encode_string(bp, name, namesz);721 bp = xdr_encode_name(bp, name);
779 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);722 bp = xdr_encode_YFSStoreStatus_mode(bp, op->create.mode);
780 yfs_check_req(call, bp);723 yfs_check_req(call, bp);
781 724
782 afs_use_fs_server(call, fc->cbi);725 trace_afs_make_fs_call1(call, &dvp->fid, name);
783 trace_afs_make_fs_call1(call, &dvnode->fid, name);726 afs_make_op_call(op, call, GFP_NOFS);
784 afs_set_fc_call(call, fc);
785 afs_make_call(&fc->ac, call, GFP_NOFS);
786 return afs_wait_for_call_to_complete(call, &fc->ac);
787}727}
788 728
789/*729/*
@@ -791,6 +731,9 @@ int yfs_fs_make_dir(struct afs_fs_cursor *fc, · 1 unmodified line
791 */731 */
792static int yfs_deliver_fs_remove_file2(struct afs_call *call)732static int yfs_deliver_fs_remove_file2(struct afs_call *call)
793{733{
734 struct afs_operation *op = call->op;
735 struct afs_vnode_param *dvp = &op->file[0];
736 struct afs_vnode_param *vp = &op->file[1];
794 struct afs_fid fid;737 struct afs_fid fid;
795 const __be32 *bp;738 const __be32 *bp;
796 int ret;739 int ret;
@@ -802,20 +745,24 @@ static int yfs_deliver_fs_remove_file2(struct afs_call *call) · 5 unmodified lines
802 return ret;745 return ret;
803 746
804 bp = call->buffer;747 bp = call->buffer;
805 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);748 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
806 if (ret < 0)
807 return ret;
808
809 xdr_decode_YFSFid(&bp, &fid);749 xdr_decode_YFSFid(&bp, &fid);
810 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);750 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
811 if (ret < 0)
812 return ret;
813 /* Was deleted if vnode->status.abort_code == VNOVNODE. */751 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
814 752
815 xdr_decode_YFSVolSync(&bp, call->out_volsync);753 xdr_decode_YFSVolSync(&bp, &op->volsync);
816 return 0;754 return 0;
817}755}
818 756
757static void yfs_done_fs_remove_file2(struct afs_call *call)
758{
759 if (call->error == -ECONNABORTED &&
760 call->abort_code == RX_INVALID_OPERATION) {
761 set_bit(AFS_SERVER_FL_NO_RM2, &call->server->flags);
762 call->op->flags |= AFS_OPERATION_DOWNGRADE;
763 }
764}
765
819/*766/*
820 * YFS.RemoveFile2 operation type.767 * YFS.RemoveFile2 operation type.
821 */768 */
@@ -823,55 +770,44 @@ static const struct afs_call_type yfs_RXYFSRemoveFile2 = { · 1 unmodified line
823 .name = "YFS.RemoveFile2",770 .name = "YFS.RemoveFile2",
824 .op = yfs_FS_RemoveFile2,771 .op = yfs_FS_RemoveFile2,
825 .deliver = yfs_deliver_fs_remove_file2,772 .deliver = yfs_deliver_fs_remove_file2,
773 .done = yfs_done_fs_remove_file2,
826 .destructor = afs_flat_call_destructor,774 .destructor = afs_flat_call_destructor,
827};775};
828 776
829/*777/*
830 * Remove a file and retrieve new file status.778 * Remove a file and retrieve new file status.
831 */779 */
832int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,780void yfs_fs_remove_file2(struct afs_operation *op)
833 const char *name, struct afs_status_cb *dvnode_scb,
834 struct afs_status_cb *vnode_scb)
835{781{
836 struct afs_vnode *dvnode = fc->vnode;782 struct afs_vnode_param *dvp = &op->file[0];
783 const struct qstr *name = &op->dentry->d_name;
837 struct afs_call *call;784 struct afs_call *call;
838 struct afs_net *net = afs_v2net(dvnode);
839 size_t namesz;
840 __be32 *bp;785 __be32 *bp;
841 786
842 _enter("");787 _enter("");
843 788
844 namesz = strlen(name);789 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile2,
845
846 call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
847 sizeof(__be32) +790 sizeof(__be32) +
848 sizeof(struct yfs_xdr_RPCFlags) +791 sizeof(struct yfs_xdr_RPCFlags) +
849 sizeof(struct yfs_xdr_YFSFid) +792 sizeof(struct yfs_xdr_YFSFid) +
850 xdr_strlen(namesz),793 xdr_strlen(name->len),
851 sizeof(struct yfs_xdr_YFSFetchStatus) +794 sizeof(struct yfs_xdr_YFSFetchStatus) +
852 sizeof(struct yfs_xdr_YFSFid) +795 sizeof(struct yfs_xdr_YFSFid) +
853 sizeof(struct yfs_xdr_YFSFetchStatus) +796 sizeof(struct yfs_xdr_YFSFetchStatus) +
854 sizeof(struct yfs_xdr_YFSVolSync));797 sizeof(struct yfs_xdr_YFSVolSync));
855 if (!call)798 if (!call)
856 return -ENOMEM;799 return afs_op_nomem(op);
857
858 call->key = fc->key;
859 call->out_dir_scb = dvnode_scb;
860 call->out_scb = vnode_scb;
861 800
862 /* marshall the parameters */801 /* marshall the parameters */
863 bp = call->request;802 bp = call->request;
864 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);803 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
865 bp = xdr_encode_u32(bp, 0); /* RPC flags */804 bp = xdr_encode_u32(bp, 0); /* RPC flags */
866 bp = xdr_encode_YFSFid(bp, &dvnode->fid);805 bp = xdr_encode_YFSFid(bp, &dvp->fid);
867 bp = xdr_encode_string(bp, name, namesz);806 bp = xdr_encode_name(bp, name);
868 yfs_check_req(call, bp);807 yfs_check_req(call, bp);
869 808
870 afs_use_fs_server(call, fc->cbi);809 trace_afs_make_fs_call1(call, &dvp->fid, name);
871 trace_afs_make_fs_call1(call, &dvnode->fid, name);810 afs_make_op_call(op, call, GFP_NOFS);
872 afs_set_fc_call(call, fc);
873 afs_make_call(&fc->ac, call, GFP_NOFS);
874 return afs_wait_for_call_to_complete(call, &fc->ac);
875}811}
876 812
877/*813/*
@@ -879,6 +815,8 @@ int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode, · 1 unmodified line
879 */815 */
880static int yfs_deliver_fs_remove(struct afs_call *call)816static int yfs_deliver_fs_remove(struct afs_call *call)
881{817{
818 struct afs_operation *op = call->op;
819 struct afs_vnode_param *dvp = &op->file[0];
882 const __be32 *bp;820 const __be32 *bp;
883 int ret;821 int ret;
884 822
@@ -889,11 +827,8 @@ static int yfs_deliver_fs_remove(struct afs_call *call) · 4 unmodified lines
889 return ret;827 return ret;
890 828
891 bp = call->buffer;829 bp = call->buffer;
892 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);830 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
893 if (ret < 0)831 xdr_decode_YFSVolSync(&bp, &op->volsync);
894 return ret;
895
896 xdr_decode_YFSVolSync(&bp, call->out_volsync);
897 return 0;832 return 0;
898}833}
899 834
@@ -907,6 +842,43 @@ static const struct afs_call_type yfs_RXYFSRemoveFile = { · 7 unmodified lines
907 .destructor = afs_flat_call_destructor,842 .destructor = afs_flat_call_destructor,
908};843};
909 844
845/*
846 * Remove a file.
847 */
848void yfs_fs_remove_file(struct afs_operation *op)
849{
850 const struct qstr *name = &op->dentry->d_name;
851 struct afs_vnode_param *dvp = &op->file[0];
852 struct afs_call *call;
853 __be32 *bp;
854
855 _enter("");
856
857 if (!test_bit(AFS_SERVER_FL_NO_RM2, &op->server->flags))
858 return yfs_fs_remove_file2(op);
859
860 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile,
861 sizeof(__be32) +
862 sizeof(struct yfs_xdr_RPCFlags) +
863 sizeof(struct yfs_xdr_YFSFid) +
864 xdr_strlen(name->len),
865 sizeof(struct yfs_xdr_YFSFetchStatus) +
866 sizeof(struct yfs_xdr_YFSVolSync));
867 if (!call)
868 return afs_op_nomem(op);
869
870 /* marshall the parameters */
871 bp = call->request;
872 bp = xdr_encode_u32(bp, YFSREMOVEFILE);
873 bp = xdr_encode_u32(bp, 0); /* RPC flags */
874 bp = xdr_encode_YFSFid(bp, &dvp->fid);
875 bp = xdr_encode_name(bp, name);
876 yfs_check_req(call, bp);
877
878 trace_afs_make_fs_call1(call, &dvp->fid, name);
879 afs_make_op_call(op, call, GFP_NOFS);
880}
881
910static const struct afs_call_type yfs_RXYFSRemoveDir = {882static const struct afs_call_type yfs_RXYFSRemoveDir = {
911 .name = "YFS.RemoveDir",883 .name = "YFS.RemoveDir",
912 .op = yfs_FS_RemoveDir,884 .op = yfs_FS_RemoveDir,
@@ -915,48 +887,37 @@ static const struct afs_call_type yfs_RXYFSRemoveDir = { · 2 unmodified lines
915};887};
916 888
917/*889/*
918 * remove a file or directory890 * Remove a directory.
919 */891 */
920int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,892void yfs_fs_remove_dir(struct afs_operation *op)
921 const char *name, bool isdir,
922 struct afs_status_cb *dvnode_scb)
923{893{
924 struct afs_vnode *dvnode = fc->vnode;894 const struct qstr *name = &op->dentry->d_name;
895 struct afs_vnode_param *dvp = &op->file[0];
925 struct afs_call *call;896 struct afs_call *call;
926 struct afs_net *net = afs_v2net(dvnode);
927 size_t namesz;
928 __be32 *bp;897 __be32 *bp;
929 898
930 _enter("");899 _enter("");
931 900
932 namesz = strlen(name);901 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveDir,
933 call = afs_alloc_flat_call(902 sizeof(__be32) +
934 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,903 sizeof(struct yfs_xdr_RPCFlags) +
935 sizeof(__be32) +904 sizeof(struct yfs_xdr_YFSFid) +
936 sizeof(struct yfs_xdr_RPCFlags) +905 xdr_strlen(name->len),
937 sizeof(struct yfs_xdr_YFSFid) +906 sizeof(struct yfs_xdr_YFSFetchStatus) +
938 xdr_strlen(namesz),907 sizeof(struct yfs_xdr_YFSVolSync));
939 sizeof(struct yfs_xdr_YFSFetchStatus) +
940 sizeof(struct yfs_xdr_YFSVolSync));
941 if (!call)908 if (!call)
942 return -ENOMEM;909 return afs_op_nomem(op);
943
944 call->key = fc->key;
945 call->out_dir_scb = dvnode_scb;
946 910
947 /* marshall the parameters */911 /* marshall the parameters */
948 bp = call->request;912 bp = call->request;
949 bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);913 bp = xdr_encode_u32(bp, YFSREMOVEDIR);
950 bp = xdr_encode_u32(bp, 0); /* RPC flags */914 bp = xdr_encode_u32(bp, 0); /* RPC flags */
951 bp = xdr_encode_YFSFid(bp, &dvnode->fid);915 bp = xdr_encode_YFSFid(bp, &dvp->fid);
952 bp = xdr_encode_string(bp, name, namesz);916 bp = xdr_encode_name(bp, name);
953 yfs_check_req(call, bp);917 yfs_check_req(call, bp);
954 918
955 afs_use_fs_server(call, fc->cbi);919 trace_afs_make_fs_call1(call, &dvp->fid, name);
956 trace_afs_make_fs_call1(call, &dvnode->fid, name);920 afs_make_op_call(op, call, GFP_NOFS);
957 afs_set_fc_call(call, fc);
958 afs_make_call(&fc->ac, call, GFP_NOFS);
959 return afs_wait_for_call_to_complete(call, &fc->ac);
960}921}
961 922
962/*923/*
@@ -964,6 +925,9 @@ int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, · 1 unmodified line
964 */925 */
965static int yfs_deliver_fs_link(struct afs_call *call)926static int yfs_deliver_fs_link(struct afs_call *call)
966{927{
928 struct afs_operation *op = call->op;
929 struct afs_vnode_param *dvp = &op->file[0];
930 struct afs_vnode_param *vp = &op->file[1];
967 const __be32 *bp;931 const __be32 *bp;
968 int ret;932 int ret;
969 933
@@ -974,13 +938,9 @@ static int yfs_deliver_fs_link(struct afs_call *call) · 4 unmodified lines
974 return ret;938 return ret;
975 939
976 bp = call->buffer;940 bp = call->buffer;
977 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);941 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
978 if (ret < 0)942 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
979 return ret;943 xdr_decode_YFSVolSync(&bp, &op->volsync);
980 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
981 if (ret < 0)
982 return ret;
983 xdr_decode_YFSVolSync(&bp, call->out_volsync);
984 _leave(" = 0 [done]");944 _leave(" = 0 [done]");
985 return 0;945 return 0;
986}946}
@@ -998,50 +958,39 @@ static const struct afs_call_type yfs_RXYFSLink = { · 11 unmodified lines
998/*958/*
999 * Make a hard link.959 * Make a hard link.
1000 */960 */
1001int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,961void yfs_fs_link(struct afs_operation *op)
1002 const char *name,
1003 struct afs_status_cb *dvnode_scb,
1004 struct afs_status_cb *vnode_scb)
1005{962{
1006 struct afs_vnode *dvnode = fc->vnode;963 const struct qstr *name = &op->dentry->d_name;
964 struct afs_vnode_param *dvp = &op->file[0];
965 struct afs_vnode_param *vp = &op->file[1];
1007 struct afs_call *call;966 struct afs_call *call;
1008 struct afs_net *net = afs_v2net(vnode);
1009 size_t namesz;
1010 __be32 *bp;967 __be32 *bp;
1011 968
1012 _enter("");969 _enter("");
1013 970
1014 namesz = strlen(name);971 call = afs_alloc_flat_call(op->net, &yfs_RXYFSLink,
1015 call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1016 sizeof(__be32) +972 sizeof(__be32) +
1017 sizeof(struct yfs_xdr_RPCFlags) +973 sizeof(struct yfs_xdr_RPCFlags) +
1018 sizeof(struct yfs_xdr_YFSFid) +974 sizeof(struct yfs_xdr_YFSFid) +
1019 xdr_strlen(namesz) +975 xdr_strlen(name->len) +
1020 sizeof(struct yfs_xdr_YFSFid),976 sizeof(struct yfs_xdr_YFSFid),
1021 sizeof(struct yfs_xdr_YFSFetchStatus) +977 sizeof(struct yfs_xdr_YFSFetchStatus) +
1022 sizeof(struct yfs_xdr_YFSFetchStatus) +978 sizeof(struct yfs_xdr_YFSFetchStatus) +
1023 sizeof(struct yfs_xdr_YFSVolSync));979 sizeof(struct yfs_xdr_YFSVolSync));
1024 if (!call)980 if (!call)
1025 return -ENOMEM;981 return afs_op_nomem(op);
1026
1027 call->key = fc->key;
1028 call->out_dir_scb = dvnode_scb;
1029 call->out_scb = vnode_scb;
1030 982
1031 /* marshall the parameters */983 /* marshall the parameters */
1032 bp = call->request;984 bp = call->request;
1033 bp = xdr_encode_u32(bp, YFSLINK);985 bp = xdr_encode_u32(bp, YFSLINK);
1034 bp = xdr_encode_u32(bp, 0); /* RPC flags */986 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1035 bp = xdr_encode_YFSFid(bp, &dvnode->fid);987 bp = xdr_encode_YFSFid(bp, &dvp->fid);
1036 bp = xdr_encode_string(bp, name, namesz);988 bp = xdr_encode_name(bp, name);
1037 bp = xdr_encode_YFSFid(bp, &vnode->fid);989 bp = xdr_encode_YFSFid(bp, &vp->fid);
1038 yfs_check_req(call, bp);990 yfs_check_req(call, bp);
1039 991
1040 afs_use_fs_server(call, fc->cbi);992 trace_afs_make_fs_call1(call, &vp->fid, name);
1041 trace_afs_make_fs_call1(call, &vnode->fid, name);993 afs_make_op_call(op, call, GFP_NOFS);
1042 afs_set_fc_call(call, fc);
1043 afs_make_call(&fc->ac, call, GFP_NOFS);
1044 return afs_wait_for_call_to_complete(call, &fc->ac);
1045}994}
1046 995
1047/*996/*
@@ -1049,6 +998,9 @@ int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, · 1 unmodified line
1049 */998 */
1050static int yfs_deliver_fs_symlink(struct afs_call *call)999static int yfs_deliver_fs_symlink(struct afs_call *call)
1051{1000{
1001 struct afs_operation *op = call->op;
1002 struct afs_vnode_param *dvp = &op->file[0];
1003 struct afs_vnode_param *vp = &op->file[1];
1052 const __be32 *bp;1004 const __be32 *bp;
1053 int ret;1005 int ret;
1054 1006
@@ -1060,14 +1012,10 @@ static int yfs_deliver_fs_symlink(struct afs_call *call) · 5 unmodified lines
1060 1012
1061 /* unmarshall the reply once we've received all of it */1013 /* unmarshall the reply once we've received all of it */
1062 bp = call->buffer;1014 bp = call->buffer;
1063 xdr_decode_YFSFid(&bp, call->out_fid);1015 xdr_decode_YFSFid(&bp, &vp->fid);
1064 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);1016 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
1065 if (ret < 0)1017 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
1066 return ret;1018 xdr_decode_YFSVolSync(&bp, &op->volsync);
1067 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1068 if (ret < 0)
1069 return ret;
1070 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1071 1019
1072 _leave(" = 0 [done]");1020 _leave(" = 0 [done]");
1073 return 0;1021 return 0;
@@ -1086,28 +1034,22 @@ static const struct afs_call_type yfs_RXYFSSymlink = { · 12 unmodified lines
1086/*1034/*
1087 * Create a symbolic link.1035 * Create a symbolic link.
1088 */1036 */
1089int yfs_fs_symlink(struct afs_fs_cursor *fc,1037void yfs_fs_symlink(struct afs_operation *op)
1090 const char *name,
1091 const char *contents,
1092 struct afs_status_cb *dvnode_scb,
1093 struct afs_fid *newfid,
1094 struct afs_status_cb *vnode_scb)
1095{1038{
1096 struct afs_vnode *dvnode = fc->vnode;1039 const struct qstr *name = &op->dentry->d_name;
1040 struct afs_vnode_param *dvp = &op->file[0];
1097 struct afs_call *call;1041 struct afs_call *call;
1098 struct afs_net *net = afs_v2net(dvnode);1042 size_t contents_sz;
1099 size_t namesz, contents_sz;
1100 __be32 *bp;1043 __be32 *bp;
1101 1044
1102 _enter("");1045 _enter("");
1103 1046
1104 namesz = strlen(name);1047 contents_sz = strlen(op->create.symlink);
1105 contents_sz = strlen(contents);1048 call = afs_alloc_flat_call(op->net, &yfs_RXYFSSymlink,
1106 call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1107 sizeof(__be32) +1049 sizeof(__be32) +
1108 sizeof(struct yfs_xdr_RPCFlags) +1050 sizeof(struct yfs_xdr_RPCFlags) +
1109 sizeof(struct yfs_xdr_YFSFid) +1051 sizeof(struct yfs_xdr_YFSFid) +
1110 xdr_strlen(namesz) +1052 xdr_strlen(name->len) +
1111 xdr_strlen(contents_sz) +1053 xdr_strlen(contents_sz) +
1112 sizeof(struct yfs_xdr_YFSStoreStatus),1054 sizeof(struct yfs_xdr_YFSStoreStatus),
1113 sizeof(struct yfs_xdr_YFSFid) +1055 sizeof(struct yfs_xdr_YFSFid) +
@@ -1115,28 +1057,20 @@ int yfs_fs_symlink(struct afs_fs_cursor *fc, · 1 unmodified line
1115 sizeof(struct yfs_xdr_YFSFetchStatus) +1057 sizeof(struct yfs_xdr_YFSFetchStatus) +
1116 sizeof(struct yfs_xdr_YFSVolSync));1058 sizeof(struct yfs_xdr_YFSVolSync));
1117 if (!call)1059 if (!call)
1118 return -ENOMEM;1060 return afs_op_nomem(op);
1119
1120 call->key = fc->key;
1121 call->out_dir_scb = dvnode_scb;
1122 call->out_fid = newfid;
1123 call->out_scb = vnode_scb;
1124 1061
1125 /* marshall the parameters */1062 /* marshall the parameters */
1126 bp = call->request;1063 bp = call->request;
1127 bp = xdr_encode_u32(bp, YFSSYMLINK);1064 bp = xdr_encode_u32(bp, YFSSYMLINK);
1128 bp = xdr_encode_u32(bp, 0); /* RPC flags */1065 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1129 bp = xdr_encode_YFSFid(bp, &dvnode->fid);1066 bp = xdr_encode_YFSFid(bp, &dvp->fid);
1130 bp = xdr_encode_string(bp, name, namesz);1067 bp = xdr_encode_name(bp, name);
1131 bp = xdr_encode_string(bp, contents, contents_sz);1068 bp = xdr_encode_string(bp, op->create.symlink, contents_sz);
1132 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);1069 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1133 yfs_check_req(call, bp);1070 yfs_check_req(call, bp);
1134 1071
1135 afs_use_fs_server(call, fc->cbi);1072 trace_afs_make_fs_call1(call, &dvp->fid, name);
1136 trace_afs_make_fs_call1(call, &dvnode->fid, name);1073 afs_make_op_call(op, call, GFP_NOFS);
1137 afs_set_fc_call(call, fc);
1138 afs_make_call(&fc->ac, call, GFP_NOFS);
1139 return afs_wait_for_call_to_complete(call, &fc->ac);
1140}1074}
1141 1075
1142/*1076/*
@@ -1144,6 +1078,9 @@ int yfs_fs_symlink(struct afs_fs_cursor *fc, · 1 unmodified line
1144 */1078 */
1145static int yfs_deliver_fs_rename(struct afs_call *call)1079static int yfs_deliver_fs_rename(struct afs_call *call)
1146{1080{
1081 struct afs_operation *op = call->op;
1082 struct afs_vnode_param *orig_dvp = &op->file[0];
1083 struct afs_vnode_param *new_dvp = &op->file[1];
1147 const __be32 *bp;1084 const __be32 *bp;
1148 int ret;1085 int ret;
1149 1086
@@ -1154,14 +1091,12 @@ static int yfs_deliver_fs_rename(struct afs_call *call) · 4 unmodified lines
1154 return ret;1091 return ret;
1155 1092
1156 bp = call->buffer;1093 bp = call->buffer;
1157 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);1094 /* If the two dirs are the same, we have two copies of the same status
1158 if (ret < 0)1095 * report, so we just decode it twice.
1159 return ret;1096 */
1160 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);1097 xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1161 if (ret < 0)1098 xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1162 return ret;1099 xdr_decode_YFSVolSync(&bp, &op->volsync);
1163
1164 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1165 _leave(" = 0 [done]");1100 _leave(" = 0 [done]");
1166 return 0;1101 return 0;
1167}1102}
@@ -1179,55 +1114,42 @@ static const struct afs_call_type yfs_RXYFSRename = { · 11 unmodified lines
1179/*1114/*
1180 * Rename a file or directory.1115 * Rename a file or directory.
1181 */1116 */
1182int yfs_fs_rename(struct afs_fs_cursor *fc,1117void yfs_fs_rename(struct afs_operation *op)
1183 const char *orig_name,
1184 struct afs_vnode *new_dvnode,
1185 const char *new_name,
1186 struct afs_status_cb *orig_dvnode_scb,
1187 struct afs_status_cb *new_dvnode_scb)
1188{1118{
1189 struct afs_vnode *orig_dvnode = fc->vnode;1119 struct afs_vnode_param *orig_dvp = &op->file[0];
1120 struct afs_vnode_param *new_dvp = &op->file[1];
1121 const struct qstr *orig_name = &op->dentry->d_name;
1122 const struct qstr *new_name = &op->dentry_2->d_name;
1190 struct afs_call *call;1123 struct afs_call *call;
1191 struct afs_net *net = afs_v2net(orig_dvnode);
1192 size_t o_namesz, n_namesz;
1193 __be32 *bp;1124 __be32 *bp;
1194 1125
1195 _enter("");1126 _enter("");
1196 1127
1197 o_namesz = strlen(orig_name);1128 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename,
1198 n_namesz = strlen(new_name);
1199 call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1200 sizeof(__be32) +1129 sizeof(__be32) +
1201 sizeof(struct yfs_xdr_RPCFlags) +1130 sizeof(struct yfs_xdr_RPCFlags) +
1202 sizeof(struct yfs_xdr_YFSFid) +1131 sizeof(struct yfs_xdr_YFSFid) +
1203 xdr_strlen(o_namesz) +1132 xdr_strlen(orig_name->len) +
1204 sizeof(struct yfs_xdr_YFSFid) +1133 sizeof(struct yfs_xdr_YFSFid) +
1205 xdr_strlen(n_namesz),1134 xdr_strlen(new_name->len),
1206 sizeof(struct yfs_xdr_YFSFetchStatus) +1135 sizeof(struct yfs_xdr_YFSFetchStatus) +
1207 sizeof(struct yfs_xdr_YFSFetchStatus) +1136 sizeof(struct yfs_xdr_YFSFetchStatus) +
1208 sizeof(struct yfs_xdr_YFSVolSync));1137 sizeof(struct yfs_xdr_YFSVolSync));
1209 if (!call)1138 if (!call)
1210 return -ENOMEM;1139 return afs_op_nomem(op);
1211
1212 call->key = fc->key;
1213 call->out_dir_scb = orig_dvnode_scb;
1214 call->out_scb = new_dvnode_scb;
1215 1140
1216 /* marshall the parameters */1141 /* marshall the parameters */
1217 bp = call->request;1142 bp = call->request;
1218 bp = xdr_encode_u32(bp, YFSRENAME);1143 bp = xdr_encode_u32(bp, YFSRENAME);
1219 bp = xdr_encode_u32(bp, 0); /* RPC flags */1144 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1220 bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);1145 bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1221 bp = xdr_encode_string(bp, orig_name, o_namesz);1146 bp = xdr_encode_name(bp, orig_name);
1222 bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);1147 bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1223 bp = xdr_encode_string(bp, new_name, n_namesz);1148 bp = xdr_encode_name(bp, new_name);
1224 yfs_check_req(call, bp);1149 yfs_check_req(call, bp);
1225 1150
1226 afs_use_fs_server(call, fc->cbi);1151 trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1227 trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);1152 afs_make_op_call(op, call, GFP_NOFS);
1228 afs_set_fc_call(call, fc);
1229 afs_make_call(&fc->ac, call, GFP_NOFS);
1230 return afs_wait_for_call_to_complete(call, &fc->ac);
1231}1153}
1232 1154
1233/*1155/*
@@ -1243,27 +1165,23 @@ static const struct afs_call_type yfs_RXYFSStoreData64 = { · 9 unmodified lines
1243/*1165/*
1244 * Store a set of pages to a large file.1166 * Store a set of pages to a large file.
1245 */1167 */
1246int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,1168void yfs_fs_store_data(struct afs_operation *op)
1247 pgoff_t first, pgoff_t last,
1248 unsigned offset, unsigned to,
1249 struct afs_status_cb *scb)
1250{1169{
1251 struct afs_vnode *vnode = fc->vnode;1170 struct afs_vnode_param *vp = &op->file[0];
1252 struct afs_call *call;1171 struct afs_call *call;
1253 struct afs_net *net = afs_v2net(vnode);
1254 loff_t size, pos, i_size;1172 loff_t size, pos, i_size;
1255 __be32 *bp;1173 __be32 *bp;
1256 1174
1257 _enter(",%x,{%llx:%llu},,",1175 _enter(",%x,{%llx:%llu},,",
1258 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1176 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1259 1177
1260 size = (loff_t)to - (loff_t)offset;1178 size = (loff_t)op->store.last_to - (loff_t)op->store.first_offset;
1261 if (first != last)1179 if (op->store.first != op->store.last)
1262 size += (loff_t)(last - first) << PAGE_SHIFT;1180 size += (loff_t)(op->store.last - op->store.first) << PAGE_SHIFT;
1263 pos = (loff_t)first << PAGE_SHIFT;1181 pos = (loff_t)op->store.first << PAGE_SHIFT;
1264 pos += offset;1182 pos += op->store.first_offset;
1265 1183
1266 i_size = i_size_read(&vnode->vfs_inode);1184 i_size = i_size_read(&vp->vnode->vfs_inode);
1267 if (pos + size > i_size)1185 if (pos + size > i_size)
1268 i_size = size + pos;1186 i_size = size + pos;
1269 1187
@@ -1271,7 +1189,7 @@ int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, · 1 unmodified line
1271 (unsigned long long)size, (unsigned long long)pos,1189 (unsigned long long)size, (unsigned long long)pos,
1272 (unsigned long long)i_size);1190 (unsigned long long)i_size);
1273 1191
1274 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,1192 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64,
1275 sizeof(__be32) +1193 sizeof(__be32) +
1276 sizeof(__be32) +1194 sizeof(__be32) +
1277 sizeof(struct yfs_xdr_YFSFid) +1195 sizeof(struct yfs_xdr_YFSFid) +
@@ -1280,33 +1198,24 @@ int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, · 2 unmodified lines
1280 sizeof(struct yfs_xdr_YFSFetchStatus) +1198 sizeof(struct yfs_xdr_YFSFetchStatus) +
1281 sizeof(struct yfs_xdr_YFSVolSync));1199 sizeof(struct yfs_xdr_YFSVolSync));
1282 if (!call)1200 if (!call)
1283 return -ENOMEM;1201 return afs_op_nomem(op);
1284 1202
1285 call->key = fc->key;1203 call->key = op->key;
1286 call->mapping = mapping;
1287 call->first = first;
1288 call->last = last;
1289 call->first_offset = offset;
1290 call->last_to = to;
1291 call->send_pages = true;1204 call->send_pages = true;
1292 call->out_scb = scb;
1293 1205
1294 /* marshall the parameters */1206 /* marshall the parameters */
1295 bp = call->request;1207 bp = call->request;
1296 bp = xdr_encode_u32(bp, YFSSTOREDATA64);1208 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1297 bp = xdr_encode_u32(bp, 0); /* RPC flags */1209 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1298 bp = xdr_encode_YFSFid(bp, &vnode->fid);1210 bp = xdr_encode_YFSFid(bp, &vp->fid);
1299 bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);1211 bp = xdr_encode_YFSStoreStatus_mtime(bp, &op->mtime);
1300 bp = xdr_encode_u64(bp, pos);1212 bp = xdr_encode_u64(bp, pos);
1301 bp = xdr_encode_u64(bp, size);1213 bp = xdr_encode_u64(bp, size);
1302 bp = xdr_encode_u64(bp, i_size);1214 bp = xdr_encode_u64(bp, i_size);
1303 yfs_check_req(call, bp);1215 yfs_check_req(call, bp);
1304 1216
1305 afs_use_fs_server(call, fc->cbi);1217 trace_afs_make_fs_call(call, &vp->fid);
1306 trace_afs_make_fs_call(call, &vnode->fid);1218 afs_make_op_call(op, call, GFP_NOFS);
1307 afs_set_fc_call(call, fc);
1308 afs_make_call(&fc->ac, call, GFP_NOFS);
1309 return afs_wait_for_call_to_complete(call, &fc->ac);
1310}1219}
1311 1220
1312/*1221/*
@@ -1330,18 +1239,17 @@ static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = { · 17 unmodified lines
1330 * Set the attributes on a file, using YFS.StoreData64 rather than1239 * Set the attributes on a file, using YFS.StoreData64 rather than
1331 * YFS.StoreStatus so as to alter the file size also.1240 * YFS.StoreStatus so as to alter the file size also.
1332 */1241 */
1333static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr,1242static void yfs_fs_setattr_size(struct afs_operation *op)
1334 struct afs_status_cb *scb)
1335{1243{
1336 struct afs_vnode *vnode = fc->vnode;1244 struct afs_vnode_param *vp = &op->file[0];
1337 struct afs_call *call;1245 struct afs_call *call;
1338 struct afs_net *net = afs_v2net(vnode);1246 struct iattr *attr = op->setattr.attr;
1339 __be32 *bp;1247 __be32 *bp;
1340 1248
1341 _enter(",%x,{%llx:%llu},,",1249 _enter(",%x,{%llx:%llu},,",
1342 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1250 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1343 1251
1344 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,1252 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64_as_Status,
1345 sizeof(__be32) * 2 +1253 sizeof(__be32) * 2 +
1346 sizeof(struct yfs_xdr_YFSFid) +1254 sizeof(struct yfs_xdr_YFSFid) +
1347 sizeof(struct yfs_xdr_YFSStoreStatus) +1255 sizeof(struct yfs_xdr_YFSStoreStatus) +
@@ -1349,72 +1257,59 @@ static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr, · 1 unmodified line
1349 sizeof(struct yfs_xdr_YFSFetchStatus) +1257 sizeof(struct yfs_xdr_YFSFetchStatus) +
1350 sizeof(struct yfs_xdr_YFSVolSync));1258 sizeof(struct yfs_xdr_YFSVolSync));
1351 if (!call)1259 if (!call)
1352 return -ENOMEM;1260 return afs_op_nomem(op);
1353
1354 call->key = fc->key;
1355 call->out_scb = scb;
1356 1261
1357 /* marshall the parameters */1262 /* marshall the parameters */
1358 bp = call->request;1263 bp = call->request;
1359 bp = xdr_encode_u32(bp, YFSSTOREDATA64);1264 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1360 bp = xdr_encode_u32(bp, 0); /* RPC flags */1265 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1361 bp = xdr_encode_YFSFid(bp, &vnode->fid);1266 bp = xdr_encode_YFSFid(bp, &vp->fid);
1362 bp = xdr_encode_YFS_StoreStatus(bp, attr);1267 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1363 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */1268 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1364 bp = xdr_encode_u64(bp, 0); /* size of write */1269 bp = xdr_encode_u64(bp, 0); /* size of write */
1365 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */1270 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1366 yfs_check_req(call, bp);1271 yfs_check_req(call, bp);
1367 1272
1368 afs_use_fs_server(call, fc->cbi);1273 trace_afs_make_fs_call(call, &vp->fid);
1369 trace_afs_make_fs_call(call, &vnode->fid);1274 afs_make_op_call(op, call, GFP_NOFS);
1370 afs_set_fc_call(call, fc);
1371 afs_make_call(&fc->ac, call, GFP_NOFS);
1372 return afs_wait_for_call_to_complete(call, &fc->ac);
1373}1275}
1374 1276
1375/*1277/*
1376 * Set the attributes on a file, using YFS.StoreData64 if there's a change in1278 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1377 * file size, and YFS.StoreStatus otherwise.1279 * file size, and YFS.StoreStatus otherwise.
1378 */1280 */
1379int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr,1281void yfs_fs_setattr(struct afs_operation *op)
1380 struct afs_status_cb *scb)
1381{1282{
1382 struct afs_vnode *vnode = fc->vnode;1283 struct afs_vnode_param *vp = &op->file[0];
1383 struct afs_call *call;1284 struct afs_call *call;
1384 struct afs_net *net = afs_v2net(vnode);1285 struct iattr *attr = op->setattr.attr;
1385 __be32 *bp;1286 __be32 *bp;
1386 1287
1387 if (attr->ia_valid & ATTR_SIZE)1288 if (attr->ia_valid & ATTR_SIZE)
1388 return yfs_fs_setattr_size(fc, attr, scb);1289 return yfs_fs_setattr_size(op);
1389 1290
1390 _enter(",%x,{%llx:%llu},,",1291 _enter(",%x,{%llx:%llu},,",
1391 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1292 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1392 1293
1393 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,1294 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreStatus,
1394 sizeof(__be32) * 2 +1295 sizeof(__be32) * 2 +
1395 sizeof(struct yfs_xdr_YFSFid) +1296 sizeof(struct yfs_xdr_YFSFid) +
1396 sizeof(struct yfs_xdr_YFSStoreStatus),1297 sizeof(struct yfs_xdr_YFSStoreStatus),
1397 sizeof(struct yfs_xdr_YFSFetchStatus) +1298 sizeof(struct yfs_xdr_YFSFetchStatus) +
1398 sizeof(struct yfs_xdr_YFSVolSync));1299 sizeof(struct yfs_xdr_YFSVolSync));
1399 if (!call)1300 if (!call)
1400 return -ENOMEM;1301 return afs_op_nomem(op);
1401
1402 call->key = fc->key;
1403 call->out_scb = scb;
1404 1302
1405 /* marshall the parameters */1303 /* marshall the parameters */
1406 bp = call->request;1304 bp = call->request;
1407 bp = xdr_encode_u32(bp, YFSSTORESTATUS);1305 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1408 bp = xdr_encode_u32(bp, 0); /* RPC flags */1306 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1409 bp = xdr_encode_YFSFid(bp, &vnode->fid);1307 bp = xdr_encode_YFSFid(bp, &vp->fid);
1410 bp = xdr_encode_YFS_StoreStatus(bp, attr);1308 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1411 yfs_check_req(call, bp);1309 yfs_check_req(call, bp);
1412 1310
1413 afs_use_fs_server(call, fc->cbi);1311 trace_afs_make_fs_call(call, &vp->fid);
1414 trace_afs_make_fs_call(call, &vnode->fid);1312 afs_make_op_call(op, call, GFP_NOFS);
1415 afs_set_fc_call(call, fc);
1416 afs_make_call(&fc->ac, call, GFP_NOFS);
1417 return afs_wait_for_call_to_complete(call, &fc->ac);
1418}1313}
1419 1314
1420/*1315/*
@@ -1422,6 +1317,7 @@ int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr, · 1 unmodified line
1422 */1317 */
1423static int yfs_deliver_fs_get_volume_status(struct afs_call *call)1318static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1424{1319{
1320 struct afs_operation *op = call->op;
1425 const __be32 *bp;1321 const __be32 *bp;
1426 char *p;1322 char *p;
1427 u32 size;1323 u32 size;
@@ -1443,7 +1339,7 @@ static int yfs_deliver_fs_get_volume_status(struct afs_call *call) · 15 unmodified lines
1443 return ret;1339 return ret;
1444 1340
1445 bp = call->buffer;1341 bp = call->buffer;
1446 xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus);1342 xdr_decode_YFSFetchVolumeStatus(&bp, &op->volstatus.vs);
1447 call->unmarshall++;1343 call->unmarshall++;
1448 afs_extract_to_tmp(call);1344 afs_extract_to_tmp(call);
1449 /* Fall through */1345 /* Fall through */
@@ -1457,8 +1353,7 @@ static int yfs_deliver_fs_get_volume_status(struct afs_call *call) · 7 unmodified lines
1457 call->count = ntohl(call->tmp);1353 call->count = ntohl(call->tmp);
1458 _debug("volname length: %u", call->count);1354 _debug("volname length: %u", call->count);
1459 if (call->count >= AFSNAMEMAX)1355 if (call->count >= AFSNAMEMAX)
1460 return afs_protocol_error(call, -EBADMSG,1356 return afs_protocol_error(call, afs_eproto_volname_len);
1461 afs_eproto_volname_len);
1462 size = (call->count + 3) & ~3; /* It's padded */1357 size = (call->count + 3) & ~3; /* It's padded */
1463 afs_extract_to_buf(call, size);1358 afs_extract_to_buf(call, size);
1464 call->unmarshall++;1359 call->unmarshall++;
@@ -1487,8 +1382,7 @@ static int yfs_deliver_fs_get_volume_status(struct afs_call *call) · 22 unmodified lines
1487 call->count = ntohl(call->tmp);1382 call->count = ntohl(call->tmp);
1488 _debug("offline msg length: %u", call->count);1383 _debug("offline msg length: %u", call->count);
1489 if (call->count >= AFSNAMEMAX)1384 if (call->count >= AFSNAMEMAX)
1490 return afs_protocol_error(call, -EBADMSG,1385 return afs_protocol_error(call, afs_eproto_offline_msg_len);
1491 afs_eproto_offline_msg_len);
1492 size = (call->count + 3) & ~3; /* It's padded */1386 size = (call->count + 3) & ~3; /* It's padded */
1493 afs_extract_to_buf(call, size);1387 afs_extract_to_buf(call, size);
1494 call->unmarshall++;1388 call->unmarshall++;
@@ -1518,8 +1412,7 @@ static int yfs_deliver_fs_get_volume_status(struct afs_call *call) · 23 unmodified lines
1518 call->count = ntohl(call->tmp);1412 call->count = ntohl(call->tmp);
1519 _debug("motd length: %u", call->count);1413 _debug("motd length: %u", call->count);
1520 if (call->count >= AFSNAMEMAX)1414 if (call->count >= AFSNAMEMAX)
1521 return afs_protocol_error(call, -EBADMSG,1415 return afs_protocol_error(call, afs_eproto_motd_len);
1522 afs_eproto_motd_len);
1523 size = (call->count + 3) & ~3; /* It's padded */1416 size = (call->count + 3) & ~3; /* It's padded */
1524 afs_extract_to_buf(call, size);1417 afs_extract_to_buf(call, size);
1525 call->unmarshall++;1418 call->unmarshall++;
@@ -1560,17 +1453,15 @@ static const struct afs_call_type yfs_RXYFSGetVolumeStatus = { · 34 unmodified lines
1560/*1453/*
1561 * fetch the status of a volume1454 * fetch the status of a volume
1562 */1455 */
1563int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,1456void yfs_fs_get_volume_status(struct afs_operation *op)
1564 struct afs_volume_status *vs)
1565{1457{
1566 struct afs_vnode *vnode = fc->vnode;1458 struct afs_vnode_param *vp = &op->file[0];
1567 struct afs_call *call;1459 struct afs_call *call;
1568 struct afs_net *net = afs_v2net(vnode);
1569 __be32 *bp;1460 __be32 *bp;
1570 1461
1571 _enter("");1462 _enter("");
1572 1463
1573 call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,1464 call = afs_alloc_flat_call(op->net, &yfs_RXYFSGetVolumeStatus,
1574 sizeof(__be32) * 2 +1465 sizeof(__be32) * 2 +
1575 sizeof(struct yfs_xdr_u64),1466 sizeof(struct yfs_xdr_u64),
1576 max_t(size_t,1467 max_t(size_t,
@@ -1578,23 +1469,17 @@ int yfs_fs_get_volume_status(struct afs_fs_cursor *fc, · 1 unmodified line
1578 sizeof(__be32),1469 sizeof(__be32),
1579 AFSOPAQUEMAX + 1));1470 AFSOPAQUEMAX + 1));
1580 if (!call)1471 if (!call)
1581 return -ENOMEM;1472 return afs_op_nomem(op);
1582
1583 call->key = fc->key;
1584 call->out_volstatus = vs;
1585 1473
1586 /* marshall the parameters */1474 /* marshall the parameters */
1587 bp = call->request;1475 bp = call->request;
1588 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);1476 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1589 bp = xdr_encode_u32(bp, 0); /* RPC flags */1477 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1590 bp = xdr_encode_u64(bp, vnode->fid.vid);1478 bp = xdr_encode_u64(bp, vp->fid.vid);
1591 yfs_check_req(call, bp);1479 yfs_check_req(call, bp);
1592 1480
1593 afs_use_fs_server(call, fc->cbi);1481 trace_afs_make_fs_call(call, &vp->fid);
1594 trace_afs_make_fs_call(call, &vnode->fid);1482 afs_make_op_call(op, call, GFP_NOFS);
1595 afs_set_fc_call(call, fc);
1596 afs_make_call(&fc->ac, call, GFP_NOFS);
1597 return afs_wait_for_call_to_complete(call, &fc->ac);
1598}1483}
1599 1484
1600/*1485/*
@@ -1632,118 +1517,93 @@ static const struct afs_call_type yfs_RXYFSReleaseLock = { · 31 unmodified lines
1632/*1517/*
1633 * Set a lock on a file1518 * Set a lock on a file
1634 */1519 */
1635int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,1520void yfs_fs_set_lock(struct afs_operation *op)
1636 struct afs_status_cb *scb)
1637{1521{
1638 struct afs_vnode *vnode = fc->vnode;1522 struct afs_vnode_param *vp = &op->file[0];
1639 struct afs_call *call;1523 struct afs_call *call;
1640 struct afs_net *net = afs_v2net(vnode);
1641 __be32 *bp;1524 __be32 *bp;
1642 1525
1643 _enter("");1526 _enter("");
1644 1527
1645 call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,1528 call = afs_alloc_flat_call(op->net, &yfs_RXYFSSetLock,
1646 sizeof(__be32) * 2 +1529 sizeof(__be32) * 2 +
1647 sizeof(struct yfs_xdr_YFSFid) +1530 sizeof(struct yfs_xdr_YFSFid) +
1648 sizeof(__be32),1531 sizeof(__be32),
1649 sizeof(struct yfs_xdr_YFSFetchStatus) +1532 sizeof(struct yfs_xdr_YFSFetchStatus) +
1650 sizeof(struct yfs_xdr_YFSVolSync));1533 sizeof(struct yfs_xdr_YFSVolSync));
1651 if (!call)1534 if (!call)
1652 return -ENOMEM;1535 return afs_op_nomem(op);
1653
1654 call->key = fc->key;
1655 call->lvnode = vnode;
1656 call->out_scb = scb;
1657 1536
1658 /* marshall the parameters */1537 /* marshall the parameters */
1659 bp = call->request;1538 bp = call->request;
1660 bp = xdr_encode_u32(bp, YFSSETLOCK);1539 bp = xdr_encode_u32(bp, YFSSETLOCK);
1661 bp = xdr_encode_u32(bp, 0); /* RPC flags */1540 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1662 bp = xdr_encode_YFSFid(bp, &vnode->fid);1541 bp = xdr_encode_YFSFid(bp, &vp->fid);
1663 bp = xdr_encode_u32(bp, type);1542 bp = xdr_encode_u32(bp, op->lock.type);
1664 yfs_check_req(call, bp);1543 yfs_check_req(call, bp);
1665 1544
1666 afs_use_fs_server(call, fc->cbi);1545 trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);
1667 trace_afs_make_fs_calli(call, &vnode->fid, type);1546 afs_make_op_call(op, call, GFP_NOFS);
1668 afs_set_fc_call(call, fc);
1669 afs_make_call(&fc->ac, call, GFP_NOFS);
1670 return afs_wait_for_call_to_complete(call, &fc->ac);
1671}1547}
1672 1548
1673/*1549/*
1674 * extend a lock on a file1550 * extend a lock on a file
1675 */1551 */
1676int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)1552void yfs_fs_extend_lock(struct afs_operation *op)
1677{1553{
1678 struct afs_vnode *vnode = fc->vnode;1554 struct afs_vnode_param *vp = &op->file[0];
1679 struct afs_call *call;1555 struct afs_call *call;
1680 struct afs_net *net = afs_v2net(vnode);
1681 __be32 *bp;1556 __be32 *bp;
1682 1557
1683 _enter("");1558 _enter("");
1684 1559
1685 call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,1560 call = afs_alloc_flat_call(op->net, &yfs_RXYFSExtendLock,
1686 sizeof(__be32) * 2 +1561 sizeof(__be32) * 2 +
1687 sizeof(struct yfs_xdr_YFSFid),1562 sizeof(struct yfs_xdr_YFSFid),
1688 sizeof(struct yfs_xdr_YFSFetchStatus) +1563 sizeof(struct yfs_xdr_YFSFetchStatus) +
1689 sizeof(struct yfs_xdr_YFSVolSync));1564 sizeof(struct yfs_xdr_YFSVolSync));
1690 if (!call)1565 if (!call)
1691 return -ENOMEM;1566 return afs_op_nomem(op);
1692
1693 call->key = fc->key;
1694 call->lvnode = vnode;
1695 call->out_scb = scb;
1696 1567
1697 /* marshall the parameters */1568 /* marshall the parameters */
1698 bp = call->request;1569 bp = call->request;
1699 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);1570 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1700 bp = xdr_encode_u32(bp, 0); /* RPC flags */1571 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1701 bp = xdr_encode_YFSFid(bp, &vnode->fid);1572 bp = xdr_encode_YFSFid(bp, &vp->fid);
1702 yfs_check_req(call, bp);1573 yfs_check_req(call, bp);
1703 1574
1704 afs_use_fs_server(call, fc->cbi);1575 trace_afs_make_fs_call(call, &vp->fid);
1705 trace_afs_make_fs_call(call, &vnode->fid);1576 afs_make_op_call(op, call, GFP_NOFS);
1706 afs_set_fc_call(call, fc);
1707 afs_make_call(&fc->ac, call, GFP_NOFS);
1708 return afs_wait_for_call_to_complete(call, &fc->ac);
1709}1577}
1710 1578
1711/*1579/*
1712 * release a lock on a file1580 * release a lock on a file
1713 */1581 */
1714int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)1582void yfs_fs_release_lock(struct afs_operation *op)
1715{1583{
1716 struct afs_vnode *vnode = fc->vnode;1584 struct afs_vnode_param *vp = &op->file[0];
1717 struct afs_call *call;1585 struct afs_call *call;
1718 struct afs_net *net = afs_v2net(vnode);
1719 __be32 *bp;1586 __be32 *bp;
1720 1587
1721 _enter("");1588 _enter("");
1722 1589
1723 call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,1590 call = afs_alloc_flat_call(op->net, &yfs_RXYFSReleaseLock,
1724 sizeof(__be32) * 2 +1591 sizeof(__be32) * 2 +
1725 sizeof(struct yfs_xdr_YFSFid),1592 sizeof(struct yfs_xdr_YFSFid),
1726 sizeof(struct yfs_xdr_YFSFetchStatus) +1593 sizeof(struct yfs_xdr_YFSFetchStatus) +
1727 sizeof(struct yfs_xdr_YFSVolSync));1594 sizeof(struct yfs_xdr_YFSVolSync));
1728 if (!call)1595 if (!call)
1729 return -ENOMEM;1596 return afs_op_nomem(op);
1730
1731 call->key = fc->key;
1732 call->lvnode = vnode;
1733 call->out_scb = scb;
1734 1597
1735 /* marshall the parameters */1598 /* marshall the parameters */
1736 bp = call->request;1599 bp = call->request;
1737 bp = xdr_encode_u32(bp, YFSRELEASELOCK);1600 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1738 bp = xdr_encode_u32(bp, 0); /* RPC flags */1601 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1739 bp = xdr_encode_YFSFid(bp, &vnode->fid);1602 bp = xdr_encode_YFSFid(bp, &vp->fid);
1740 yfs_check_req(call, bp);1603 yfs_check_req(call, bp);
1741 1604
1742 afs_use_fs_server(call, fc->cbi);1605 trace_afs_make_fs_call(call, &vp->fid);
1743 trace_afs_make_fs_call(call, &vnode->fid);1606 afs_make_op_call(op, call, GFP_NOFS);
1744 afs_set_fc_call(call, fc);
1745 afs_make_call(&fc->ac, call, GFP_NOFS);
1746 return afs_wait_for_call_to_complete(call, &fc->ac);
1747}1607}
1748 1608
1749/*1609/*
@@ -1759,45 +1619,33 @@ static const struct afs_call_type yfs_RXYFSFetchStatus = { · 9 unmodified lines
1759/*1619/*
1760 * Fetch the status information for a fid without needing a vnode handle.1620 * Fetch the status information for a fid without needing a vnode handle.
1761 */1621 */
1762int yfs_fs_fetch_status(struct afs_fs_cursor *fc,1622void yfs_fs_fetch_status(struct afs_operation *op)
1763 struct afs_net *net,
1764 struct afs_fid *fid,
1765 struct afs_status_cb *scb,
1766 struct afs_volsync *volsync)
1767{1623{
1624 struct afs_vnode_param *vp = &op->file[0];
1768 struct afs_call *call;1625 struct afs_call *call;
1769 __be32 *bp;1626 __be32 *bp;
1770 1627
1771 _enter(",%x,{%llx:%llu},,",1628 _enter(",%x,{%llx:%llu},,",
1772 key_serial(fc->key), fid->vid, fid->vnode);1629 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1773 1630
1774 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,1631 call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus,
1775 sizeof(__be32) * 2 +1632 sizeof(__be32) * 2 +
1776 sizeof(struct yfs_xdr_YFSFid),1633 sizeof(struct yfs_xdr_YFSFid),
1777 sizeof(struct yfs_xdr_YFSFetchStatus) +1634 sizeof(struct yfs_xdr_YFSFetchStatus) +
1778 sizeof(struct yfs_xdr_YFSCallBack) +1635 sizeof(struct yfs_xdr_YFSCallBack) +
1779 sizeof(struct yfs_xdr_YFSVolSync));1636 sizeof(struct yfs_xdr_YFSVolSync));
1780 if (!call) {1637 if (!call)
1781 fc->ac.error = -ENOMEM;1638 return afs_op_nomem(op);
1782 return -ENOMEM;
1783 }
1784
1785 call->key = fc->key;
1786 call->out_scb = scb;
1787 call->out_volsync = volsync;
1788 1639
1789 /* marshall the parameters */1640 /* marshall the parameters */
1790 bp = call->request;1641 bp = call->request;
1791 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);1642 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1792 bp = xdr_encode_u32(bp, 0); /* RPC flags */1643 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1793 bp = xdr_encode_YFSFid(bp, fid);1644 bp = xdr_encode_YFSFid(bp, &vp->fid);
1794 yfs_check_req(call, bp);1645 yfs_check_req(call, bp);
1795 1646
1796 afs_use_fs_server(call, fc->cbi);1647 trace_afs_make_fs_call(call, &vp->fid);
1797 trace_afs_make_fs_call(call, fid);1648 afs_make_op_call(op, call, GFP_NOFS);
1798 afs_set_fc_call(call, fc);
1799 afs_make_call(&fc->ac, call, GFP_NOFS);
1800 return afs_wait_for_call_to_complete(call, &fc->ac);
1801}1649}
1802 1650
1803/*1651/*
@@ -1805,6 +1653,7 @@ int yfs_fs_fetch_status(struct afs_fs_cursor *fc, · 1 unmodified line
1805 */1653 */
1806static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)1654static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1807{1655{
1656 struct afs_operation *op = call->op;
1808 struct afs_status_cb *scb;1657 struct afs_status_cb *scb;
1809 const __be32 *bp;1658 const __be32 *bp;
1810 u32 tmp;1659 u32 tmp;
@@ -1826,10 +1675,9 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) · 15 unmodified lines
1826 return ret;1675 return ret;
1827 1676
1828 tmp = ntohl(call->tmp);1677 tmp = ntohl(call->tmp);
1829 _debug("status count: %u/%u", tmp, call->count2);1678 _debug("status count: %u/%u", tmp, op->nr_files);
1830 if (tmp != call->count2)1679 if (tmp != op->nr_files)
1831 return afs_protocol_error(call, -EBADMSG,1680 return afs_protocol_error(call, afs_eproto_ibulkst_count);
1832 afs_eproto_ibulkst_count);
1833 1681
1834 call->count = 0;1682 call->count = 0;
1835 call->unmarshall++;1683 call->unmarshall++;
@@ -1843,14 +1691,23 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) · 7 unmodified lines
1843 if (ret < 0)1691 if (ret < 0)
1844 return ret;1692 return ret;
1845 1693
1694 switch (call->count) {
1695 case 0:
1696 scb = &op->file[0].scb;
1697 break;
1698 case 1:
1699 scb = &op->file[1].scb;
1700 break;
1701 default:
1702 scb = &op->more_files[call->count - 2].scb;
1703 break;
1704 }
1705
1846 bp = call->buffer;1706 bp = call->buffer;
1847 scb = &call->out_scb[call->count];1707 xdr_decode_YFSFetchStatus(&bp, call, scb);
1848 ret = xdr_decode_YFSFetchStatus(&bp, call, scb);
1849 if (ret < 0)
1850 return ret;
1851 1708
1852 call->count++;1709 call->count++;
1853 if (call->count < call->count2)1710 if (call->count < op->nr_files)
1854 goto more_counts;1711 goto more_counts;
1855 1712
1856 call->count = 0;1713 call->count = 0;
@@ -1867,9 +1724,8 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) · 10 unmodified lines
1867 1724
1868 tmp = ntohl(call->tmp);1725 tmp = ntohl(call->tmp);
1869 _debug("CB count: %u", tmp);1726 _debug("CB count: %u", tmp);
1870 if (tmp != call->count2)1727 if (tmp != op->nr_files)
1871 return afs_protocol_error(call, -EBADMSG,1728 return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
1872 afs_eproto_ibulkst_cb_count);
1873 call->count = 0;1729 call->count = 0;
1874 call->unmarshall++;1730 call->unmarshall++;
1875 more_cbs:1731 more_cbs:
@@ -1883,11 +1739,22 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) · 7 unmodified lines
1883 return ret;1739 return ret;
1884 1740
1885 _debug("unmarshall CB array");1741 _debug("unmarshall CB array");
1742 switch (call->count) {
1743 case 0:
1744 scb = &op->file[0].scb;
1745 break;
1746 case 1:
1747 scb = &op->file[1].scb;
1748 break;
1749 default:
1750 scb = &op->more_files[call->count - 2].scb;
1751 break;
1752 }
1753
1886 bp = call->buffer;1754 bp = call->buffer;
1887 scb = &call->out_scb[call->count];
1888 xdr_decode_YFSCallBack(&bp, call, scb);1755 xdr_decode_YFSCallBack(&bp, call, scb);
1889 call->count++;1756 call->count++;
1890 if (call->count < call->count2)1757 if (call->count < op->nr_files)
1891 goto more_cbs;1758 goto more_cbs;
1892 1759
1893 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));1760 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
@@ -1900,7 +1767,7 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) · 6 unmodified lines
1900 return ret;1767 return ret;
1901 1768
1902 bp = call->buffer;1769 bp = call->buffer;
1903 xdr_decode_YFSVolSync(&bp, call->out_volsync);1770 xdr_decode_YFSVolSync(&bp, &op->volsync);
1904 1771
1905 call->unmarshall++;1772 call->unmarshall++;
1906 /* Fall through */1773 /* Fall through */
@@ -1926,50 +1793,39 @@ static const struct afs_call_type yfs_RXYFSInlineBulkStatus = { · 19 unmodified lines
1926/*1793/*
1927 * Fetch the status information for up to 1024 files1794 * Fetch the status information for up to 1024 files
1928 */1795 */
1929int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,1796void yfs_fs_inline_bulk_status(struct afs_operation *op)
1930 struct afs_net *net,
1931 struct afs_fid *fids,
1932 struct afs_status_cb *statuses,
1933 unsigned int nr_fids,
1934 struct afs_volsync *volsync)
1935{1797{
1798 struct afs_vnode_param *dvp = &op->file[0];
1799 struct afs_vnode_param *vp = &op->file[1];
1936 struct afs_call *call;1800 struct afs_call *call;
1937 __be32 *bp;1801 __be32 *bp;
1938 int i;1802 int i;
1939 1803
1940 _enter(",%x,{%llx:%llu},%u",1804 _enter(",%x,{%llx:%llu},%u",
1941 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);1805 key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);
1942 1806
1943 call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,1807 call = afs_alloc_flat_call(op->net, &yfs_RXYFSInlineBulkStatus,
1944 sizeof(__be32) +1808 sizeof(__be32) +
1945 sizeof(__be32) +1809 sizeof(__be32) +
1946 sizeof(__be32) +1810 sizeof(__be32) +
1947 sizeof(struct yfs_xdr_YFSFid) * nr_fids,1811 sizeof(struct yfs_xdr_YFSFid) * op->nr_files,
1948 sizeof(struct yfs_xdr_YFSFetchStatus));1812 sizeof(struct yfs_xdr_YFSFetchStatus));
1949 if (!call) {1813 if (!call)
1950 fc->ac.error = -ENOMEM;1814 return afs_op_nomem(op);
1951 return -ENOMEM;
1952 }
1953
1954 call->key = fc->key;
1955 call->out_scb = statuses;
1956 call->out_volsync = volsync;
1957 call->count2 = nr_fids;
1958 1815
1959 /* marshall the parameters */1816 /* marshall the parameters */
1960 bp = call->request;1817 bp = call->request;
1961 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);1818 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1962 bp = xdr_encode_u32(bp, 0); /* RPCFlags */1819 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1963 bp = xdr_encode_u32(bp, nr_fids);1820 bp = xdr_encode_u32(bp, op->nr_files);
1964 for (i = 0; i < nr_fids; i++)1821 bp = xdr_encode_YFSFid(bp, &dvp->fid);
1965 bp = xdr_encode_YFSFid(bp, &fids[i]);1822 bp = xdr_encode_YFSFid(bp, &vp->fid);
1823 for (i = 0; i < op->nr_files - 2; i++)
1824 bp = xdr_encode_YFSFid(bp, &op->more_files[i].fid);
1966 yfs_check_req(call, bp);1825 yfs_check_req(call, bp);
1967 1826
1968 afs_use_fs_server(call, fc->cbi);1827 trace_afs_make_fs_call(call, &vp->fid);
1969 trace_afs_make_fs_call(call, &fids[0]);1828 afs_make_op_call(op, call, GFP_NOFS);
1970 afs_set_fc_call(call, fc);
1971 afs_make_call(&fc->ac, call, GFP_NOFS);
1972 return afs_wait_for_call_to_complete(call, &fc->ac);
1973}1829}
1974 1830
1975/*1831/*
@@ -1977,7 +1833,9 @@ int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc, · 1 unmodified line
1977 */1833 */
1978static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)1834static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1979{1835{
1980 struct yfs_acl *yacl = call->out_yacl;1836 struct afs_operation *op = call->op;
1837 struct afs_vnode_param *vp = &op->file[0];
1838 struct yfs_acl *yacl = op->yacl;
1981 struct afs_acl *acl;1839 struct afs_acl *acl;
1982 const __be32 *bp;1840 const __be32 *bp;
1983 unsigned int size;1841 unsigned int size;
@@ -2067,10 +1925,8 @@ static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call) · 83 unmodified lines
2067 bp = call->buffer;1925 bp = call->buffer;
2068 yacl->inherit_flag = ntohl(*bp++);1926 yacl->inherit_flag = ntohl(*bp++);
2069 yacl->num_cleaned = ntohl(*bp++);1927 yacl->num_cleaned = ntohl(*bp++);
2070 ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);1928 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
2071 if (ret < 0)1929 xdr_decode_YFSVolSync(&bp, &op->volsync);
2072 return ret;
2073 xdr_decode_YFSVolSync(&bp, call->out_volsync);
2074 1930
2075 call->unmarshall++;1931 call->unmarshall++;
2076 /* Fall through */1932 /* Fall through */
@@ -2105,45 +1961,33 @@ static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = { · 28 unmodified lines
2105/*1961/*
2106 * Fetch the YFS advanced ACLs for a file.1962 * Fetch the YFS advanced ACLs for a file.
2107 */1963 */
2108struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,1964void yfs_fs_fetch_opaque_acl(struct afs_operation *op)
2109 struct yfs_acl *yacl,
2110 struct afs_status_cb *scb)
2111{1965{
2112 struct afs_vnode *vnode = fc->vnode;1966 struct afs_vnode_param *vp = &op->file[0];
2113 struct afs_call *call;1967 struct afs_call *call;
2114 struct afs_net *net = afs_v2net(vnode);
2115 __be32 *bp;1968 __be32 *bp;
2116 1969
2117 _enter(",%x,{%llx:%llu},,",1970 _enter(",%x,{%llx:%llu},,",
2118 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);1971 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2119 1972
2120 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,1973 call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchOpaqueACL,
2121 sizeof(__be32) * 2 +1974 sizeof(__be32) * 2 +
2122 sizeof(struct yfs_xdr_YFSFid),1975 sizeof(struct yfs_xdr_YFSFid),
2123 sizeof(__be32) * 2 +1976 sizeof(__be32) * 2 +
2124 sizeof(struct yfs_xdr_YFSFetchStatus) +1977 sizeof(struct yfs_xdr_YFSFetchStatus) +
2125 sizeof(struct yfs_xdr_YFSVolSync));1978 sizeof(struct yfs_xdr_YFSVolSync));
2126 if (!call) {1979 if (!call)
2127 fc->ac.error = -ENOMEM;1980 return afs_op_nomem(op);
2128 return ERR_PTR(-ENOMEM);
2129 }
2130
2131 call->key = fc->key;
2132 call->out_yacl = yacl;
2133 call->out_scb = scb;
2134 call->out_volsync = NULL;
2135 1981
2136 /* marshall the parameters */1982 /* marshall the parameters */
2137 bp = call->request;1983 bp = call->request;
2138 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);1984 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2139 bp = xdr_encode_u32(bp, 0); /* RPC flags */1985 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2140 bp = xdr_encode_YFSFid(bp, &vnode->fid);1986 bp = xdr_encode_YFSFid(bp, &vp->fid);
2141 yfs_check_req(call, bp);1987 yfs_check_req(call, bp);
2142 1988
2143 afs_use_fs_server(call, fc->cbi);1989 trace_afs_make_fs_call(call, &vp->fid);
2144 trace_afs_make_fs_call(call, &vnode->fid);1990 afs_make_op_call(op, call, GFP_KERNEL);
2145 afs_make_call(&fc->ac, call, GFP_KERNEL);
2146 return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2147}1991}
2148 1992
2149/*1993/*
@@ -2159,46 +2003,38 @@ static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = { · 9 unmodified lines
2159/*2003/*
2160 * Fetch the YFS ACL for a file.2004 * Fetch the YFS ACL for a file.
2161 */2005 */
2162int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl,2006void yfs_fs_store_opaque_acl2(struct afs_operation *op)
2163 struct afs_status_cb *scb)
2164{2007{
2165 struct afs_vnode *vnode = fc->vnode;2008 struct afs_vnode_param *vp = &op->file[0];
2166 struct afs_call *call;2009 struct afs_call *call;
2167 struct afs_net *net = afs_v2net(vnode);2010 struct afs_acl *acl = op->acl;
2168 size_t size;2011 size_t size;
2169 __be32 *bp;2012 __be32 *bp;
2170 2013
2171 _enter(",%x,{%llx:%llu},,",2014 _enter(",%x,{%llx:%llu},,",
2172 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);2015 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2173 2016
2174 size = round_up(acl->size, 4);2017 size = round_up(acl->size, 4);
2175 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreOpaqueACL2,2018 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreOpaqueACL2,
2176 sizeof(__be32) * 2 +2019 sizeof(__be32) * 2 +
2177 sizeof(struct yfs_xdr_YFSFid) +2020 sizeof(struct yfs_xdr_YFSFid) +
2178 sizeof(__be32) + size,2021 sizeof(__be32) + size,
2179 sizeof(struct yfs_xdr_YFSFetchStatus) +2022 sizeof(struct yfs_xdr_YFSFetchStatus) +
2180 sizeof(struct yfs_xdr_YFSVolSync));2023 sizeof(struct yfs_xdr_YFSVolSync));
2181 if (!call) {2024 if (!call)
2182 fc->ac.error = -ENOMEM;2025 return afs_op_nomem(op);
2183 return -ENOMEM;
2184 }
2185
2186 call->key = fc->key;
2187 call->out_scb = scb;
2188 call->out_volsync = NULL;
2189 2026
2190 /* marshall the parameters */2027 /* marshall the parameters */
2191 bp = call->request;2028 bp = call->request;
2192 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);2029 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2193 bp = xdr_encode_u32(bp, 0); /* RPC flags */2030 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2194 bp = xdr_encode_YFSFid(bp, &vnode->fid);2031 bp = xdr_encode_YFSFid(bp, &vp->fid);
2195 bp = xdr_encode_u32(bp, acl->size);2032 bp = xdr_encode_u32(bp, acl->size);
2196 memcpy(bp, acl->data, acl->size);2033 memcpy(bp, acl->data, acl->size);
2197 if (acl->size != size)2034 if (acl->size != size)
2198 memset((void *)bp + acl->size, 0, size - acl->size);2035 memset((void *)bp + acl->size, 0, size - acl->size);
2199 yfs_check_req(call, bp);2036 yfs_check_req(call, bp);
2200 2037
2201 trace_afs_make_fs_call(call, &vnode->fid);2038 trace_afs_make_fs_call(call, &vp->fid);
2202 afs_make_call(&fc->ac, call, GFP_KERNEL);2039 afs_make_op_call(op, call, GFP_KERNEL);
2203 return afs_wait_for_call_to_complete(call, &fc->ac);
2204}2040}
fs/ext4/inode.c+22−22
@@ -4865,21 +4865,22 @@ static int ext4_inode_blocks_set(handle_t *handle, · 4864 unmodified lines
4865 return 0;4865 return 0;
4866}4866}
4867 4867
4868struct other_inode {4868static void __ext4_update_other_inode_time(struct super_block *sb,
4869 unsigned long orig_ino;4869 unsigned long orig_ino,
4870 struct ext4_inode *raw_inode;4870 unsigned long ino,
4871};4871 struct ext4_inode *raw_inode)
4872
4873static int other_inode_match(struct inode * inode, unsigned long ino,
4874 void *data)
4875{4872{
4876 struct other_inode *oi = (struct other_inode *) data;4873 struct inode *inode;
4874
4875 inode = find_inode_by_ino_rcu(sb, ino);
4876 if (!inode)
4877 return;
4877 4878
4878 if ((inode->i_ino != ino) ||4879 if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
4879 (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
4880 I_DIRTY_INODE)) ||4880 I_DIRTY_INODE)) ||
4881 ((inode->i_state & I_DIRTY_TIME) == 0))4881 ((inode->i_state & I_DIRTY_TIME) == 0))
4882 return 0;4882 return;
4883
4883 spin_lock(&inode->i_lock);4884 spin_lock(&inode->i_lock);
4884 if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |4885 if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
4885 I_DIRTY_INODE)) == 0) &&4886 I_DIRTY_INODE)) == 0) &&
@@ -4890,16 +4891,15 @@ static int other_inode_match(struct inode * inode, unsigned long ino, · 4 unmodified lines
4890 spin_unlock(&inode->i_lock);4891 spin_unlock(&inode->i_lock);
4891 4892
4892 spin_lock(&ei->i_raw_lock);4893 spin_lock(&ei->i_raw_lock);
4893 EXT4_INODE_SET_XTIME(i_ctime, inode, oi->raw_inode);4894 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
4894 EXT4_INODE_SET_XTIME(i_mtime, inode, oi->raw_inode);4895 EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode);
4895 EXT4_INODE_SET_XTIME(i_atime, inode, oi->raw_inode);4896 EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode);
4896 ext4_inode_csum_set(inode, oi->raw_inode, ei);4897 ext4_inode_csum_set(inode, raw_inode, ei);
4897 spin_unlock(&ei->i_raw_lock);4898 spin_unlock(&ei->i_raw_lock);
4898 trace_ext4_other_inode_update_time(inode, oi->orig_ino);4899 trace_ext4_other_inode_update_time(inode, orig_ino);
4899 return -1;4900 return;
4900 }4901 }
4901 spin_unlock(&inode->i_lock);4902 spin_unlock(&inode->i_lock);
4902 return -1;
4903}4903}
4904 4904
4905/*4905/*
@@ -4909,24 +4909,24 @@ static int other_inode_match(struct inode * inode, unsigned long ino, · 3 unmodified lines
4909static void ext4_update_other_inodes_time(struct super_block *sb,4909static void ext4_update_other_inodes_time(struct super_block *sb,
4910 unsigned long orig_ino, char *buf)4910 unsigned long orig_ino, char *buf)
4911{4911{
4912 struct other_inode oi;
4913 unsigned long ino;4912 unsigned long ino;
4914 int i, inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;4913 int i, inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
4915 int inode_size = EXT4_INODE_SIZE(sb);4914 int inode_size = EXT4_INODE_SIZE(sb);
4916 4915
4917 oi.orig_ino = orig_ino;
4918 /*4916 /*
4919 * Calculate the first inode in the inode table block. Inode4917 * Calculate the first inode in the inode table block. Inode
4920 * numbers are one-based. That is, the first inode in a block4918 * numbers are one-based. That is, the first inode in a block
4921 * (assuming 4k blocks and 256 byte inodes) is (n*16 + 1).4919 * (assuming 4k blocks and 256 byte inodes) is (n*16 + 1).
4922 */4920 */
4923 ino = ((orig_ino - 1) & ~(inodes_per_block - 1)) + 1;4921 ino = ((orig_ino - 1) & ~(inodes_per_block - 1)) + 1;
4922 rcu_read_lock();
4924 for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) {4923 for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) {
4925 if (ino == orig_ino)4924 if (ino == orig_ino)
4926 continue;4925 continue;
4927 oi.raw_inode = (struct ext4_inode *) buf;4926 __ext4_update_other_inode_time(sb, orig_ino, ino,
4928 (void) find_inode_nowait(sb, ino, other_inode_match, &oi);4927 (struct ext4_inode *)buf);
4929 }4928 }
4929 rcu_read_unlock();
4930}4930}
4931 4931
4932/*4932/*
fs/inode.c+96−16
@@ -497,7 +497,7 @@ void __insert_inode_hash(struct inode *inode, unsigned long hashval) · 496 unmodified lines
497 497
498 spin_lock(&inode_hash_lock);498 spin_lock(&inode_hash_lock);
499 spin_lock(&inode->i_lock);499 spin_lock(&inode->i_lock);
500 hlist_add_head(&inode->i_hash, b);500 hlist_add_head_rcu(&inode->i_hash, b);
501 spin_unlock(&inode->i_lock);501 spin_unlock(&inode->i_lock);
502 spin_unlock(&inode_hash_lock);502 spin_unlock(&inode_hash_lock);
503}503}
@@ -513,7 +513,7 @@ void __remove_inode_hash(struct inode *inode) · 9 unmodified lines
513{513{
514 spin_lock(&inode_hash_lock);514 spin_lock(&inode_hash_lock);
515 spin_lock(&inode->i_lock);515 spin_lock(&inode->i_lock);
516 hlist_del_init(&inode->i_hash);516 hlist_del_init_rcu(&inode->i_hash);
517 spin_unlock(&inode->i_lock);517 spin_unlock(&inode->i_lock);
518 spin_unlock(&inode_hash_lock);518 spin_unlock(&inode_hash_lock);
519}519}
@@ -1107,7 +1107,7 @@ again: · 587 unmodified lines
1107 */1107 */
1108 spin_lock(&inode->i_lock);1108 spin_lock(&inode->i_lock);
1109 inode->i_state |= I_NEW;1109 inode->i_state |= I_NEW;
1110 hlist_add_head(&inode->i_hash, head);1110 hlist_add_head_rcu(&inode->i_hash, head);
1111 spin_unlock(&inode->i_lock);1111 spin_unlock(&inode->i_lock);
1112 if (!creating)1112 if (!creating)
1113 inode_sb_list_add(inode);1113 inode_sb_list_add(inode);
@@ -1201,7 +1201,7 @@ again: · 87 unmodified lines
1201 inode->i_ino = ino;1201 inode->i_ino = ino;
1202 spin_lock(&inode->i_lock);1202 spin_lock(&inode->i_lock);
1203 inode->i_state = I_NEW;1203 inode->i_state = I_NEW;
1204 hlist_add_head(&inode->i_hash, head);1204 hlist_add_head_rcu(&inode->i_hash, head);
1205 spin_unlock(&inode->i_lock);1205 spin_unlock(&inode->i_lock);
1206 inode_sb_list_add(inode);1206 inode_sb_list_add(inode);
1207 spin_unlock(&inode_hash_lock);1207 spin_unlock(&inode_hash_lock);
@@ -1244,15 +1244,10 @@ static int test_inode_iunique(struct super_block *sb, unsigned long ino) · 36 unmodified lines
1244 struct hlist_head *b = inode_hashtable + hash(sb, ino);1244 struct hlist_head *b = inode_hashtable + hash(sb, ino);
1245 struct inode *inode;1245 struct inode *inode;
1246 1246
1247 spin_lock(&inode_hash_lock);1247 hlist_for_each_entry_rcu(inode, b, i_hash) {
1248 hlist_for_each_entry(inode, b, i_hash) {1248 if (inode->i_ino == ino && inode->i_sb == sb)
1249 if (inode->i_ino == ino && inode->i_sb == sb) {
1250 spin_unlock(&inode_hash_lock);
1251 return 0;1249 return 0;
1252 }
1253 }1250 }
1254 spin_unlock(&inode_hash_lock);
1255
1256 return 1;1251 return 1;
1257}1252}
1258 1253
@@ -1281,6 +1276,7 @@ ino_t iunique(struct super_block *sb, ino_t max_reserved) · 22 unmodified lines
1281 static unsigned int counter;1276 static unsigned int counter;
1282 ino_t res;1277 ino_t res;
1283 1278
1279 rcu_read_lock();
1284 spin_lock(&iunique_lock);1280 spin_lock(&iunique_lock);
1285 do {1281 do {
1286 if (counter <= max_reserved)1282 if (counter <= max_reserved)
@@ -1288,6 +1284,7 @@ ino_t iunique(struct super_block *sb, ino_t max_reserved) · 1 unmodified line
1288 res = counter++;1284 res = counter++;
1289 } while (!test_inode_iunique(sb, res));1285 } while (!test_inode_iunique(sb, res));
1290 spin_unlock(&iunique_lock);1286 spin_unlock(&iunique_lock);
1287 rcu_read_unlock();
1291 1288
1292 return res;1289 return res;
1293}1290}
@@ -1456,6 +1453,84 @@ out: · 162 unmodified lines
1456}1453}
1457EXPORT_SYMBOL(find_inode_nowait);1454EXPORT_SYMBOL(find_inode_nowait);
1458 1455
1456/**
1457 * find_inode_rcu - find an inode in the inode cache
1458 * @sb: Super block of file system to search
1459 * @hashval: Key to hash
1460 * @test: Function to test match on an inode
1461 * @data: Data for test function
1462 *
1463 * Search for the inode specified by @hashval and @data in the inode cache,
1464 * where the helper function @test will return 0 if the inode does not match
1465 * and 1 if it does. The @test function must be responsible for taking the
1466 * i_lock spin_lock and checking i_state for an inode being freed or being
1467 * initialized.
1468 *
1469 * If successful, this will return the inode for which the @test function
1470 * returned 1 and NULL otherwise.
1471 *
1472 * The @test function is not permitted to take a ref on any inode presented.
1473 * It is also not permitted to sleep.
1474 *
1475 * The caller must hold the RCU read lock.
1476 */
1477struct inode *find_inode_rcu(struct super_block *sb, unsigned long hashval,
1478 int (*test)(struct inode *, void *), void *data)
1479{
1480 struct hlist_head *head = inode_hashtable + hash(sb, hashval);
1481 struct inode *inode;
1482
1483 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
1484 "suspicious find_inode_rcu() usage");
1485
1486 hlist_for_each_entry_rcu(inode, head, i_hash) {
1487 if (inode->i_sb == sb &&
1488 !(READ_ONCE(inode->i_state) & (I_FREEING | I_WILL_FREE)) &&
1489 test(inode, data))
1490 return inode;
1491 }
1492 return NULL;
1493}
1494EXPORT_SYMBOL(find_inode_rcu);
1495
1496/**
1497 * find_inode_by_rcu - Find an inode in the inode cache
1498 * @sb: Super block of file system to search
1499 * @ino: The inode number to match
1500 *
1501 * Search for the inode specified by @hashval and @data in the inode cache,
1502 * where the helper function @test will return 0 if the inode does not match
1503 * and 1 if it does. The @test function must be responsible for taking the
1504 * i_lock spin_lock and checking i_state for an inode being freed or being
1505 * initialized.
1506 *
1507 * If successful, this will return the inode for which the @test function
1508 * returned 1 and NULL otherwise.
1509 *
1510 * The @test function is not permitted to take a ref on any inode presented.
1511 * It is also not permitted to sleep.
1512 *
1513 * The caller must hold the RCU read lock.
1514 */
1515struct inode *find_inode_by_ino_rcu(struct super_block *sb,
1516 unsigned long ino)
1517{
1518 struct hlist_head *head = inode_hashtable + hash(sb, ino);
1519 struct inode *inode;
1520
1521 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
1522 "suspicious find_inode_by_ino_rcu() usage");
1523
1524 hlist_for_each_entry_rcu(inode, head, i_hash) {
1525 if (inode->i_ino == ino &&
1526 inode->i_sb == sb &&
1527 !(READ_ONCE(inode->i_state) & (I_FREEING | I_WILL_FREE)))
1528 return inode;
1529 }
1530 return NULL;
1531}
1532EXPORT_SYMBOL(find_inode_by_ino_rcu);
1533
1459int insert_inode_locked(struct inode *inode)1534int insert_inode_locked(struct inode *inode)
1460{1535{
1461 struct super_block *sb = inode->i_sb;1536 struct super_block *sb = inode->i_sb;
@@ -1480,7 +1555,7 @@ int insert_inode_locked(struct inode *inode) · 18 unmodified lines
1480 if (likely(!old)) {1555 if (likely(!old)) {
1481 spin_lock(&inode->i_lock);1556 spin_lock(&inode->i_lock);
1482 inode->i_state |= I_NEW | I_CREATING;1557 inode->i_state |= I_NEW | I_CREATING;
1483 hlist_add_head(&inode->i_hash, head);1558 hlist_add_head_rcu(&inode->i_hash, head);
1484 spin_unlock(&inode->i_lock);1559 spin_unlock(&inode->i_lock);
1485 spin_unlock(&inode_hash_lock);1560 spin_unlock(&inode_hash_lock);
1486 return 0;1561 return 0;
@@ -1540,6 +1615,7 @@ static void iput_final(struct inode *inode) · 53 unmodified lines
1540{1615{
1541 struct super_block *sb = inode->i_sb;1616 struct super_block *sb = inode->i_sb;
1542 const struct super_operations *op = inode->i_sb->s_op;1617 const struct super_operations *op = inode->i_sb->s_op;
1618 unsigned long state;
1543 int drop;1619 int drop;
1544 1620
1545 WARN_ON(inode->i_state & I_NEW);1621 WARN_ON(inode->i_state & I_NEW);
@@ -1555,16 +1631,20 @@ static void iput_final(struct inode *inode) · 9 unmodified lines
1555 return;1631 return;
1556 }1632 }
1557 1633
1634 state = inode->i_state;
1558 if (!drop) {1635 if (!drop) {
1559 inode->i_state |= I_WILL_FREE;1636 WRITE_ONCE(inode->i_state, state | I_WILL_FREE);
1560 spin_unlock(&inode->i_lock);1637 spin_unlock(&inode->i_lock);
1638
1561 write_inode_now(inode, 1);1639 write_inode_now(inode, 1);
1640
1562 spin_lock(&inode->i_lock);1641 spin_lock(&inode->i_lock);
1563 WARN_ON(inode->i_state & I_NEW);1642 state = inode->i_state;
1564 inode->i_state &= ~I_WILL_FREE;1643 WARN_ON(state & I_NEW);
1644 state &= ~I_WILL_FREE;
1565 }1645 }
1566 1646
1567 inode->i_state |= I_FREEING;1647 WRITE_ONCE(inode->i_state, state | I_FREEING);
1568 if (!list_empty(&inode->i_lru))1648 if (!list_empty(&inode->i_lru))
1569 inode_lru_list_del(inode);1649 inode_lru_list_del(inode);
1570 spin_unlock(&inode->i_lock);1650 spin_unlock(&inode->i_lock);
include/linux/fs.h+3−0
@@ -3081,6 +3081,9 @@ extern struct inode *find_inode_nowait(struct super_block *, · 3080 unmodified lines
3081 int (*match)(struct inode *,3081 int (*match)(struct inode *,
3082 unsigned long, void *),3082 unsigned long, void *),
3083 void *data);3083 void *data);
3084extern struct inode *find_inode_rcu(struct super_block *, unsigned long,
3085 int (*)(struct inode *, void *), void *);
3086extern struct inode *find_inode_by_ino_rcu(struct super_block *, unsigned long);
3084extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *);3087extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *);
3085extern int insert_inode_locked(struct inode *);3088extern int insert_inode_locked(struct inode *);
3086#ifdef CONFIG_DEBUG_LOCK_ALLOC3089#ifdef CONFIG_DEBUG_LOCK_ALLOC
include/trace/events/afs.h+88−23
@@ -33,20 +33,40 @@ enum afs_server_trace { · 32 unmodified lines
33 afs_server_trace_destroy,33 afs_server_trace_destroy,
34 afs_server_trace_free,34 afs_server_trace_free,
35 afs_server_trace_gc,35 afs_server_trace_gc,
36 afs_server_trace_get_by_addr,
36 afs_server_trace_get_by_uuid,37 afs_server_trace_get_by_uuid,
37 afs_server_trace_get_caps,38 afs_server_trace_get_caps,
38 afs_server_trace_get_install,39 afs_server_trace_get_install,
39 afs_server_trace_get_new_cbi,40 afs_server_trace_get_new_cbi,
41 afs_server_trace_get_probe,
40 afs_server_trace_give_up_cb,42 afs_server_trace_give_up_cb,
41 afs_server_trace_put_call,43 afs_server_trace_put_call,
42 afs_server_trace_put_cbi,44 afs_server_trace_put_cbi,
43 afs_server_trace_put_find_rsq,45 afs_server_trace_put_find_rsq,
46 afs_server_trace_put_probe,
44 afs_server_trace_put_slist,47 afs_server_trace_put_slist,
45 afs_server_trace_put_slist_isort,48 afs_server_trace_put_slist_isort,
46 afs_server_trace_put_uuid_rsq,49 afs_server_trace_put_uuid_rsq,
47 afs_server_trace_update,50 afs_server_trace_update,
48};51};
49 52
53enum 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,
68};
69
50enum afs_fs_operation {70enum afs_fs_operation {
51 afs_FS_FetchData = 130, /* AFS Fetch file data */71 afs_FS_FetchData = 130, /* AFS Fetch file data */
52 afs_FS_FetchACL = 131, /* AFS Fetch file ACL */72 afs_FS_FetchACL = 131, /* AFS Fetch file ACL */
@@ -108,6 +128,7 @@ enum afs_vl_operation { · 55 unmodified lines
108 afs_VL_GetEntryByNameU = 527, /* AFS Get Vol Entry By Name operation ID */128 afs_VL_GetEntryByNameU = 527, /* AFS Get Vol Entry By Name operation ID */
109 afs_VL_GetAddrsU = 533, /* AFS Get FS server addresses */129 afs_VL_GetAddrsU = 533, /* AFS Get FS server addresses */
110 afs_YFSVL_GetEndpoints = 64002, /* YFS Get FS & Vol server addresses */130 afs_YFSVL_GetEndpoints = 64002, /* YFS Get FS & Vol server addresses */
131 afs_YFSVL_GetCellName = 64014, /* YFS Get actual cell name */
111 afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */132 afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */
112};133};
113 134
@@ -140,6 +161,7 @@ enum afs_eproto_cause { · 26 unmodified lines
140 afs_eproto_bad_status,161 afs_eproto_bad_status,
141 afs_eproto_cb_count,162 afs_eproto_cb_count,
142 afs_eproto_cb_fid_count,163 afs_eproto_cb_fid_count,
164 afs_eproto_cellname_len,
143 afs_eproto_file_type,165 afs_eproto_file_type,
144 afs_eproto_ibulkst_cb_count,166 afs_eproto_ibulkst_cb_count,
145 afs_eproto_ibulkst_count,167 afs_eproto_ibulkst_count,
@@ -241,19 +263,38 @@ enum afs_cb_break_reason { · 95 unmodified lines
241 EM(afs_server_trace_destroy, "DESTROY ") \263 EM(afs_server_trace_destroy, "DESTROY ") \
242 EM(afs_server_trace_free, "FREE ") \264 EM(afs_server_trace_free, "FREE ") \
243 EM(afs_server_trace_gc, "GC ") \265 EM(afs_server_trace_gc, "GC ") \
266 EM(afs_server_trace_get_by_addr, "GET addr ") \
244 EM(afs_server_trace_get_by_uuid, "GET uuid ") \267 EM(afs_server_trace_get_by_uuid, "GET uuid ") \
245 EM(afs_server_trace_get_caps, "GET caps ") \268 EM(afs_server_trace_get_caps, "GET caps ") \
246 EM(afs_server_trace_get_install, "GET inst ") \269 EM(afs_server_trace_get_install, "GET inst ") \
247 EM(afs_server_trace_get_new_cbi, "GET cbi ") \270 EM(afs_server_trace_get_new_cbi, "GET cbi ") \
271 EM(afs_server_trace_get_probe, "GET probe") \
248 EM(afs_server_trace_give_up_cb, "giveup-cb") \272 EM(afs_server_trace_give_up_cb, "giveup-cb") \
249 EM(afs_server_trace_put_call, "PUT call ") \273 EM(afs_server_trace_put_call, "PUT call ") \
250 EM(afs_server_trace_put_cbi, "PUT cbi ") \274 EM(afs_server_trace_put_cbi, "PUT cbi ") \
251 EM(afs_server_trace_put_find_rsq, "PUT f-rsq") \275 EM(afs_server_trace_put_find_rsq, "PUT f-rsq") \
276 EM(afs_server_trace_put_probe, "PUT probe") \
252 EM(afs_server_trace_put_slist, "PUT slist") \277 EM(afs_server_trace_put_slist, "PUT slist") \
253 EM(afs_server_trace_put_slist_isort, "PUT isort") \278 EM(afs_server_trace_put_slist_isort, "PUT isort") \
254 EM(afs_server_trace_put_uuid_rsq, "PUT u-req") \279 EM(afs_server_trace_put_uuid_rsq, "PUT u-req") \
255 E_(afs_server_trace_update, "UPDATE")280 E_(afs_server_trace_update, "UPDATE")
256 281
282#define afs_volume_traces \
283 EM(afs_volume_trace_alloc, "ALLOC ") \
284 EM(afs_volume_trace_free, "FREE ") \
285 EM(afs_volume_trace_get_alloc_sbi, "GET sbi-alloc ") \
286 EM(afs_volume_trace_get_cell_insert, "GET cell-insrt") \
287 EM(afs_volume_trace_get_new_op, "GET op-new ") \
288 EM(afs_volume_trace_get_query_alias, "GET cell-alias") \
289 EM(afs_volume_trace_put_cell_dup, "PUT cell-dup ") \
290 EM(afs_volume_trace_put_cell_root, "PUT cell-root ") \
291 EM(afs_volume_trace_put_destroy_sbi, "PUT sbi-destry") \
292 EM(afs_volume_trace_put_free_fc, "PUT fc-free ") \
293 EM(afs_volume_trace_put_put_op, "PUT op-put ") \
294 EM(afs_volume_trace_put_query_alias, "PUT cell-alias") \
295 EM(afs_volume_trace_put_validate_fc, "PUT fc-validat") \
296 E_(afs_volume_trace_remove, "REMOVE ")
297
257#define afs_fs_operations \298#define afs_fs_operations \
258 EM(afs_FS_FetchData, "FS.FetchData") \299 EM(afs_FS_FetchData, "FS.FetchData") \
259 EM(afs_FS_FetchStatus, "FS.FetchStatus") \300 EM(afs_FS_FetchStatus, "FS.FetchStatus") \
@@ -310,6 +351,7 @@ enum afs_cb_break_reason { · 50 unmodified lines
310 EM(afs_VL_GetEntryByNameU, "VL.GetEntryByNameU") \351 EM(afs_VL_GetEntryByNameU, "VL.GetEntryByNameU") \
311 EM(afs_VL_GetAddrsU, "VL.GetAddrsU") \352 EM(afs_VL_GetAddrsU, "VL.GetAddrsU") \
312 EM(afs_YFSVL_GetEndpoints, "YFSVL.GetEndpoints") \353 EM(afs_YFSVL_GetEndpoints, "YFSVL.GetEndpoints") \
354 EM(afs_YFSVL_GetCellName, "YFSVL.GetCellName") \
313 E_(afs_VL_GetCapabilities, "VL.GetCapabilities")355 E_(afs_VL_GetCapabilities, "VL.GetCapabilities")
314 356
315#define afs_edit_dir_ops \357#define afs_edit_dir_ops \
@@ -339,6 +381,7 @@ enum afs_cb_break_reason { · 23 unmodified lines
339 EM(afs_eproto_bad_status, "BadStatus") \381 EM(afs_eproto_bad_status, "BadStatus") \
340 EM(afs_eproto_cb_count, "CbCount") \382 EM(afs_eproto_cb_count, "CbCount") \
341 EM(afs_eproto_cb_fid_count, "CbFidCount") \383 EM(afs_eproto_cb_fid_count, "CbFidCount") \
384 EM(afs_eproto_cellname_len, "CellNameLen") \
342 EM(afs_eproto_file_type, "FileTYpe") \385 EM(afs_eproto_file_type, "FileTYpe") \
343 EM(afs_eproto_ibulkst_cb_count, "IBS.CbCount") \386 EM(afs_eproto_ibulkst_cb_count, "IBS.CbCount") \
344 EM(afs_eproto_ibulkst_count, "IBS.FidCount") \387 EM(afs_eproto_ibulkst_count, "IBS.FidCount") \
@@ -636,7 +679,7 @@ TRACE_EVENT(afs_make_fs_calli, · 291 unmodified lines
636 679
637TRACE_EVENT(afs_make_fs_call1,680TRACE_EVENT(afs_make_fs_call1,
638 TP_PROTO(struct afs_call *call, const struct afs_fid *fid,681 TP_PROTO(struct afs_call *call, const struct afs_fid *fid,
639 const char *name),682 const struct qstr *name),
640 683
641 TP_ARGS(call, fid, name),684 TP_ARGS(call, fid, name),
642 685
@@ -648,8 +691,7 @@ TRACE_EVENT(afs_make_fs_call1, · 5 unmodified lines
648 ),691 ),
649 692
650 TP_fast_assign(693 TP_fast_assign(
651 int __len = strlen(name);694 unsigned int __len = min_t(unsigned int, name->len, 23);
652 __len = min(__len, 23);
653 __entry->call = call->debug_id;695 __entry->call = call->debug_id;
654 __entry->op = call->operation_ID;696 __entry->op = call->operation_ID;
655 if (fid) {697 if (fid) {
@@ -659,7 +701,7 @@ TRACE_EVENT(afs_make_fs_call1, · 3 unmodified lines
659 __entry->fid.vnode = 0;701 __entry->fid.vnode = 0;
660 __entry->fid.unique = 0;702 __entry->fid.unique = 0;
661 }703 }
662 memcpy(__entry->name, name, __len);704 memcpy(__entry->name, name->name, __len);
663 __entry->name[__len] = 0;705 __entry->name[__len] = 0;
664 ),706 ),
665 707
@@ -674,7 +716,7 @@ TRACE_EVENT(afs_make_fs_call1, · 8 unmodified lines
674 716
675TRACE_EVENT(afs_make_fs_call2,717TRACE_EVENT(afs_make_fs_call2,
676 TP_PROTO(struct afs_call *call, const struct afs_fid *fid,718 TP_PROTO(struct afs_call *call, const struct afs_fid *fid,
677 const char *name, const char *name2),719 const struct qstr *name, const struct qstr *name2),
678 720
679 TP_ARGS(call, fid, name, name2),721 TP_ARGS(call, fid, name, name2),
680 722
@@ -687,10 +729,8 @@ TRACE_EVENT(afs_make_fs_call2, · 6 unmodified lines
687 ),729 ),
688 730
689 TP_fast_assign(731 TP_fast_assign(
690 int __len = strlen(name);732 unsigned int __len = min_t(unsigned int, name->len, 23);
691 int __len2 = strlen(name2);733 unsigned int __len2 = min_t(unsigned int, name2->len, 23);
692 __len = min(__len, 23);
693 __len2 = min(__len2, 23);
694 __entry->call = call->debug_id;734 __entry->call = call->debug_id;
695 __entry->op = call->operation_ID;735 __entry->op = call->operation_ID;
696 if (fid) {736 if (fid) {
@@ -700,9 +740,9 @@ TRACE_EVENT(afs_make_fs_call2, · 3 unmodified lines
700 __entry->fid.vnode = 0;740 __entry->fid.vnode = 0;
701 __entry->fid.unique = 0;741 __entry->fid.unique = 0;
702 }742 }
703 memcpy(__entry->name, name, __len);743 memcpy(__entry->name, name->name, __len);
704 __entry->name[__len] = 0;744 __entry->name[__len] = 0;
705 memcpy(__entry->name2, name2, __len2);745 memcpy(__entry->name2, name2->name, __len2);
706 __entry->name2[__len2] = 0;746 __entry->name2[__len2] = 0;
707 ),747 ),
708 748
@@ -988,24 +1028,22 @@ TRACE_EVENT(afs_edit_dir, · 279 unmodified lines
988 );1028 );
989 1029
990TRACE_EVENT(afs_protocol_error,1030TRACE_EVENT(afs_protocol_error,
991 TP_PROTO(struct afs_call *call, int error, enum afs_eproto_cause cause),1031 TP_PROTO(struct afs_call *call, enum afs_eproto_cause cause),
992 1032
993 TP_ARGS(call, error, cause),1033 TP_ARGS(call, cause),
994 1034
995 TP_STRUCT__entry(1035 TP_STRUCT__entry(
996 __field(unsigned int, call )1036 __field(unsigned int, call )
997 __field(int, error )
998 __field(enum afs_eproto_cause, cause )1037 __field(enum afs_eproto_cause, cause )
999 ),1038 ),
1000 1039
1001 TP_fast_assign(1040 TP_fast_assign(
1002 __entry->call = call ? call->debug_id : 0;1041 __entry->call = call ? call->debug_id : 0;
1003 __entry->error = error;
1004 __entry->cause = cause;1042 __entry->cause = cause;
1005 ),1043 ),
1006 1044
1007 TP_printk("c=%08x r=%d %s",1045 TP_printk("c=%08x %s",
1008 __entry->call, __entry->error,1046 __entry->call,
1009 __print_symbolic(__entry->cause, afs_eproto_causes))1047 __print_symbolic(__entry->cause, afs_eproto_causes))
1010 );1048 );
1011 1049
@@ -1271,26 +1309,53 @@ TRACE_EVENT(afs_cb_miss, · 259 unmodified lines
1271 );1309 );
1272 1310
1273TRACE_EVENT(afs_server,1311TRACE_EVENT(afs_server,
1274 TP_PROTO(struct afs_server *server, int usage, enum afs_server_trace reason),1312 TP_PROTO(struct afs_server *server, int ref, int active,
1313 enum afs_server_trace reason),
1275 1314
1276 TP_ARGS(server, usage, reason),1315 TP_ARGS(server, ref, active, reason),
1277 1316
1278 TP_STRUCT__entry(1317 TP_STRUCT__entry(
1279 __field(unsigned int, server )1318 __field(unsigned int, server )
1280 __field(int, usage )1319 __field(int, ref )
1320 __field(int, active )
1281 __field(int, reason )1321 __field(int, reason )
1282 ),1322 ),
1283 1323
1284 TP_fast_assign(1324 TP_fast_assign(
1285 __entry->server = server->debug_id;1325 __entry->server = server->debug_id;
1286 __entry->usage = usage;1326 __entry->ref = ref;
1327 __entry->active = active;
1287 __entry->reason = reason;1328 __entry->reason = reason;
1288 ),1329 ),
1289 1330
1290 TP_printk("s=%08x %s u=%d",1331 TP_printk("s=%08x %s u=%d a=%d",
1291 __entry->server,1332 __entry->server,
1292 __print_symbolic(__entry->reason, afs_server_traces),1333 __print_symbolic(__entry->reason, afs_server_traces),
1293 __entry->usage)1334 __entry->ref,
1335 __entry->active)
1336 );
1337
1338TRACE_EVENT(afs_volume,
1339 TP_PROTO(afs_volid_t vid, int ref, enum afs_volume_trace reason),
1340
1341 TP_ARGS(vid, ref, reason),
1342
1343 TP_STRUCT__entry(
1344 __field(afs_volid_t, vid )
1345 __field(int, ref )
1346 __field(enum afs_volume_trace, reason )
1347 ),
1348
1349 TP_fast_assign(
1350 __entry->vid = vid;
1351 __entry->ref = ref;
1352 __entry->reason = reason;
1353 ),
1354
1355 TP_printk("V=%llx %s u=%d",
1356 __entry->vid,
1357 __print_symbolic(__entry->reason, afs_volume_traces),
1358 __entry->ref)
1294 );1359 );
1295 1360
1296#endif /* _TRACE_AFS_H */1361#endif /* _TRACE_AFS_H */
net/rxrpc/peer_event.c+3−0
@@ -271,6 +271,9 @@ static void rxrpc_store_error(struct rxrpc_peer *peer, · 270 unmodified lines
271 break;271 break;
272 272
273 case SO_EE_ORIGIN_ICMP6:273 case SO_EE_ORIGIN_ICMP6:
274 if (err == EACCES)
275 err = EHOSTUNREACH;
276 /* Fall through */
274 default:277 default:
275 _proto("Rx Received error report { orig=%u }", ee->ee_origin);278 _proto("Rx Received error report { orig=%u }", ee->ee_origin);
276 break;279 break;
net/rxrpc/proc.c+3−3
@@ -68,7 +68,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v) · 67 unmodified lines
68 "Proto Local "68 "Proto Local "
69 " Remote "69 " Remote "
70 " SvID ConnID CallID End Use State Abort "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 return 0;72 return 0;
73 }73 }
74 74
@@ -100,7 +100,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v) · 25 unmodified lines
100 rx_hard_ack = READ_ONCE(call->rx_hard_ack);100 rx_hard_ack = READ_ONCE(call->rx_hard_ack);
101 seq_printf(seq,101 seq_printf(seq,
102 "UDP %-47.47s %-47.47s %4x %08x %08x %s %3u"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 lbuff,104 lbuff,
105 rbuff,105 rbuff,
106 call->service_id,106 call->service_id,
@@ -110,7 +110,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v) · 3 unmodified lines
110 atomic_read(&call->usage),110 atomic_read(&call->usage),
111 rxrpc_call_states[call->state],111 rxrpc_call_states[call->state],
112 call->abort_code,112 call->abort_code,
113 call->user_call_ID,113 call->debug_id,
114 tx_hard_ack, READ_ONCE(call->tx_top) - tx_hard_ack,114 tx_hard_ack, READ_ONCE(call->tx_top) - tx_hard_ack,
115 rx_hard_ack, READ_ONCE(call->rx_top) - rx_hard_ack,115 rx_hard_ack, READ_ONCE(call->rx_top) - rx_hard_ack,
116 call->rx_serial,116 call->rx_serial,