@@ -29,43 +29,39 @@ static void afs_pages_written_back(struct afs_vnode *vnode, loff_t start, unsign
2929
3030/*
3131 * 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.
3435 */
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 )
3737{
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 ;
4144
4245 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 ) ;
4548 else
46- p = vnode -> wb_keys . next ;
49+ wbk = list_first_entry ( & vnode -> wb_keys , struct afs_wb_key , vnode_link ) ;
4750
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 ) {
5052 _debug ("wbk %u" , key_serial (wbk -> key ));
51- ret2 = key_validate (wbk -> key );
52- if (ret2 == 0 ) {
53+ if (key_validate (wbk -> key ) == 0 ) {
5354 refcount_inc (& wbk -> usage );
55+ wreq -> netfs_priv = key_get (wbk -> key );
56+ wreq -> netfs_priv2 = wbk ;
5457 _debug ("USE WB KEY %u" , key_serial (wbk -> key ));
5558 break ;
5659 }
57-
58- wbk = NULL ;
59- if (ret == - ENOKEY )
60- ret = ret2 ;
61- p = p -> next ;
6260 }
6361
6462 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 );
6965}
7066
7167static void afs_store_data_success (struct afs_operation * op )
@@ -88,72 +84,91 @@ static const struct afs_operation_ops afs_store_data_operation = {
8884};
8985
9086/*
91- * write to a file
87+ * Prepare a subrequest to write to the server. This sets the max_len
88+ * parameter.
9289 */
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 )
9491{
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 ;
95105 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 ;
98109 int ret = - ENOKEY ;
99110
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 ,
101113 vnode -> volume -> name ,
102114 vnode -> fid .vid ,
103115 vnode -> fid .vnode ,
104116 vnode -> fid .unique ,
105- size , pos );
117+ pos , len );
106118
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);
112122
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);
117126 }
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);
118132
119133 afs_op_set_vnode (op , 0 , vnode );
120- op -> file [0 ].dv_delta = 1 ;
134+ op -> file [0 ].dv_delta = 1 ;
121135 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 ;
126140
127- try_next_key :
128141 afs_begin_vnode_operation (op );
129142
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 );
133146
134147 afs_wait_for_operation (op );
135-
136- switch (afs_op_error ( op ) ) {
148+ ret = afs_put_operation ( op );
149+ switch (ret ) {
137150 case - EACCES :
138151 case - EPERM :
139152 case - ENOKEY :
140153 case - EKEYEXPIRED :
141154 case - EKEYREJECTED :
142155 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 );
151161 break ;
152162 }
153163
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 );
157172}
158173
159174/*
@@ -162,52 +177,32 @@ static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t
162177 */
163178void afs_begin_writeback (struct netfs_io_request * wreq )
164179{
180+ afs_get_writeback_key (wreq );
165181 wreq -> io_streams [0 ].avail = true;
166182}
167183
168184/*
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.
182187 */
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 )
184189{
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 );
195193
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 ;
199205 }
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 );
211206}
212207
213208/*
0 commit comments