Skip to content

Commit 3ee1a1f

Browse files
committed
cifs: Cut over to using netfslib
Make the cifs filesystem use netfslib to handle reading and writing on behalf of cifs. The changes include: (1) Various read_iter/write_iter type functions are turned into wrappers around netfslib API functions or are pointed directly at those functions: cifs_file_direct{,_nobrl}_ops switch to use netfs_unbuffered_read_iter and netfs_unbuffered_write_iter. Large pieces of code that will be removed are #if'd out and will be removed in subsequent patches. [?] Why does cifs mark the page dirty in the destination buffer of a DIO read? Should that happen automatically? Does netfs need to do that? Signed-off-by: David Howells <[email protected]> cc: Steve French <[email protected]> cc: Shyam Prasad N <[email protected]> cc: Rohith Surabattula <[email protected]> cc: Jeff Layton <[email protected]> cc: [email protected] cc: [email protected] cc: [email protected] cc: [email protected]
1 parent 69c3c02 commit 3ee1a1f

File tree

14 files changed

+361
-180
lines changed

14 files changed

+361
-180
lines changed

fs/netfs/io.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,13 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
213213
unsigned int i;
214214
size_t transferred = 0;
215215

216-
for (i = 0; i < rreq->direct_bv_count; i++)
216+
for (i = 0; i < rreq->direct_bv_count; i++) {
217217
flush_dcache_page(rreq->direct_bv[i].bv_page);
218+
// TODO: cifs marks pages in the destination buffer
219+
// dirty under some circumstances after a read. Do we
220+
// need to do that too?
221+
set_page_dirty(rreq->direct_bv[i].bv_page);
222+
}
218223

219224
list_for_each_entry(subreq, &rreq->subrequests, rreq_link) {
220225
if (subreq->error || subreq->transferred == 0)

fs/smb/client/cifsfs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,8 +1522,8 @@ const struct file_operations cifs_file_strict_ops = {
15221522
};
15231523

15241524
const struct file_operations cifs_file_direct_ops = {
1525-
.read_iter = cifs_direct_readv,
1526-
.write_iter = cifs_direct_writev,
1525+
.read_iter = netfs_unbuffered_read_iter,
1526+
.write_iter = netfs_file_write_iter,
15271527
.open = cifs_open,
15281528
.release = cifs_close,
15291529
.lock = cifs_lock,
@@ -1578,8 +1578,8 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
15781578
};
15791579

15801580
const struct file_operations cifs_file_direct_nobrl_ops = {
1581-
.read_iter = cifs_direct_readv,
1582-
.write_iter = cifs_direct_writev,
1581+
.read_iter = netfs_unbuffered_read_iter,
1582+
.write_iter = netfs_file_write_iter,
15831583
.open = cifs_open,
15841584
.release = cifs_close,
15851585
.fsync = cifs_fsync,

fs/smb/client/cifsfs.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,7 @@ extern const struct file_operations cifs_file_strict_nobrl_ops;
9494
extern int cifs_open(struct inode *inode, struct file *file);
9595
extern int cifs_close(struct inode *inode, struct file *file);
9696
extern int cifs_closedir(struct inode *inode, struct file *file);
97-
extern ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to);
98-
extern ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to);
9997
extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
100-
extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
101-
extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
10298
extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
10399
ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
104100
ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter);
@@ -112,9 +108,6 @@ extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma);
112108
extern const struct file_operations cifs_dir_ops;
113109
extern int cifs_dir_open(struct inode *inode, struct file *file);
114110
extern int cifs_readdir(struct file *file, struct dir_context *ctx);
115-
extern void cifs_pages_written_back(struct inode *inode, loff_t start, unsigned int len);
116-
extern void cifs_pages_write_failed(struct inode *inode, loff_t start, unsigned int len);
117-
extern void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int len);
118111

119112
/* Functions related to dir entries */
120113
extern const struct dentry_operations cifs_dentry_ops;

fs/smb/client/cifsglob.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ struct smb_version_operations {
451451
/* async read from the server */
452452
int (*async_readv)(struct cifs_io_subrequest *);
453453
/* async write to the server */
454-
int (*async_writev)(struct cifs_io_subrequest *);
454+
void (*async_writev)(struct cifs_io_subrequest *);
455455
/* sync read from the server */
456456
int (*sync_read)(const unsigned int, struct cifs_fid *,
457457
struct cifs_io_parms *, unsigned int *, char **,
@@ -1516,7 +1516,7 @@ struct cifs_io_subrequest {
15161516
#endif
15171517
struct cifs_credits credits;
15181518

1519-
// TODO: Remove following elements
1519+
#if 0 // TODO: Remove following elements
15201520
struct list_head list;
15211521
struct completion done;
15221522
struct work_struct work;
@@ -1526,6 +1526,7 @@ struct cifs_io_subrequest {
15261526
enum writeback_sync_modes sync_mode;
15271527
bool uncached;
15281528
struct bio_vec *bv;
1529+
#endif
15291530
};
15301531

15311532
/*

fs/smb/client/cifsproto.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
148148
bool from_readdir);
149149
extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
150150
unsigned int bytes_written);
151+
void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
152+
bool was_async);
151153
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
152154
extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
153155
int flags,
@@ -599,6 +601,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses);
599601
extern struct cifs_ses *
600602
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
601603

604+
#if 0 // TODO Remove
602605
void cifs_readdata_release(struct cifs_io_subrequest *rdata);
603606
static inline void cifs_get_readdata(struct cifs_io_subrequest *rdata)
604607
{
@@ -609,11 +612,13 @@ static inline void cifs_put_readdata(struct cifs_io_subrequest *rdata)
609612
if (refcount_dec_and_test(&rdata->subreq.ref))
610613
cifs_readdata_release(rdata);
611614
}
615+
#endif
612616
int cifs_async_readv(struct cifs_io_subrequest *rdata);
613617
int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
614618

615-
int cifs_async_writev(struct cifs_io_subrequest *wdata);
619+
void cifs_async_writev(struct cifs_io_subrequest *wdata);
616620
void cifs_writev_complete(struct work_struct *work);
621+
#if 0 // TODO Remove
617622
struct cifs_io_subrequest *cifs_writedata_alloc(work_func_t complete);
618623
void cifs_writedata_release(struct cifs_io_subrequest *rdata);
619624
static inline void cifs_get_writedata(struct cifs_io_subrequest *wdata)
@@ -625,6 +630,7 @@ static inline void cifs_put_writedata(struct cifs_io_subrequest *wdata)
625630
if (refcount_dec_and_test(&wdata->subreq.ref))
626631
cifs_writedata_release(wdata);
627632
}
633+
#endif
628634
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
629635
struct cifs_sb_info *cifs_sb,
630636
const unsigned char *path, char *pbuf,

fs/smb/client/cifssmb.c

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ static void
12651265
cifs_readv_callback(struct mid_q_entry *mid)
12661266
{
12671267
struct cifs_io_subrequest *rdata = mid->callback_data;
1268-
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1268+
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
12691269
struct TCP_Server_Info *server = tcon->ses->server;
12701270
struct smb_rqst rqst = { .rq_iov = rdata->iov,
12711271
.rq_nvec = 2,
@@ -1306,7 +1306,13 @@ cifs_readv_callback(struct mid_q_entry *mid)
13061306
rdata->result = -EIO;
13071307
}
13081308

1309-
queue_work(cifsiod_wq, &rdata->work);
1309+
if (rdata->result == 0 || rdata->result == -EAGAIN)
1310+
iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes);
1311+
rdata->credits.value = 0;
1312+
netfs_subreq_terminated(&rdata->subreq,
1313+
(rdata->result == 0 || rdata->result == -EAGAIN) ?
1314+
rdata->got_bytes : rdata->result,
1315+
false);
13101316
release_mid(mid);
13111317
add_credits(server, &credits, 0);
13121318
}
@@ -1318,7 +1324,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
13181324
int rc;
13191325
READ_REQ *smb = NULL;
13201326
int wct;
1321-
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1327+
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
13221328
struct smb_rqst rqst = { .rq_iov = rdata->iov,
13231329
.rq_nvec = 2 };
13241330

@@ -1343,7 +1349,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
13431349
smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
13441350

13451351
smb->AndXCommand = 0xFF; /* none */
1346-
smb->Fid = rdata->cfile->fid.netfid;
1352+
smb->Fid = rdata->req->cfile->fid.netfid;
13471353
smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
13481354
if (wct == 12)
13491355
smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
@@ -1613,15 +1619,16 @@ static void
16131619
cifs_writev_callback(struct mid_q_entry *mid)
16141620
{
16151621
struct cifs_io_subrequest *wdata = mid->callback_data;
1616-
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1617-
unsigned int written;
1622+
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
16181623
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
16191624
struct cifs_credits credits = { .value = 1, .instance = 0 };
1625+
ssize_t result;
1626+
size_t written;
16201627

16211628
switch (mid->mid_state) {
16221629
case MID_RESPONSE_RECEIVED:
1623-
wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1624-
if (wdata->result != 0)
1630+
result = cifs_check_receive(mid, tcon->ses->server, 0);
1631+
if (result != 0)
16251632
break;
16261633

16271634
written = le16_to_cpu(smb->CountHigh);
@@ -1637,32 +1644,33 @@ cifs_writev_callback(struct mid_q_entry *mid)
16371644
written &= 0xFFFF;
16381645

16391646
if (written < wdata->subreq.len)
1640-
wdata->result = -ENOSPC;
1647+
result = -ENOSPC;
16411648
else
1642-
wdata->subreq.len = written;
1649+
result = written;
16431650
break;
16441651
case MID_REQUEST_SUBMITTED:
16451652
case MID_RETRY_NEEDED:
1646-
wdata->result = -EAGAIN;
1653+
result = -EAGAIN;
16471654
break;
16481655
default:
1649-
wdata->result = -EIO;
1656+
result = -EIO;
16501657
break;
16511658
}
16521659

1653-
queue_work(cifsiod_wq, &wdata->work);
1660+
wdata->credits.value = 0;
1661+
cifs_write_subrequest_terminated(wdata, result, true);
16541662
release_mid(mid);
16551663
add_credits(tcon->ses->server, &credits, 0);
16561664
}
16571665

16581666
/* cifs_async_writev - send an async write, and set up mid to handle result */
1659-
int
1667+
void
16601668
cifs_async_writev(struct cifs_io_subrequest *wdata)
16611669
{
16621670
int rc = -EACCES;
16631671
WRITE_REQ *smb = NULL;
16641672
int wct;
1665-
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1673+
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
16661674
struct kvec iov[2];
16671675
struct smb_rqst rqst = { };
16681676

@@ -1672,7 +1680,8 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
16721680
wct = 12;
16731681
if (wdata->subreq.start >> 32 > 0) {
16741682
/* can not handle big offset for old srv */
1675-
return -EIO;
1683+
rc = -EIO;
1684+
goto out;
16761685
}
16771686
}
16781687

@@ -1684,7 +1693,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
16841693
smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
16851694

16861695
smb->AndXCommand = 0xFF; /* none */
1687-
smb->Fid = wdata->cfile->fid.netfid;
1696+
smb->Fid = wdata->req->cfile->fid.netfid;
16881697
smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
16891698
if (wct == 14)
16901699
smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
@@ -1724,18 +1733,19 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
17241733
iov[1].iov_len += 4; /* pad bigger by four bytes */
17251734
}
17261735

1727-
cifs_get_writedata(wdata);
17281736
rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
17291737
cifs_writev_callback, NULL, wdata, 0, NULL);
1730-
1738+
/* Can't touch wdata if rc == 0 */
17311739
if (rc == 0)
17321740
cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1733-
else
1734-
cifs_put_writedata(wdata);
17351741

17361742
async_writev_out:
17371743
cifs_small_buf_release(smb);
1738-
return rc;
1744+
out:
1745+
if (rc) {
1746+
add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
1747+
cifs_write_subrequest_terminated(wdata, rc, false);
1748+
}
17391749
}
17401750

17411751
int

0 commit comments

Comments
 (0)