Skip to content

Commit f28fc20

Browse files
dhowellsbrauner
authored andcommitted
afs: Eliminate afs_read
Now that directory and symlink reads go through netfslib, the afs_read struct is mostly redundant with almost all data duplicated in the netfs_io_request and netfs_io_subrequest structs that are also available any time we're doing a fetch. Eliminate afs_read by moving the one field we still need there to the afs_call struct (we may be given a different amount of data than what we asked for and have to track what remains of that) and using the netfs_io_subrequest directly instead. Signed-off-by: David Howells <[email protected]> Link: https://lore.kernel.org/r/[email protected] cc: Marc Dionne <[email protected]> cc: [email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent eae9e78 commit f28fc20

File tree

6 files changed

+72
-165
lines changed

6 files changed

+72
-165
lines changed

fs/afs/file.c

Lines changed: 18 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -200,50 +200,12 @@ int afs_release(struct inode *inode, struct file *file)
200200
return ret;
201201
}
202202

203-
/*
204-
* Allocate a new read record.
205-
*/
206-
struct afs_read *afs_alloc_read(gfp_t gfp)
207-
{
208-
struct afs_read *req;
209-
210-
req = kzalloc(sizeof(struct afs_read), gfp);
211-
if (req)
212-
refcount_set(&req->usage, 1);
213-
214-
return req;
215-
}
216-
217-
/*
218-
* Dispose of a ref to a read record.
219-
*/
220-
void afs_put_read(struct afs_read *req)
221-
{
222-
if (refcount_dec_and_test(&req->usage)) {
223-
if (req->cleanup)
224-
req->cleanup(req);
225-
key_put(req->key);
226-
kfree(req);
227-
}
228-
}
229-
230203
static void afs_fetch_data_notify(struct afs_operation *op)
231204
{
232-
struct afs_read *req = op->fetch.req;
233-
struct netfs_io_subrequest *subreq = req->subreq;
234-
int error = afs_op_error(op);
235-
236-
req->error = error;
237-
if (subreq) {
238-
subreq->rreq->i_size = req->file_size;
239-
if (req->pos + req->actual_len >= req->file_size)
240-
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
241-
subreq->error = error;
242-
netfs_read_subreq_terminated(subreq);
243-
req->subreq = NULL;
244-
} else if (req->done) {
245-
req->done(req);
246-
}
205+
struct netfs_io_subrequest *subreq = op->fetch.subreq;
206+
207+
subreq->error = afs_op_error(op);
208+
netfs_read_subreq_terminated(subreq);
247209
}
248210

249211
static void afs_fetch_data_success(struct afs_operation *op)
@@ -253,7 +215,7 @@ static void afs_fetch_data_success(struct afs_operation *op)
253215
_enter("op=%08x", op->debug_id);
254216
afs_vnode_commit_status(op, &op->file[0]);
255217
afs_stat_v(vnode, n_fetches);
256-
atomic_long_add(op->fetch.req->actual_len, &op->net->n_fetch_bytes);
218+
atomic_long_add(op->fetch.subreq->transferred, &op->net->n_fetch_bytes);
257219
afs_fetch_data_notify(op);
258220
}
259221

@@ -265,11 +227,10 @@ static void afs_fetch_data_aborted(struct afs_operation *op)
265227

266228
static void afs_fetch_data_put(struct afs_operation *op)
267229
{
268-
op->fetch.req->error = afs_op_error(op);
269-
afs_put_read(op->fetch.req);
230+
op->fetch.subreq->error = afs_op_error(op);
270231
}
271232

272-
static const struct afs_operation_ops afs_fetch_data_operation = {
233+
const struct afs_operation_ops afs_fetch_data_operation = {
273234
.issue_afs_rpc = afs_fs_fetch_data,
274235
.issue_yfs_rpc = yfs_fs_fetch_data,
275236
.success = afs_fetch_data_success,
@@ -281,55 +242,34 @@ static const struct afs_operation_ops afs_fetch_data_operation = {
281242
/*
282243
* Fetch file data from the volume.
283244
*/
284-
int afs_fetch_data(struct afs_vnode *vnode, struct afs_read *req)
245+
static void afs_read_worker(struct work_struct *work)
285246
{
247+
struct netfs_io_subrequest *subreq = container_of(work, struct netfs_io_subrequest, work);
286248
struct afs_operation *op;
249+
struct afs_vnode *vnode = AFS_FS_I(subreq->rreq->inode);
250+
struct key *key = subreq->rreq->netfs_priv;
287251

288252
_enter("%s{%llx:%llu.%u},%x,,,",
289253
vnode->volume->name,
290254
vnode->fid.vid,
291255
vnode->fid.vnode,
292256
vnode->fid.unique,
293-
key_serial(req->key));
257+
key_serial(key));
294258

295-
op = afs_alloc_operation(req->key, vnode->volume);
259+
op = afs_alloc_operation(key, vnode->volume);
296260
if (IS_ERR(op)) {
297-
if (req->subreq) {
298-
req->subreq->error = PTR_ERR(op);
299-
netfs_read_subreq_terminated(req->subreq);
300-
}
301-
return PTR_ERR(op);
261+
subreq->error = PTR_ERR(op);
262+
netfs_read_subreq_terminated(subreq);
263+
return;
302264
}
303265

304266
afs_op_set_vnode(op, 0, vnode);
305267

306-
op->fetch.req = afs_get_read(req);
268+
op->fetch.subreq = subreq;
307269
op->ops = &afs_fetch_data_operation;
308-
return afs_do_sync_operation(op);
309-
}
310-
311-
static void afs_read_worker(struct work_struct *work)
312-
{
313-
struct netfs_io_subrequest *subreq = container_of(work, struct netfs_io_subrequest, work);
314-
struct afs_vnode *vnode = AFS_FS_I(subreq->rreq->inode);
315-
struct afs_read *fsreq;
316-
317-
fsreq = afs_alloc_read(GFP_NOFS);
318-
if (!fsreq) {
319-
subreq->error = -ENOMEM;
320-
return netfs_read_subreq_terminated(subreq);
321-
}
322-
323-
fsreq->subreq = subreq;
324-
fsreq->pos = subreq->start + subreq->transferred;
325-
fsreq->len = subreq->len - subreq->transferred;
326-
fsreq->key = key_get(subreq->rreq->netfs_priv);
327-
fsreq->vnode = vnode;
328-
fsreq->iter = &subreq->io_iter;
329270

330271
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
331-
afs_fetch_data(fsreq->vnode, fsreq);
332-
afs_put_read(fsreq);
272+
afs_do_sync_operation(op);
333273
}
334274

335275
static void afs_issue_read(struct netfs_io_subrequest *subreq)

fs/afs/fsclient.c

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -301,19 +301,19 @@ void afs_fs_fetch_status(struct afs_operation *op)
301301
static int afs_deliver_fs_fetch_data(struct afs_call *call)
302302
{
303303
struct afs_operation *op = call->op;
304+
struct netfs_io_subrequest *subreq = op->fetch.subreq;
304305
struct afs_vnode_param *vp = &op->file[0];
305-
struct afs_read *req = op->fetch.req;
306306
const __be32 *bp;
307307
size_t count_before;
308308
int ret;
309309

310310
_enter("{%u,%zu,%zu/%llu}",
311311
call->unmarshall, call->iov_len, iov_iter_count(call->iter),
312-
req->actual_len);
312+
call->remaining);
313313

314314
switch (call->unmarshall) {
315315
case 0:
316-
req->actual_len = 0;
316+
call->remaining = 0;
317317
call->unmarshall++;
318318
if (call->operation_ID == FSFETCHDATA64) {
319319
afs_extract_to_tmp64(call);
@@ -323,8 +323,8 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
323323
}
324324
fallthrough;
325325

326-
/* Extract the returned data length into
327-
* ->actual_len. This may indicate more or less data than was
326+
/* Extract the returned data length into ->remaining.
327+
* This may indicate more or less data than was
328328
* requested will be returned.
329329
*/
330330
case 1:
@@ -333,42 +333,41 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
333333
if (ret < 0)
334334
return ret;
335335

336-
req->actual_len = be64_to_cpu(call->tmp64);
337-
_debug("DATA length: %llu", req->actual_len);
336+
call->remaining = be64_to_cpu(call->tmp64);
337+
_debug("DATA length: %llu", call->remaining);
338338

339-
if (req->actual_len == 0)
339+
if (call->remaining == 0)
340340
goto no_more_data;
341341

342-
call->iter = req->iter;
343-
call->iov_len = min(req->actual_len, req->len);
342+
call->iter = &subreq->io_iter;
343+
call->iov_len = umin(call->remaining, subreq->len - subreq->transferred);
344344
call->unmarshall++;
345345
fallthrough;
346346

347347
/* extract the returned data */
348348
case 2:
349349
count_before = call->iov_len;
350-
_debug("extract data %zu/%llu", count_before, req->actual_len);
350+
_debug("extract data %zu/%llu", count_before, call->remaining);
351351

352352
ret = afs_extract_data(call, true);
353-
if (req->subreq) {
354-
req->subreq->transferred += count_before - call->iov_len;
355-
netfs_read_subreq_progress(req->subreq);
356-
}
353+
subreq->transferred += count_before - call->iov_len;
354+
call->remaining -= count_before - call->iov_len;
355+
netfs_read_subreq_progress(subreq);
357356
if (ret < 0)
358357
return ret;
359358

360359
call->iter = &call->def_iter;
361-
if (req->actual_len <= req->len)
360+
if (call->remaining)
362361
goto no_more_data;
363362

364363
/* Discard any excess data the server gave us */
365-
afs_extract_discard(call, req->actual_len - req->len);
364+
afs_extract_discard(call, call->remaining);
366365
call->unmarshall = 3;
367366
fallthrough;
368367

369368
case 3:
370369
_debug("extract discard %zu/%llu",
371-
iov_iter_count(call->iter), req->actual_len - req->len);
370+
iov_iter_count(call->iter), call->remaining);
372371

373372
ret = afs_extract_data(call, true);
374373
if (ret < 0)
@@ -390,8 +389,8 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
390389
xdr_decode_AFSCallBack(&bp, call, &vp->scb);
391390
xdr_decode_AFSVolSync(&bp, &op->volsync);
392391

393-
req->data_version = vp->scb.status.data_version;
394-
req->file_size = vp->scb.status.size;
392+
if (subreq->start + subreq->transferred >= vp->scb.status.size)
393+
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
395394

396395
call->unmarshall++;
397396
fallthrough;
@@ -426,8 +425,8 @@ static const struct afs_call_type afs_RXFSFetchData64 = {
426425
*/
427426
static void afs_fs_fetch_data64(struct afs_operation *op)
428427
{
428+
struct netfs_io_subrequest *subreq = op->fetch.subreq;
429429
struct afs_vnode_param *vp = &op->file[0];
430-
struct afs_read *req = op->fetch.req;
431430
struct afs_call *call;
432431
__be32 *bp;
433432

@@ -443,10 +442,10 @@ static void afs_fs_fetch_data64(struct afs_operation *op)
443442
bp[1] = htonl(vp->fid.vid);
444443
bp[2] = htonl(vp->fid.vnode);
445444
bp[3] = htonl(vp->fid.unique);
446-
bp[4] = htonl(upper_32_bits(req->pos));
447-
bp[5] = htonl(lower_32_bits(req->pos));
445+
bp[4] = htonl(upper_32_bits(subreq->start + subreq->transferred));
446+
bp[5] = htonl(lower_32_bits(subreq->start + subreq->transferred));
448447
bp[6] = 0;
449-
bp[7] = htonl(lower_32_bits(req->len));
448+
bp[7] = htonl(lower_32_bits(subreq->len - subreq->transferred));
450449

451450
call->fid = vp->fid;
452451
trace_afs_make_fs_call(call, &vp->fid);
@@ -458,9 +457,9 @@ static void afs_fs_fetch_data64(struct afs_operation *op)
458457
*/
459458
void afs_fs_fetch_data(struct afs_operation *op)
460459
{
460+
struct netfs_io_subrequest *subreq = op->fetch.subreq;
461461
struct afs_vnode_param *vp = &op->file[0];
462462
struct afs_call *call;
463-
struct afs_read *req = op->fetch.req;
464463
__be32 *bp;
465464

466465
if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))
@@ -472,16 +471,14 @@ void afs_fs_fetch_data(struct afs_operation *op)
472471
if (!call)
473472
return afs_op_nomem(op);
474473

475-
req->call_debug_id = call->debug_id;
476-
477474
/* marshall the parameters */
478475
bp = call->request;
479476
bp[0] = htonl(FSFETCHDATA);
480477
bp[1] = htonl(vp->fid.vid);
481478
bp[2] = htonl(vp->fid.vnode);
482479
bp[3] = htonl(vp->fid.unique);
483-
bp[4] = htonl(lower_32_bits(req->pos));
484-
bp[5] = htonl(lower_32_bits(req->len));
480+
bp[4] = htonl(lower_32_bits(subreq->start + subreq->transferred));
481+
bp[5] = htonl(lower_32_bits(subreq->len + subreq->transferred));
485482

486483
call->fid = vp->fid;
487484
trace_afs_make_fs_call(call, &vp->fid);

fs/afs/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ static void afs_apply_status(struct afs_operation *op,
317317
inode_set_ctime_to_ts(inode, t);
318318
inode_set_atime_to_ts(inode, t);
319319
}
320+
if (op->ops == &afs_fetch_data_operation)
321+
op->fetch.subreq->rreq->i_size = status->size;
320322
}
321323
}
322324

fs/afs/internal.h

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ struct afs_call {
163163
spinlock_t state_lock;
164164
int error; /* error code */
165165
u32 abort_code; /* Remote abort ID or 0 */
166+
unsigned long long remaining; /* How much is left to receive */
166167
unsigned int max_lifespan; /* Maximum lifespan in secs to set if not 0 */
167168
unsigned request_size; /* size of request data */
168169
unsigned reply_max; /* maximum size of reply */
@@ -232,28 +233,6 @@ static inline struct key *afs_file_key(struct file *file)
232233
return af->key;
233234
}
234235

235-
/*
236-
* Record of an outstanding read operation on a vnode.
237-
*/
238-
struct afs_read {
239-
loff_t pos; /* Where to start reading */
240-
loff_t len; /* How much we're asking for */
241-
loff_t actual_len; /* How much we're actually getting */
242-
loff_t file_size; /* File size returned by server */
243-
struct key *key; /* The key to use to reissue the read */
244-
struct afs_vnode *vnode; /* The file being read into. */
245-
struct netfs_io_subrequest *subreq; /* Fscache helper read request this belongs to */
246-
afs_dataversion_t data_version; /* Version number returned by server */
247-
refcount_t usage;
248-
unsigned int call_debug_id;
249-
unsigned int nr_pages;
250-
int error;
251-
void (*done)(struct afs_read *);
252-
void (*cleanup)(struct afs_read *);
253-
struct iov_iter *iter; /* Iterator representing the buffer */
254-
struct iov_iter def_iter; /* Default iterator */
255-
};
256-
257236
/*
258237
* AFS superblock private data
259238
* - there's one superblock per volume
@@ -911,7 +890,7 @@ struct afs_operation {
911890
bool new_negative;
912891
} rename;
913892
struct {
914-
struct afs_read *req;
893+
struct netfs_io_subrequest *subreq;
915894
} fetch;
916895
struct {
917896
afs_lock_type_t type;
@@ -1118,21 +1097,13 @@ extern void afs_dynroot_depopulate(struct super_block *);
11181097
extern const struct address_space_operations afs_file_aops;
11191098
extern const struct inode_operations afs_file_inode_operations;
11201099
extern const struct file_operations afs_file_operations;
1100+
extern const struct afs_operation_ops afs_fetch_data_operation;
11211101
extern const struct netfs_request_ops afs_req_ops;
11221102

11231103
extern int afs_cache_wb_key(struct afs_vnode *, struct afs_file *);
11241104
extern void afs_put_wb_key(struct afs_wb_key *);
11251105
extern int afs_open(struct inode *, struct file *);
11261106
extern int afs_release(struct inode *, struct file *);
1127-
extern int afs_fetch_data(struct afs_vnode *, struct afs_read *);
1128-
extern struct afs_read *afs_alloc_read(gfp_t);
1129-
extern void afs_put_read(struct afs_read *);
1130-
1131-
static inline struct afs_read *afs_get_read(struct afs_read *req)
1132-
{
1133-
refcount_inc(&req->usage);
1134-
return req;
1135-
}
11361107

11371108
/*
11381109
* flock.c

0 commit comments

Comments
 (0)