@@ -29,43 +29,39 @@ static void afs_pages_written_back(struct afs_vnode *vnode, loff_t start, unsign
29
29
30
30
/*
31
31
* Find a key to use for the writeback. We cached the keys used to author the
32
- * writes on the vnode. *_wbk will contain the last writeback key used or NULL
33
- * and we need to start from there if it's set.
32
+ * writes on the vnode. wreq->netfs_priv2 will contain the last writeback key
33
+ * record used or NULL and we need to start from there if it's set.
34
+ * wreq->netfs_priv will be set to the key itself or NULL.
34
35
*/
35
- static int afs_get_writeback_key (struct afs_vnode * vnode ,
36
- struct afs_wb_key * * _wbk )
36
+ static void afs_get_writeback_key (struct netfs_io_request * wreq )
37
37
{
38
- struct afs_wb_key * wbk = NULL ;
39
- struct list_head * p ;
40
- int ret = - ENOKEY , ret2 ;
38
+ struct afs_wb_key * wbk , * old = wreq -> netfs_priv2 ;
39
+ struct afs_vnode * vnode = AFS_FS_I (wreq -> inode );
40
+
41
+ key_put (wreq -> netfs_priv );
42
+ wreq -> netfs_priv = NULL ;
43
+ wreq -> netfs_priv2 = NULL ;
41
44
42
45
spin_lock (& vnode -> wb_lock );
43
- if (* _wbk )
44
- p = ( * _wbk ) -> vnode_link . next ;
46
+ if (old )
47
+ wbk = list_next_entry ( old , vnode_link ) ;
45
48
else
46
- p = vnode -> wb_keys . next ;
49
+ wbk = list_first_entry ( & vnode -> wb_keys , struct afs_wb_key , vnode_link ) ;
47
50
48
- while (p != & vnode -> wb_keys ) {
49
- wbk = list_entry (p , struct afs_wb_key , vnode_link );
51
+ list_for_each_entry_from (wbk , & vnode -> wb_keys , vnode_link ) {
50
52
_debug ("wbk %u" , key_serial (wbk -> key ));
51
- ret2 = key_validate (wbk -> key );
52
- if (ret2 == 0 ) {
53
+ if (key_validate (wbk -> key ) == 0 ) {
53
54
refcount_inc (& wbk -> usage );
55
+ wreq -> netfs_priv = key_get (wbk -> key );
56
+ wreq -> netfs_priv2 = wbk ;
54
57
_debug ("USE WB KEY %u" , key_serial (wbk -> key ));
55
58
break ;
56
59
}
57
-
58
- wbk = NULL ;
59
- if (ret == - ENOKEY )
60
- ret = ret2 ;
61
- p = p -> next ;
62
60
}
63
61
64
62
spin_unlock (& vnode -> wb_lock );
65
- if (* _wbk )
66
- afs_put_wb_key (* _wbk );
67
- * _wbk = wbk ;
68
- return 0 ;
63
+
64
+ afs_put_wb_key (old );
69
65
}
70
66
71
67
static void afs_store_data_success (struct afs_operation * op )
@@ -88,72 +84,91 @@ static const struct afs_operation_ops afs_store_data_operation = {
88
84
};
89
85
90
86
/*
91
- * write to a file
87
+ * Prepare a subrequest to write to the server. This sets the max_len
88
+ * parameter.
92
89
*/
93
- static int afs_store_data (struct afs_vnode * vnode , struct iov_iter * iter , loff_t pos )
90
+ void afs_prepare_write (struct netfs_io_subrequest * subreq )
94
91
{
92
+ //if (test_bit(NETFS_SREQ_RETRYING, &subreq->flags))
93
+ // subreq->max_len = 512 * 1024;
94
+ //else
95
+ subreq -> max_len = 256 * 1024 * 1024 ;
96
+ }
97
+
98
+ /*
99
+ * Issue a subrequest to write to the server.
100
+ */
101
+ static void afs_issue_write_worker (struct work_struct * work )
102
+ {
103
+ struct netfs_io_subrequest * subreq = container_of (work , struct netfs_io_subrequest , work );
104
+ struct netfs_io_request * wreq = subreq -> rreq ;
95
105
struct afs_operation * op ;
96
- struct afs_wb_key * wbk = NULL ;
97
- loff_t size = iov_iter_count (iter );
106
+ struct afs_vnode * vnode = AFS_FS_I (wreq -> inode );
107
+ unsigned long long pos = subreq -> start + subreq -> transferred ;
108
+ size_t len = subreq -> len - subreq -> transferred ;
98
109
int ret = - ENOKEY ;
99
110
100
- _enter ("%s{%llx:%llu.%u},%llx,%llx" ,
111
+ _enter ("R=%x[%x],%s{%llx:%llu.%u},%llx,%zx" ,
112
+ wreq -> debug_id , subreq -> debug_index ,
101
113
vnode -> volume -> name ,
102
114
vnode -> fid .vid ,
103
115
vnode -> fid .vnode ,
104
116
vnode -> fid .unique ,
105
- size , pos );
117
+ pos , len );
106
118
107
- ret = afs_get_writeback_key (vnode , & wbk );
108
- if (ret ) {
109
- _leave (" = %d [no keys]" , ret );
110
- return ret ;
111
- }
119
+ #if 0 // Error injection
120
+ if (subreq -> debug_index == 3 )
121
+ return netfs_write_subrequest_terminated (subreq , - ENOANO , false);
112
122
113
- op = afs_alloc_operation (wbk -> key , vnode -> volume );
114
- if (IS_ERR (op )) {
115
- afs_put_wb_key (wbk );
116
- return - ENOMEM ;
123
+ if (!test_bit (NETFS_SREQ_RETRYING , & subreq -> flags )) {
124
+ set_bit (NETFS_SREQ_NEED_RETRY , & subreq -> flags );
125
+ return netfs_write_subrequest_terminated (subreq , - EAGAIN , false);
117
126
}
127
+ #endif
128
+
129
+ op = afs_alloc_operation (wreq -> netfs_priv , vnode -> volume );
130
+ if (IS_ERR (op ))
131
+ return netfs_write_subrequest_terminated (subreq , - EAGAIN , false);
118
132
119
133
afs_op_set_vnode (op , 0 , vnode );
120
- op -> file [0 ].dv_delta = 1 ;
134
+ op -> file [0 ].dv_delta = 1 ;
121
135
op -> file [0 ].modification = true;
122
- op -> store .pos = pos ;
123
- op -> store .size = size ;
124
- op -> flags |= AFS_OPERATION_UNINTR ;
125
- op -> ops = & afs_store_data_operation ;
136
+ op -> store .pos = pos ;
137
+ op -> store .size = len ;
138
+ op -> flags |= AFS_OPERATION_UNINTR ;
139
+ op -> ops = & afs_store_data_operation ;
126
140
127
- try_next_key :
128
141
afs_begin_vnode_operation (op );
129
142
130
- op -> store .write_iter = iter ;
131
- op -> store .i_size = max (pos + size , vnode -> netfs .remote_i_size );
132
- op -> mtime = inode_get_mtime (& vnode -> netfs .inode );
143
+ op -> store .write_iter = & subreq -> io_iter ;
144
+ op -> store .i_size = umax (pos + len , vnode -> netfs .remote_i_size );
145
+ op -> mtime = inode_get_mtime (& vnode -> netfs .inode );
133
146
134
147
afs_wait_for_operation (op );
135
-
136
- switch (afs_op_error ( op ) ) {
148
+ ret = afs_put_operation ( op );
149
+ switch (ret ) {
137
150
case - EACCES :
138
151
case - EPERM :
139
152
case - ENOKEY :
140
153
case - EKEYEXPIRED :
141
154
case - EKEYREJECTED :
142
155
case - EKEYREVOKED :
143
- _debug ("next" );
144
-
145
- ret = afs_get_writeback_key (vnode , & wbk );
146
- if (ret == 0 ) {
147
- key_put (op -> key );
148
- op -> key = key_get (wbk -> key );
149
- goto try_next_key ;
150
- }
156
+ /* If there are more keys we can try, use the retry algorithm
157
+ * to rotate the keys.
158
+ */
159
+ if (wreq -> netfs_priv2 )
160
+ set_bit (NETFS_SREQ_NEED_RETRY , & subreq -> flags );
151
161
break ;
152
162
}
153
163
154
- afs_put_wb_key (wbk );
155
- _leave (" = %d" , afs_op_error (op ));
156
- return afs_put_operation (op );
164
+ netfs_write_subrequest_terminated (subreq , ret < 0 ? ret : subreq -> len , false);
165
+ }
166
+
167
+ void afs_issue_write (struct netfs_io_subrequest * subreq )
168
+ {
169
+ subreq -> work .func = afs_issue_write_worker ;
170
+ if (!queue_work (system_unbound_wq , & subreq -> work ))
171
+ WARN_ON_ONCE (1 );
157
172
}
158
173
159
174
/*
@@ -162,52 +177,32 @@ static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t
162
177
*/
163
178
void afs_begin_writeback (struct netfs_io_request * wreq )
164
179
{
180
+ afs_get_writeback_key (wreq );
165
181
wreq -> io_streams [0 ].avail = true;
166
182
}
167
183
168
184
/*
169
- * Prepare a subrequest to write to the server. This sets the max_len
170
- * parameter.
171
- */
172
- void afs_prepare_write (struct netfs_io_subrequest * subreq )
173
- {
174
- //if (test_bit(NETFS_SREQ_RETRYING, &subreq->flags))
175
- // subreq->max_len = 512 * 1024;
176
- //else
177
- subreq -> max_len = 256 * 1024 * 1024 ;
178
- }
179
-
180
- /*
181
- * Issue a subrequest to write to the server.
185
+ * Prepare to retry the writes in request. Use this to try rotating the
186
+ * available writeback keys.
182
187
*/
183
- static void afs_issue_write_worker (struct work_struct * work )
188
+ void afs_retry_request (struct netfs_io_request * wreq , struct netfs_io_stream * stream )
184
189
{
185
- struct netfs_io_subrequest * subreq = container_of (work , struct netfs_io_subrequest , work );
186
- struct afs_vnode * vnode = AFS_FS_I (subreq -> rreq -> inode );
187
- ssize_t ret ;
188
-
189
- _enter ("%x[%x],%zx" ,
190
- subreq -> rreq -> debug_id , subreq -> debug_index , subreq -> io_iter .count );
191
-
192
- #if 0 // Error injection
193
- if (subreq -> debug_index == 3 )
194
- return netfs_write_subrequest_terminated (subreq , - ENOANO , false);
190
+ struct netfs_io_subrequest * subreq =
191
+ list_first_entry (& stream -> subrequests ,
192
+ struct netfs_io_subrequest , rreq_link );
195
193
196
- if (!test_bit (NETFS_SREQ_RETRYING , & subreq -> flags )) {
197
- set_bit (NETFS_SREQ_NEED_RETRY , & subreq -> flags );
198
- return netfs_write_subrequest_terminated (subreq , - EAGAIN , false);
194
+ switch (subreq -> error ) {
195
+ case - EACCES :
196
+ case - EPERM :
197
+ case - ENOKEY :
198
+ case - EKEYEXPIRED :
199
+ case - EKEYREJECTED :
200
+ case - EKEYREVOKED :
201
+ afs_get_writeback_key (wreq );
202
+ if (!wreq -> netfs_priv )
203
+ stream -> failed = true;
204
+ break ;
199
205
}
200
- #endif
201
-
202
- ret = afs_store_data (vnode , & subreq -> io_iter , subreq -> start );
203
- netfs_write_subrequest_terminated (subreq , ret < 0 ? ret : subreq -> len , false);
204
- }
205
-
206
- void afs_issue_write (struct netfs_io_subrequest * subreq )
207
- {
208
- subreq -> work .func = afs_issue_write_worker ;
209
- if (!queue_work (system_unbound_wq , & subreq -> work ))
210
- WARN_ON_ONCE (1 );
211
206
}
212
207
213
208
/*
0 commit comments