Skip to content

Commit d70b910

Browse files
piastrysmfrench
authored andcommitted
CIFS: Add copy into pages callback for a read operation
Since we have two different types of reads (pagecache and direct) we need to process such responses differently after decryption of a packet. The change allows to specify a callback that copies a read payload data into preallocated pages. Signed-off-by: Pavel Shilovsky <[email protected]>
1 parent 9b7c18a commit d70b910

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

fs/cifs/cifsglob.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,9 @@ struct cifs_readdata {
11291129
int (*read_into_pages)(struct TCP_Server_Info *server,
11301130
struct cifs_readdata *rdata,
11311131
unsigned int len);
1132+
int (*copy_into_pages)(struct TCP_Server_Info *server,
1133+
struct cifs_readdata *rdata,
1134+
struct iov_iter *iter);
11321135
struct kvec iov[2];
11331136
unsigned int pagesz;
11341137
unsigned int tailsz;

fs/cifs/file.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,8 +2911,9 @@ cifs_uncached_readv_complete(struct work_struct *work)
29112911
}
29122912

29132913
static int
2914-
cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
2915-
struct cifs_readdata *rdata, unsigned int len)
2914+
uncached_fill_pages(struct TCP_Server_Info *server,
2915+
struct cifs_readdata *rdata, struct iov_iter *iter,
2916+
unsigned int len)
29162917
{
29172918
int result = 0;
29182919
unsigned int i;
@@ -2941,7 +2942,10 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
29412942
rdata->tailsz = len;
29422943
len = 0;
29432944
}
2944-
result = cifs_read_page_from_socket(server, page, n);
2945+
if (iter)
2946+
result = copy_page_from_iter(page, 0, n, iter);
2947+
else
2948+
result = cifs_read_page_from_socket(server, page, n);
29452949
if (result < 0)
29462950
break;
29472951

@@ -2952,6 +2956,21 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
29522956
rdata->got_bytes : result;
29532957
}
29542958

2959+
static int
2960+
cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
2961+
struct cifs_readdata *rdata, unsigned int len)
2962+
{
2963+
return uncached_fill_pages(server, rdata, NULL, len);
2964+
}
2965+
2966+
static int
2967+
cifs_uncached_copy_into_pages(struct TCP_Server_Info *server,
2968+
struct cifs_readdata *rdata,
2969+
struct iov_iter *iter)
2970+
{
2971+
return uncached_fill_pages(server, rdata, iter, iter->count);
2972+
}
2973+
29552974
static int
29562975
cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
29572976
struct cifs_sb_info *cifs_sb, struct list_head *rdata_list)
@@ -2999,6 +3018,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
29993018
rdata->pid = pid;
30003019
rdata->pagesz = PAGE_SIZE;
30013020
rdata->read_into_pages = cifs_uncached_read_into_pages;
3021+
rdata->copy_into_pages = cifs_uncached_copy_into_pages;
30023022
rdata->credits = credits;
30033023

30043024
if (!rdata->cfile->invalidHandle ||
@@ -3349,8 +3369,9 @@ cifs_readv_complete(struct work_struct *work)
33493369
}
33503370

33513371
static int
3352-
cifs_readpages_read_into_pages(struct TCP_Server_Info *server,
3353-
struct cifs_readdata *rdata, unsigned int len)
3372+
readpages_fill_pages(struct TCP_Server_Info *server,
3373+
struct cifs_readdata *rdata, struct iov_iter *iter,
3374+
unsigned int len)
33543375
{
33553376
int result = 0;
33563377
unsigned int i;
@@ -3404,7 +3425,10 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server,
34043425
continue;
34053426
}
34063427

3407-
result = cifs_read_page_from_socket(server, page, n);
3428+
if (iter)
3429+
result = copy_page_from_iter(page, 0, n, iter);
3430+
else
3431+
result = cifs_read_page_from_socket(server, page, n);
34083432
if (result < 0)
34093433
break;
34103434

@@ -3415,6 +3439,21 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server,
34153439
rdata->got_bytes : result;
34163440
}
34173441

3442+
static int
3443+
cifs_readpages_read_into_pages(struct TCP_Server_Info *server,
3444+
struct cifs_readdata *rdata, unsigned int len)
3445+
{
3446+
return readpages_fill_pages(server, rdata, NULL, len);
3447+
}
3448+
3449+
static int
3450+
cifs_readpages_copy_into_pages(struct TCP_Server_Info *server,
3451+
struct cifs_readdata *rdata,
3452+
struct iov_iter *iter)
3453+
{
3454+
return readpages_fill_pages(server, rdata, iter, iter->count);
3455+
}
3456+
34183457
static int
34193458
readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
34203459
unsigned int rsize, struct list_head *tmplist,
@@ -3569,6 +3608,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
35693608
rdata->pid = pid;
35703609
rdata->pagesz = PAGE_SIZE;
35713610
rdata->read_into_pages = cifs_readpages_read_into_pages;
3611+
rdata->copy_into_pages = cifs_readpages_copy_into_pages;
35723612
rdata->credits = credits;
35733613

35743614
list_for_each_entry_safe(page, tpage, &tmplist, lru) {

0 commit comments

Comments
 (0)