Commit e2bc9f6c authored by Christian Brauner's avatar Christian Brauner

Merge branch 'cifs-netfs' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

Pull cifs netfs updates from David Howells:

This ports cifs over to use the netfs library.

* 'cifs-netfs' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
  cifs: Enable large folio support
  cifs: Remove some code that's no longer used, part 3
  cifs: Remove some code that's no longer used, part 2
  cifs: Remove some code that's no longer used, part 1
  cifs: Cut over to using netfslib
  cifs: Implement netfslib hooks
  cifs: Make add_credits_and_wake_if() clear deducted credits
  cifs: Add mempools for cifs_io_request and cifs_io_subrequest structs
  cifs: Set zero_point in the copy_file_range() and remap_file_range()
  cifs: Move cifs_loose_read_iter() and cifs_file_write_iter() to file.c
  cifs: Replace the writedata replay bool with a netfs sreq flag
  cifs: Make wait_mtu_credits take size_t args
  cifs: Use more fields from netfs_io_subrequest
  cifs: Replace cifs_writedata with a wrapper around netfs_io_subrequest
  cifs: Replace cifs_readdata with a wrapper around netfs_io_subrequest
  cifs: Use alternative invalidation to using launder_folio
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parents 3931e678 7c1ac894
...@@ -405,6 +405,9 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter, ...@@ -405,6 +405,9 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
} while (iov_iter_count(iter)); } while (iov_iter_count(iter));
out: out:
if (likely(written) && ctx->ops->post_modify)
ctx->ops->post_modify(inode);
if (unlikely(wreq)) { if (unlikely(wreq)) {
ret2 = netfs_end_writethrough(wreq, &wbc, writethrough); ret2 = netfs_end_writethrough(wreq, &wbc, writethrough);
wbc_detach_inode(&wbc); wbc_detach_inode(&wbc);
...@@ -521,6 +524,7 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr ...@@ -521,6 +524,7 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
struct folio *folio = page_folio(vmf->page); struct folio *folio = page_folio(vmf->page);
struct file *file = vmf->vma->vm_file; struct file *file = vmf->vma->vm_file;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct netfs_inode *ictx = netfs_inode(inode);
vm_fault_t ret = VM_FAULT_RETRY; vm_fault_t ret = VM_FAULT_RETRY;
int err; int err;
...@@ -567,6 +571,8 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr ...@@ -567,6 +571,8 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
trace_netfs_folio(folio, netfs_folio_trace_mkwrite); trace_netfs_folio(folio, netfs_folio_trace_mkwrite);
netfs_set_group(folio, netfs_group); netfs_set_group(folio, netfs_group);
file_update_time(file); file_update_time(file);
if (ictx->ops->post_modify)
ictx->ops->post_modify(inode);
ret = VM_FAULT_LOCKED; ret = VM_FAULT_LOCKED;
out: out:
sb_end_pagefault(inode->i_sb); sb_end_pagefault(inode->i_sb);
......
...@@ -213,8 +213,13 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq) ...@@ -213,8 +213,13 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
unsigned int i; unsigned int i;
size_t transferred = 0; size_t transferred = 0;
for (i = 0; i < rreq->direct_bv_count; i++) for (i = 0; i < rreq->direct_bv_count; i++) {
flush_dcache_page(rreq->direct_bv[i].bv_page); flush_dcache_page(rreq->direct_bv[i].bv_page);
// TODO: cifs marks pages in the destination buffer
// dirty under some circumstances after a read. Do we
// need to do that too?
set_page_dirty(rreq->direct_bv[i].bv_page);
}
list_for_each_entry(subreq, &rreq->subrequests, rreq_link) { list_for_each_entry(subreq, &rreq->subrequests, rreq_link) {
if (subreq->error || subreq->transferred == 0) if (subreq->error || subreq->transferred == 0)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
config CIFS config CIFS
tristate "SMB3 and CIFS support (advanced network filesystem)" tristate "SMB3 and CIFS support (advanced network filesystem)"
depends on INET depends on INET
select NETFS_SUPPORT
select NLS select NLS
select NLS_UCS2_UTILS select NLS_UCS2_UTILS
select CRYPTO select CRYPTO
......
...@@ -371,9 +371,13 @@ static struct kmem_cache *cifs_inode_cachep; ...@@ -371,9 +371,13 @@ static struct kmem_cache *cifs_inode_cachep;
static struct kmem_cache *cifs_req_cachep; static struct kmem_cache *cifs_req_cachep;
static struct kmem_cache *cifs_mid_cachep; static struct kmem_cache *cifs_mid_cachep;
static struct kmem_cache *cifs_sm_req_cachep; static struct kmem_cache *cifs_sm_req_cachep;
static struct kmem_cache *cifs_io_request_cachep;
static struct kmem_cache *cifs_io_subrequest_cachep;
mempool_t *cifs_sm_req_poolp; mempool_t *cifs_sm_req_poolp;
mempool_t *cifs_req_poolp; mempool_t *cifs_req_poolp;
mempool_t *cifs_mid_poolp; mempool_t *cifs_mid_poolp;
mempool_t cifs_io_request_pool;
mempool_t cifs_io_subrequest_pool;
static struct inode * static struct inode *
cifs_alloc_inode(struct super_block *sb) cifs_alloc_inode(struct super_block *sb)
...@@ -986,61 +990,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, ...@@ -986,61 +990,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
return root; return root;
} }
static ssize_t
cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
ssize_t rc;
struct inode *inode = file_inode(iocb->ki_filp);
if (iocb->ki_flags & IOCB_DIRECT)
return cifs_user_readv(iocb, iter);
rc = cifs_revalidate_mapping(inode);
if (rc)
return rc;
return generic_file_read_iter(iocb, iter);
}
static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
struct inode *inode = file_inode(iocb->ki_filp);
struct cifsInodeInfo *cinode = CIFS_I(inode);
ssize_t written;
int rc;
if (iocb->ki_filp->f_flags & O_DIRECT) {
written = cifs_user_writev(iocb, from);
if (written > 0 && CIFS_CACHE_READ(cinode)) {
cifs_zap_mapping(inode);
cifs_dbg(FYI,
"Set no oplock for inode=%p after a write operation\n",
inode);
cinode->oplock = 0;
}
return written;
}
written = cifs_get_writer(cinode);
if (written)
return written;
written = generic_file_write_iter(iocb, from);
if (CIFS_CACHE_WRITE(CIFS_I(inode)))
goto out;
rc = filemap_fdatawrite(inode->i_mapping);
if (rc)
cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
rc, inode);
out:
cifs_put_writer(cinode);
return written;
}
static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
{ {
struct cifsFileInfo *cfile = file->private_data; struct cifsFileInfo *cfile = file->private_data;
...@@ -1342,6 +1291,8 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off, ...@@ -1342,6 +1291,8 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false); rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false);
if (rc) if (rc)
goto unlock; goto unlock;
if (fend > target_cifsi->netfs.zero_point)
target_cifsi->netfs.zero_point = fend + 1;
/* Discard all the folios that overlap the destination region. */ /* Discard all the folios that overlap the destination region. */
cifs_dbg(FYI, "about to discard pages %llx-%llx\n", fstart, fend); cifs_dbg(FYI, "about to discard pages %llx-%llx\n", fstart, fend);
...@@ -1360,6 +1311,8 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off, ...@@ -1360,6 +1311,8 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
fscache_resize_cookie(cifs_inode_cookie(target_inode), fscache_resize_cookie(cifs_inode_cookie(target_inode),
new_size); new_size);
} }
if (rc == 0 && new_size > target_cifsi->netfs.zero_point)
target_cifsi->netfs.zero_point = new_size;
} }
/* force revalidate of size and timestamps of target file now /* force revalidate of size and timestamps of target file now
...@@ -1451,6 +1404,8 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, ...@@ -1451,6 +1404,8 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false); rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false);
if (rc) if (rc)
goto unlock; goto unlock;
if (fend > target_cifsi->netfs.zero_point)
target_cifsi->netfs.zero_point = fend + 1;
/* Discard all the folios that overlap the destination region. */ /* Discard all the folios that overlap the destination region. */
truncate_inode_pages_range(&target_inode->i_data, fstart, fend); truncate_inode_pages_range(&target_inode->i_data, fstart, fend);
...@@ -1567,8 +1522,8 @@ const struct file_operations cifs_file_strict_ops = { ...@@ -1567,8 +1522,8 @@ const struct file_operations cifs_file_strict_ops = {
}; };
const struct file_operations cifs_file_direct_ops = { const struct file_operations cifs_file_direct_ops = {
.read_iter = cifs_direct_readv, .read_iter = netfs_unbuffered_read_iter,
.write_iter = cifs_direct_writev, .write_iter = netfs_file_write_iter,
.open = cifs_open, .open = cifs_open,
.release = cifs_close, .release = cifs_close,
.lock = cifs_lock, .lock = cifs_lock,
...@@ -1623,8 +1578,8 @@ const struct file_operations cifs_file_strict_nobrl_ops = { ...@@ -1623,8 +1578,8 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
}; };
const struct file_operations cifs_file_direct_nobrl_ops = { const struct file_operations cifs_file_direct_nobrl_ops = {
.read_iter = cifs_direct_readv, .read_iter = netfs_unbuffered_read_iter,
.write_iter = cifs_direct_writev, .write_iter = netfs_file_write_iter,
.open = cifs_open, .open = cifs_open,
.release = cifs_close, .release = cifs_close,
.fsync = cifs_fsync, .fsync = cifs_fsync,
...@@ -1799,6 +1754,48 @@ static void destroy_mids(void) ...@@ -1799,6 +1754,48 @@ static void destroy_mids(void)
kmem_cache_destroy(cifs_mid_cachep); kmem_cache_destroy(cifs_mid_cachep);
} }
static int cifs_init_netfs(void)
{
cifs_io_request_cachep =
kmem_cache_create("cifs_io_request",
sizeof(struct cifs_io_request), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!cifs_io_request_cachep)
goto nomem_req;
if (mempool_init_slab_pool(&cifs_io_request_pool, 100, cifs_io_request_cachep) < 0)
goto nomem_reqpool;
cifs_io_subrequest_cachep =
kmem_cache_create("cifs_io_subrequest",
sizeof(struct cifs_io_subrequest), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!cifs_io_subrequest_cachep)
goto nomem_subreq;
if (mempool_init_slab_pool(&cifs_io_subrequest_pool, 100, cifs_io_subrequest_cachep) < 0)
goto nomem_subreqpool;
return 0;
nomem_subreqpool:
kmem_cache_destroy(cifs_io_subrequest_cachep);
nomem_subreq:
mempool_destroy(&cifs_io_request_pool);
nomem_reqpool:
kmem_cache_destroy(cifs_io_request_cachep);
nomem_req:
return -ENOMEM;
}
static void cifs_destroy_netfs(void)
{
mempool_destroy(&cifs_io_subrequest_pool);
kmem_cache_destroy(cifs_io_subrequest_cachep);
mempool_destroy(&cifs_io_request_pool);
kmem_cache_destroy(cifs_io_request_cachep);
}
static int __init static int __init
init_cifs(void) init_cifs(void)
{ {
...@@ -1903,10 +1900,14 @@ init_cifs(void) ...@@ -1903,10 +1900,14 @@ init_cifs(void)
if (rc) if (rc)
goto out_destroy_deferredclose_wq; goto out_destroy_deferredclose_wq;
rc = init_mids(); rc = cifs_init_netfs();
if (rc) if (rc)
goto out_destroy_inodecache; goto out_destroy_inodecache;
rc = init_mids();
if (rc)
goto out_destroy_netfs;
rc = cifs_init_request_bufs(); rc = cifs_init_request_bufs();
if (rc) if (rc)
goto out_destroy_mids; goto out_destroy_mids;
...@@ -1961,6 +1962,8 @@ init_cifs(void) ...@@ -1961,6 +1962,8 @@ init_cifs(void)
cifs_destroy_request_bufs(); cifs_destroy_request_bufs();
out_destroy_mids: out_destroy_mids:
destroy_mids(); destroy_mids();
out_destroy_netfs:
cifs_destroy_netfs();
out_destroy_inodecache: out_destroy_inodecache:
cifs_destroy_inodecache(); cifs_destroy_inodecache();
out_destroy_deferredclose_wq: out_destroy_deferredclose_wq:
...@@ -1999,6 +2002,7 @@ exit_cifs(void) ...@@ -1999,6 +2002,7 @@ exit_cifs(void)
#endif #endif
cifs_destroy_request_bufs(); cifs_destroy_request_bufs();
destroy_mids(); destroy_mids();
cifs_destroy_netfs();
cifs_destroy_inodecache(); cifs_destroy_inodecache();
destroy_workqueue(deferredclose_wq); destroy_workqueue(deferredclose_wq);
destroy_workqueue(cifsoplockd_wq); destroy_workqueue(cifsoplockd_wq);
......
...@@ -69,7 +69,6 @@ extern int cifs_revalidate_file_attr(struct file *filp); ...@@ -69,7 +69,6 @@ extern int cifs_revalidate_file_attr(struct file *filp);
extern int cifs_revalidate_dentry_attr(struct dentry *); extern int cifs_revalidate_dentry_attr(struct dentry *);
extern int cifs_revalidate_file(struct file *filp); extern int cifs_revalidate_file(struct file *filp);
extern int cifs_revalidate_dentry(struct dentry *); extern int cifs_revalidate_dentry(struct dentry *);
extern int cifs_invalidate_mapping(struct inode *inode);
extern int cifs_revalidate_mapping(struct inode *inode); extern int cifs_revalidate_mapping(struct inode *inode);
extern int cifs_zap_mapping(struct inode *inode); extern int cifs_zap_mapping(struct inode *inode);
extern int cifs_getattr(struct mnt_idmap *, const struct path *, extern int cifs_getattr(struct mnt_idmap *, const struct path *,
...@@ -85,6 +84,7 @@ extern const struct inode_operations cifs_namespace_inode_operations; ...@@ -85,6 +84,7 @@ extern const struct inode_operations cifs_namespace_inode_operations;
/* Functions related to files and directories */ /* Functions related to files and directories */
extern const struct netfs_request_ops cifs_req_ops;
extern const struct file_operations cifs_file_ops; extern const struct file_operations cifs_file_ops;
extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */ extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */
...@@ -94,12 +94,10 @@ extern const struct file_operations cifs_file_strict_nobrl_ops; ...@@ -94,12 +94,10 @@ extern const struct file_operations cifs_file_strict_nobrl_ops;
extern int cifs_open(struct inode *inode, struct file *file); extern int cifs_open(struct inode *inode, struct file *file);
extern int cifs_close(struct inode *inode, struct file *file); extern int cifs_close(struct inode *inode, struct file *file);
extern int cifs_closedir(struct inode *inode, struct file *file); extern int cifs_closedir(struct inode *inode, struct file *file);
extern ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to);
extern ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to);
extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to); extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from); extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter);
extern int cifs_flock(struct file *pfile, int cmd, struct file_lock *plock); extern int cifs_flock(struct file *pfile, int cmd, struct file_lock *plock);
extern int cifs_lock(struct file *, int, struct file_lock *); extern int cifs_lock(struct file *, int, struct file_lock *);
extern int cifs_fsync(struct file *, loff_t, loff_t, int); extern int cifs_fsync(struct file *, loff_t, loff_t, int);
...@@ -110,9 +108,6 @@ extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma); ...@@ -110,9 +108,6 @@ extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma);
extern const struct file_operations cifs_dir_ops; extern const struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file); extern int cifs_dir_open(struct inode *inode, struct file *file);
extern int cifs_readdir(struct file *file, struct dir_context *ctx); extern int cifs_readdir(struct file *file, struct dir_context *ctx);
extern void cifs_pages_written_back(struct inode *inode, loff_t start, unsigned int len);
extern void cifs_pages_write_failed(struct inode *inode, loff_t start, unsigned int len);
extern void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int len);
/* Functions related to dir entries */ /* Functions related to dir entries */
extern const struct dentry_operations cifs_dentry_ops; extern const struct dentry_operations cifs_dentry_ops;
......
...@@ -268,8 +268,7 @@ struct dfs_info3_param; ...@@ -268,8 +268,7 @@ struct dfs_info3_param;
struct cifs_fattr; struct cifs_fattr;
struct smb3_fs_context; struct smb3_fs_context;
struct cifs_fid; struct cifs_fid;
struct cifs_readdata; struct cifs_io_subrequest;
struct cifs_writedata;
struct cifs_io_parms; struct cifs_io_parms;
struct cifs_search_info; struct cifs_search_info;
struct cifsInodeInfo; struct cifsInodeInfo;
...@@ -450,10 +449,9 @@ struct smb_version_operations { ...@@ -450,10 +449,9 @@ struct smb_version_operations {
/* send a flush request to the server */ /* send a flush request to the server */
int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *); int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *);
/* async read from the server */ /* async read from the server */
int (*async_readv)(struct cifs_readdata *); int (*async_readv)(struct cifs_io_subrequest *);
/* async write to the server */ /* async write to the server */
int (*async_writev)(struct cifs_writedata *, void (*async_writev)(struct cifs_io_subrequest *);
void (*release)(struct kref *));
/* sync read from the server */ /* sync read from the server */
int (*sync_read)(const unsigned int, struct cifs_fid *, int (*sync_read)(const unsigned int, struct cifs_fid *,
struct cifs_io_parms *, unsigned int *, char **, struct cifs_io_parms *, unsigned int *, char **,
...@@ -548,8 +546,8 @@ struct smb_version_operations { ...@@ -548,8 +546,8 @@ struct smb_version_operations {
/* writepages retry size */ /* writepages retry size */
unsigned int (*wp_retry_size)(struct inode *); unsigned int (*wp_retry_size)(struct inode *);
/* get mtu credits */ /* get mtu credits */
int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int, int (*wait_mtu_credits)(struct TCP_Server_Info *, size_t,
unsigned int *, struct cifs_credits *); size_t *, struct cifs_credits *);
/* adjust previously taken mtu credits to request size */ /* adjust previously taken mtu credits to request size */
int (*adjust_credits)(struct TCP_Server_Info *server, int (*adjust_credits)(struct TCP_Server_Info *server,
struct cifs_credits *credits, struct cifs_credits *credits,
...@@ -883,11 +881,12 @@ add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits, ...@@ -883,11 +881,12 @@ add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits,
static inline void static inline void
add_credits_and_wake_if(struct TCP_Server_Info *server, add_credits_and_wake_if(struct TCP_Server_Info *server,
const struct cifs_credits *credits, const int optype) struct cifs_credits *credits, const int optype)
{ {
if (credits->value) { if (credits->value) {
server->ops->add_credits(server, credits, optype); server->ops->add_credits(server, credits, optype);
wake_up(&server->request_q); wake_up(&server->request_q);
credits->value = 0;
} }
} }
...@@ -1492,50 +1491,30 @@ struct cifs_aio_ctx { ...@@ -1492,50 +1491,30 @@ struct cifs_aio_ctx {
bool direct_io; bool direct_io;
}; };
/* asynchronous read support */ struct cifs_io_request {
struct cifs_readdata { struct netfs_io_request rreq;
struct kref refcount;
struct list_head list;
struct completion done;
struct cifsFileInfo *cfile; struct cifsFileInfo *cfile;
struct address_space *mapping;
struct cifs_aio_ctx *ctx;
__u64 offset;
ssize_t got_bytes;
unsigned int bytes;
pid_t pid;
int result;
struct work_struct work;
struct iov_iter iter;
struct kvec iov[2];
struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT
struct smbd_mr *mr;
#endif
struct cifs_credits credits;
}; };
/* asynchronous write support */ /* asynchronous read support */
struct cifs_writedata { struct cifs_io_subrequest {
struct kref refcount; union {
struct list_head list; struct netfs_io_subrequest subreq;
struct completion done; struct netfs_io_request *rreq;
enum writeback_sync_modes sync_mode; struct cifs_io_request *req;
struct work_struct work; };
struct cifsFileInfo *cfile; ssize_t got_bytes;
struct cifs_aio_ctx *ctx;
struct iov_iter iter;
struct bio_vec *bv;
__u64 offset;
pid_t pid; pid_t pid;
unsigned int bytes; unsigned int xid;
int result; int result;
bool have_xid;
bool replay;
struct kvec iov[2];
struct TCP_Server_Info *server; struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT #ifdef CONFIG_CIFS_SMB_DIRECT
struct smbd_mr *mr; struct smbd_mr *mr;
#endif #endif
struct cifs_credits credits; struct cifs_credits credits;
bool replay;
}; };
/* /*
...@@ -2115,6 +2094,8 @@ extern __u32 cifs_lock_secret; ...@@ -2115,6 +2094,8 @@ extern __u32 cifs_lock_secret;
extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp; extern mempool_t *cifs_req_poolp;
extern mempool_t *cifs_mid_poolp; extern mempool_t *cifs_mid_poolp;
extern mempool_t cifs_io_request_pool;
extern mempool_t cifs_io_subrequest_pool;
/* Operations for different SMB versions */ /* Operations for different SMB versions */
#define SMB1_VERSION_STRING "1.0" #define SMB1_VERSION_STRING "1.0"
......
...@@ -121,7 +121,7 @@ extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *, ...@@ -121,7 +121,7 @@ extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *,
extern int cifs_check_receive(struct mid_q_entry *mid, extern int cifs_check_receive(struct mid_q_entry *mid,
struct TCP_Server_Info *server, bool log_error); struct TCP_Server_Info *server, bool log_error);
extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server, extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server,
unsigned int size, unsigned int *num, size_t size, size_t *num,
struct cifs_credits *credits); struct cifs_credits *credits);
extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *, extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
struct kvec *, int /* nvec to send */, struct kvec *, int /* nvec to send */,
...@@ -148,6 +148,8 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof, ...@@ -148,6 +148,8 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
bool from_readdir); bool from_readdir);
extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
unsigned int bytes_written); unsigned int bytes_written);
void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
bool was_async);
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
int flags, int flags,
...@@ -599,15 +601,11 @@ void __cifs_put_smb_ses(struct cifs_ses *ses); ...@@ -599,15 +601,11 @@ void __cifs_put_smb_ses(struct cifs_ses *ses);
extern struct cifs_ses * extern struct cifs_ses *
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx); cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
void cifs_readdata_release(struct kref *refcount); int cifs_async_readv(struct cifs_io_subrequest *rdata);
int cifs_async_readv(struct cifs_readdata *rdata);
int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
int cifs_async_writev(struct cifs_writedata *wdata, void cifs_async_writev(struct cifs_io_subrequest *wdata);
void (*release)(struct kref *kref));
void cifs_writev_complete(struct work_struct *work); void cifs_writev_complete(struct work_struct *work);
struct cifs_writedata *cifs_writedata_alloc(work_func_t complete);
void cifs_writedata_release(struct kref *refcount);
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, struct cifs_sb_info *cifs_sb,
const unsigned char *path, char *pbuf, const unsigned char *path, char *pbuf,
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/task_io_accounting_ops.h> #include <linux/task_io_accounting_ops.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/netfs.h>
#include <trace/events/netfs.h>
#include "cifspdu.h" #include "cifspdu.h"
#include "cifsfs.h" #include "cifsfs.h"
#include "cifsglob.h" #include "cifsglob.h"
...@@ -1262,18 +1264,17 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock, ...@@ -1262,18 +1264,17 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
static void static void
cifs_readv_callback(struct mid_q_entry *mid) cifs_readv_callback(struct mid_q_entry *mid)
{ {
struct cifs_readdata *rdata = mid->callback_data; struct cifs_io_subrequest *rdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
struct TCP_Server_Info *server = tcon->ses->server; struct TCP_Server_Info *server = tcon->ses->server;
struct smb_rqst rqst = { .rq_iov = rdata->iov, struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 2, .rq_nvec = 2,
.rq_iter_size = iov_iter_count(&rdata->iter), .rq_iter = rdata->subreq.io_iter };
.rq_iter = rdata->iter };
struct cifs_credits credits = { .value = 1, .instance = 0 }; struct cifs_credits credits = { .value = 1, .instance = 0 };
cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n", cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
__func__, mid->mid, mid->mid_state, rdata->result, __func__, mid->mid, mid->mid_state, rdata->result,
rdata->bytes); rdata->subreq.len);
switch (mid->mid_state) { switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED: case MID_RESPONSE_RECEIVED:
...@@ -1305,30 +1306,36 @@ cifs_readv_callback(struct mid_q_entry *mid) ...@@ -1305,30 +1306,36 @@ cifs_readv_callback(struct mid_q_entry *mid)
rdata->result = -EIO; rdata->result = -EIO;
} }
queue_work(cifsiod_wq, &rdata->work); if (rdata->result == 0 || rdata->result == -EAGAIN)
iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes);
rdata->credits.value = 0;
netfs_subreq_terminated(&rdata->subreq,
(rdata->result == 0 || rdata->result == -EAGAIN) ?
rdata->got_bytes : rdata->result,
false);
release_mid(mid); release_mid(mid);
add_credits(server, &credits, 0); add_credits(server, &credits, 0);
} }
/* cifs_async_readv - send an async write, and set up mid to handle result */ /* cifs_async_readv - send an async write, and set up mid to handle result */
int int
cifs_async_readv(struct cifs_readdata *rdata) cifs_async_readv(struct cifs_io_subrequest *rdata)
{ {
int rc; int rc;
READ_REQ *smb = NULL; READ_REQ *smb = NULL;
int wct; int wct;
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
struct smb_rqst rqst = { .rq_iov = rdata->iov, struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 2 }; .rq_nvec = 2 };
cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n", cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n",
__func__, rdata->offset, rdata->bytes); __func__, rdata->subreq.start, rdata->subreq.len);
if (tcon->ses->capabilities & CAP_LARGE_FILES) if (tcon->ses->capabilities & CAP_LARGE_FILES)
wct = 12; wct = 12;
else { else {
wct = 10; /* old style read */ wct = 10; /* old style read */
if ((rdata->offset >> 32) > 0) { if ((rdata->subreq.start >> 32) > 0) {
/* can not handle this big offset for old */ /* can not handle this big offset for old */
return -EIO; return -EIO;
} }
...@@ -1342,13 +1349,13 @@ cifs_async_readv(struct cifs_readdata *rdata) ...@@ -1342,13 +1349,13 @@ cifs_async_readv(struct cifs_readdata *rdata)
smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16)); smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
smb->AndXCommand = 0xFF; /* none */ smb->AndXCommand = 0xFF; /* none */
smb->Fid = rdata->cfile->fid.netfid; smb->Fid = rdata->req->cfile->fid.netfid;
smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF); smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
if (wct == 12) if (wct == 12)
smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32); smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
smb->Remaining = 0; smb->Remaining = 0;
smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF); smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF);
smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16); smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16);
if (wct == 12) if (wct == 12)
smb->ByteCount = 0; smb->ByteCount = 0;
else { else {
...@@ -1364,15 +1371,11 @@ cifs_async_readv(struct cifs_readdata *rdata) ...@@ -1364,15 +1371,11 @@ cifs_async_readv(struct cifs_readdata *rdata)
rdata->iov[1].iov_base = (char *)smb + 4; rdata->iov[1].iov_base = (char *)smb + 4;
rdata->iov[1].iov_len = get_rfc1002_length(smb); rdata->iov[1].iov_len = get_rfc1002_length(smb);
kref_get(&rdata->refcount);
rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
cifs_readv_callback, NULL, rdata, 0, NULL); cifs_readv_callback, NULL, rdata, 0, NULL);
if (rc == 0) if (rc == 0)
cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
else
kref_put(&rdata->refcount, cifs_readdata_release);
cifs_small_buf_release(smb); cifs_small_buf_release(smb);
return rc; return rc;
} }
...@@ -1615,16 +1618,17 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms, ...@@ -1615,16 +1618,17 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
static void static void
cifs_writev_callback(struct mid_q_entry *mid) cifs_writev_callback(struct mid_q_entry *mid)
{ {
struct cifs_writedata *wdata = mid->callback_data; struct cifs_io_subrequest *wdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
unsigned int written;
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
struct cifs_credits credits = { .value = 1, .instance = 0 }; struct cifs_credits credits = { .value = 1, .instance = 0 };
ssize_t result;
size_t written;
switch (mid->mid_state) { switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED: case MID_RESPONSE_RECEIVED:
wdata->result = cifs_check_receive(mid, tcon->ses->server, 0); result = cifs_check_receive(mid, tcon->ses->server, 0);
if (wdata->result != 0) if (result != 0)
break; break;
written = le16_to_cpu(smb->CountHigh); written = le16_to_cpu(smb->CountHigh);
...@@ -1636,37 +1640,37 @@ cifs_writev_callback(struct mid_q_entry *mid) ...@@ -1636,37 +1640,37 @@ cifs_writev_callback(struct mid_q_entry *mid)
* client. OS/2 servers are known to set incorrect * client. OS/2 servers are known to set incorrect
* CountHigh values. * CountHigh values.
*/ */
if (written > wdata->bytes) if (written > wdata->subreq.len)
written &= 0xFFFF; written &= 0xFFFF;
if (written < wdata->bytes) if (written < wdata->subreq.len)
wdata->result = -ENOSPC; result = -ENOSPC;
else else
wdata->bytes = written; result = written;
break; break;
case MID_REQUEST_SUBMITTED: case MID_REQUEST_SUBMITTED:
case MID_RETRY_NEEDED: case MID_RETRY_NEEDED:
wdata->result = -EAGAIN; result = -EAGAIN;
break; break;
default: default:
wdata->result = -EIO; result = -EIO;
break; break;
} }
queue_work(cifsiod_wq, &wdata->work); wdata->credits.value = 0;
cifs_write_subrequest_terminated(wdata, result, true);
release_mid(mid); release_mid(mid);
add_credits(tcon->ses->server, &credits, 0); add_credits(tcon->ses->server, &credits, 0);
} }
/* cifs_async_writev - send an async write, and set up mid to handle result */ /* cifs_async_writev - send an async write, and set up mid to handle result */
int void
cifs_async_writev(struct cifs_writedata *wdata, cifs_async_writev(struct cifs_io_subrequest *wdata)
void (*release)(struct kref *kref))
{ {
int rc = -EACCES; int rc = -EACCES;
WRITE_REQ *smb = NULL; WRITE_REQ *smb = NULL;
int wct; int wct;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
struct kvec iov[2]; struct kvec iov[2];
struct smb_rqst rqst = { }; struct smb_rqst rqst = { };
...@@ -1674,9 +1678,10 @@ cifs_async_writev(struct cifs_writedata *wdata, ...@@ -1674,9 +1678,10 @@ cifs_async_writev(struct cifs_writedata *wdata,
wct = 14; wct = 14;
} else { } else {
wct = 12; wct = 12;
if (wdata->offset >> 32 > 0) { if (wdata->subreq.start >> 32 > 0) {
/* can not handle big offset for old srv */ /* can not handle big offset for old srv */
return -EIO; rc = -EIO;
goto out;
} }
} }
...@@ -1688,10 +1693,10 @@ cifs_async_writev(struct cifs_writedata *wdata, ...@@ -1688,10 +1693,10 @@ cifs_async_writev(struct cifs_writedata *wdata,
smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16)); smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
smb->AndXCommand = 0xFF; /* none */ smb->AndXCommand = 0xFF; /* none */
smb->Fid = wdata->cfile->fid.netfid; smb->Fid = wdata->req->cfile->fid.netfid;
smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF); smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
if (wct == 14) if (wct == 14)
smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32); smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
smb->Reserved = 0xFFFFFFFF; smb->Reserved = 0xFFFFFFFF;
smb->WriteMode = 0; smb->WriteMode = 0;
smb->Remaining = 0; smb->Remaining = 0;
...@@ -1707,39 +1712,40 @@ cifs_async_writev(struct cifs_writedata *wdata, ...@@ -1707,39 +1712,40 @@ cifs_async_writev(struct cifs_writedata *wdata,
rqst.rq_iov = iov; rqst.rq_iov = iov;
rqst.rq_nvec = 2; rqst.rq_nvec = 2;
rqst.rq_iter = wdata->iter; rqst.rq_iter = wdata->subreq.io_iter;
rqst.rq_iter_size = iov_iter_count(&wdata->iter); rqst.rq_iter_size = iov_iter_count(&wdata->subreq.io_iter);
cifs_dbg(FYI, "async write at %llu %u bytes\n", cifs_dbg(FYI, "async write at %llu %zu bytes\n",
wdata->offset, wdata->bytes); wdata->subreq.start, wdata->subreq.len);
smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF); smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF);
smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16); smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
if (wct == 14) { if (wct == 14) {
inc_rfc1001_len(&smb->hdr, wdata->bytes + 1); inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1);
put_bcc(wdata->bytes + 1, &smb->hdr); put_bcc(wdata->subreq.len + 1, &smb->hdr);
} else { } else {
/* wct == 12 */ /* wct == 12 */
struct smb_com_writex_req *smbw = struct smb_com_writex_req *smbw =
(struct smb_com_writex_req *)smb; (struct smb_com_writex_req *)smb;
inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5); inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5);
put_bcc(wdata->bytes + 5, &smbw->hdr); put_bcc(wdata->subreq.len + 5, &smbw->hdr);
iov[1].iov_len += 4; /* pad bigger by four bytes */ iov[1].iov_len += 4; /* pad bigger by four bytes */
} }
kref_get(&wdata->refcount);
rc = cifs_call_async(tcon->ses->server, &rqst, NULL, rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
cifs_writev_callback, NULL, wdata, 0, NULL); cifs_writev_callback, NULL, wdata, 0, NULL);
/* Can't touch wdata if rc == 0 */
if (rc == 0) if (rc == 0)
cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
else
kref_put(&wdata->refcount, release);
async_writev_out: async_writev_out:
cifs_small_buf_release(smb); cifs_small_buf_release(smb);
return rc; out:
if (rc) {
add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
cifs_write_subrequest_terminated(wdata, rc, false);
}
} }
int int
......
This diff is collapsed.
...@@ -170,112 +170,3 @@ void cifs_fscache_release_inode_cookie(struct inode *inode) ...@@ -170,112 +170,3 @@ void cifs_fscache_release_inode_cookie(struct inode *inode)
cifsi->netfs.cache = NULL; cifsi->netfs.cache = NULL;
} }
} }
/*
* Fallback page reading interface.
*/
static int fscache_fallback_read_page(struct inode *inode, struct page *page)
{
struct netfs_cache_resources cres;
struct fscache_cookie *cookie = cifs_inode_cookie(inode);
struct iov_iter iter;
struct bio_vec bvec;
int ret;
memset(&cres, 0, sizeof(cres));
bvec_set_page(&bvec, page, PAGE_SIZE, 0);
iov_iter_bvec(&iter, ITER_DEST, &bvec, 1, PAGE_SIZE);
ret = fscache_begin_read_operation(&cres, cookie);
if (ret < 0)
return ret;
ret = fscache_read(&cres, page_offset(page), &iter, NETFS_READ_HOLE_FAIL,
NULL, NULL);
fscache_end_operation(&cres);
return ret;
}
/*
* Fallback page writing interface.
*/
static int fscache_fallback_write_pages(struct inode *inode, loff_t start, size_t len,
bool no_space_allocated_yet)
{
struct netfs_cache_resources cres;
struct fscache_cookie *cookie = cifs_inode_cookie(inode);
struct iov_iter iter;
int ret;
memset(&cres, 0, sizeof(cres));
iov_iter_xarray(&iter, ITER_SOURCE, &inode->i_mapping->i_pages, start, len);
ret = fscache_begin_write_operation(&cres, cookie);
if (ret < 0)
return ret;
ret = cres.ops->prepare_write(&cres, &start, &len, len, i_size_read(inode),
no_space_allocated_yet);
if (ret == 0)
ret = fscache_write(&cres, start, &iter, NULL, NULL);
fscache_end_operation(&cres);
return ret;
}
/*
* Retrieve a page from FS-Cache
*/
int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
{
int ret;
cifs_dbg(FYI, "%s: (fsc:%p, p:%p, i:0x%p\n",
__func__, cifs_inode_cookie(inode), page, inode);
ret = fscache_fallback_read_page(inode, page);
if (ret < 0)
return ret;
/* Read completed synchronously */
SetPageUptodate(page);
return 0;
}
void __cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len)
{
cifs_dbg(FYI, "%s: (fsc: %p, p: %llx, l: %zx, i: %p)\n",
__func__, cifs_inode_cookie(inode), pos, len, inode);
fscache_fallback_write_pages(inode, pos, len, true);
}
/*
* Query the cache occupancy.
*/
int __cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first,
unsigned int *_data_nr_pages)
{
struct netfs_cache_resources cres;
struct fscache_cookie *cookie = cifs_inode_cookie(inode);
loff_t start, data_start;
size_t len, data_len;
int ret;
ret = fscache_begin_read_operation(&cres, cookie);
if (ret < 0)
return ret;
start = first * PAGE_SIZE;
len = nr_pages * PAGE_SIZE;
ret = cres.ops->query_occupancy(&cres, start, len, PAGE_SIZE,
&data_start, &data_len);
if (ret == 0) {
*_data_first = data_start / PAGE_SIZE;
*_data_nr_pages = len / PAGE_SIZE;
}
fscache_end_operation(&cres);
return ret;
}
...@@ -74,41 +74,6 @@ static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags ...@@ -74,41 +74,6 @@ static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags
i_size_read(inode), flags); i_size_read(inode), flags);
} }
extern int __cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first,
unsigned int *_data_nr_pages);
static inline int cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first,
unsigned int *_data_nr_pages)
{
if (!cifs_inode_cookie(inode))
return -ENOBUFS;
return __cifs_fscache_query_occupancy(inode, first, nr_pages,
_data_first, _data_nr_pages);
}
extern int __cifs_readpage_from_fscache(struct inode *pinode, struct page *ppage);
extern void __cifs_readahead_to_fscache(struct inode *pinode, loff_t pos, size_t len);
static inline int cifs_readpage_from_fscache(struct inode *inode,
struct page *page)
{
if (cifs_inode_cookie(inode))
return __cifs_readpage_from_fscache(inode, page);
return -ENOBUFS;
}
static inline void cifs_readahead_to_fscache(struct inode *inode,
loff_t pos, size_t len)
{
if (cifs_inode_cookie(inode))
__cifs_readahead_to_fscache(inode, pos, len);
}
static inline bool cifs_fscache_enabled(struct inode *inode) static inline bool cifs_fscache_enabled(struct inode *inode)
{ {
return fscache_cookie_enabled(cifs_inode_cookie(inode)); return fscache_cookie_enabled(cifs_inode_cookie(inode));
...@@ -131,25 +96,6 @@ static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { re ...@@ -131,25 +96,6 @@ static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { re
static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) {} static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) {}
static inline bool cifs_fscache_enabled(struct inode *inode) { return false; } static inline bool cifs_fscache_enabled(struct inode *inode) { return false; }
static inline int cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first,
unsigned int *_data_nr_pages)
{
*_data_first = ULONG_MAX;
*_data_nr_pages = 0;
return -ENOBUFS;
}
static inline int
cifs_readpage_from_fscache(struct inode *inode, struct page *page)
{
return -ENOBUFS;
}
static inline
void cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len) {}
#endif /* CONFIG_CIFS_FSCACHE */ #endif /* CONFIG_CIFS_FSCACHE */
#endif /* _CIFS_FSCACHE_H */ #endif /* _CIFS_FSCACHE_H */
...@@ -28,14 +28,29 @@ ...@@ -28,14 +28,29 @@
#include "cached_dir.h" #include "cached_dir.h"
#include "reparse.h" #include "reparse.h"
/*
* Set parameters for the netfs library
*/
static void cifs_set_netfs_context(struct inode *inode)
{
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
netfs_inode_init(&cifs_i->netfs, &cifs_req_ops, true);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
__set_bit(NETFS_ICTX_WRITETHROUGH, &cifs_i->netfs.flags);
}
static void cifs_set_ops(struct inode *inode) static void cifs_set_ops(struct inode *inode)
{ {
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct netfs_inode *ictx = netfs_inode(inode);
switch (inode->i_mode & S_IFMT) { switch (inode->i_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
inode->i_op = &cifs_file_inode_ops; inode->i_op = &cifs_file_inode_ops;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
set_bit(NETFS_ICTX_UNBUFFERED, &ictx->flags);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop = &cifs_file_direct_nobrl_ops; inode->i_fop = &cifs_file_direct_nobrl_ops;
else else
...@@ -57,6 +72,7 @@ static void cifs_set_ops(struct inode *inode) ...@@ -57,6 +72,7 @@ static void cifs_set_ops(struct inode *inode)
inode->i_data.a_ops = &cifs_addr_ops_smallbuf; inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
else else
inode->i_data.a_ops = &cifs_addr_ops; inode->i_data.a_ops = &cifs_addr_ops;
mapping_set_large_folios(inode->i_mapping);
break; break;
case S_IFDIR: case S_IFDIR:
if (IS_AUTOMOUNT(inode)) { if (IS_AUTOMOUNT(inode)) {
...@@ -221,8 +237,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr, ...@@ -221,8 +237,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
if (fattr->cf_flags & CIFS_FATTR_JUNCTION) if (fattr->cf_flags & CIFS_FATTR_JUNCTION)
inode->i_flags |= S_AUTOMOUNT; inode->i_flags |= S_AUTOMOUNT;
if (inode->i_state & I_NEW) if (inode->i_state & I_NEW) {
cifs_set_netfs_context(inode);
cifs_set_ops(inode); cifs_set_ops(inode);
}
return 0; return 0;
} }
...@@ -2431,24 +2449,6 @@ cifs_dentry_needs_reval(struct dentry *dentry) ...@@ -2431,24 +2449,6 @@ cifs_dentry_needs_reval(struct dentry *dentry)
return false; return false;
} }
/*
* Zap the cache. Called when invalid_mapping flag is set.
*/
int
cifs_invalidate_mapping(struct inode *inode)
{
int rc = 0;
if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
rc = invalidate_inode_pages2(inode->i_mapping);
if (rc)
cifs_dbg(VFS, "%s: invalidate inode %p failed with rc %d\n",
__func__, inode, rc);
}
return rc;
}
/** /**
* cifs_wait_bit_killable - helper for functions that are sleeping on bit locks * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks
* *
...@@ -2485,9 +2485,12 @@ cifs_revalidate_mapping(struct inode *inode) ...@@ -2485,9 +2485,12 @@ cifs_revalidate_mapping(struct inode *inode)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)
goto skip_invalidate; goto skip_invalidate;
rc = cifs_invalidate_mapping(inode); rc = filemap_invalidate_inode(inode, true, 0, LLONG_MAX);
if (rc) if (rc) {
cifs_dbg(VFS, "%s: invalidate inode %p failed with rc %d\n",
__func__, inode, rc);
set_bit(CIFS_INO_INVALID_MAPPING, flags); set_bit(CIFS_INO_INVALID_MAPPING, flags);
}
} }
skip_invalidate: skip_invalidate:
......
...@@ -217,8 +217,8 @@ smb2_get_credits(struct mid_q_entry *mid) ...@@ -217,8 +217,8 @@ smb2_get_credits(struct mid_q_entry *mid)
} }
static int static int
smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, smb2_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
unsigned int *num, struct cifs_credits *credits) size_t *num, struct cifs_credits *credits)
{ {
int rc = 0; int rc = 0;
unsigned int scredits, in_flight; unsigned int scredits, in_flight;
...@@ -4490,7 +4490,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, ...@@ -4490,7 +4490,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
unsigned int cur_off; unsigned int cur_off;
unsigned int cur_page_idx; unsigned int cur_page_idx;
unsigned int pad_len; unsigned int pad_len;
struct cifs_readdata *rdata = mid->callback_data; struct cifs_io_subrequest *rdata = mid->callback_data;
struct smb2_hdr *shdr = (struct smb2_hdr *)buf; struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
int length; int length;
bool use_rdma_mr = false; bool use_rdma_mr = false;
...@@ -4592,7 +4592,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, ...@@ -4592,7 +4592,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
/* Copy the data to the output I/O iterator. */ /* Copy the data to the output I/O iterator. */
rdata->result = cifs_copy_pages_to_iter(pages, pages_len, rdata->result = cifs_copy_pages_to_iter(pages, pages_len,
cur_off, &rdata->iter); cur_off, &rdata->subreq.io_iter);
if (rdata->result != 0) { if (rdata->result != 0) {
if (is_offloaded) if (is_offloaded)
mid->mid_state = MID_RESPONSE_MALFORMED; mid->mid_state = MID_RESPONSE_MALFORMED;
...@@ -4606,7 +4606,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, ...@@ -4606,7 +4606,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
/* read response payload is in buf */ /* read response payload is in buf */
WARN_ONCE(pages && !xa_empty(pages), WARN_ONCE(pages && !xa_empty(pages),
"read data can be either in buf or in pages"); "read data can be either in buf or in pages");
length = copy_to_iter(buf + data_offset, data_len, &rdata->iter); length = copy_to_iter(buf + data_offset, data_len, &rdata->subreq.io_iter);
if (length < 0) if (length < 0)
return length; return length;
rdata->got_bytes = data_len; rdata->got_bytes = data_len;
......
This diff is collapsed.
...@@ -210,11 +210,10 @@ extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -210,11 +210,10 @@ extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, u64 persistent_fid, u64 volatile_fid,
__le64 *uniqueid); __le64 *uniqueid);
extern int smb2_async_readv(struct cifs_readdata *rdata); extern int smb2_async_readv(struct cifs_io_subrequest *rdata);
extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, char **buf, int *buf_type); unsigned int *nbytes, char **buf, int *buf_type);
extern int smb2_async_writev(struct cifs_writedata *wdata, extern void smb2_async_writev(struct cifs_io_subrequest *wdata);
void (*release)(struct kref *kref));
extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, struct kvec *iov, int n_vec); unsigned int *nbytes, struct kvec *iov, int n_vec);
extern int SMB2_echo(struct TCP_Server_Info *server); extern int SMB2_echo(struct TCP_Server_Info *server);
......
...@@ -85,6 +85,62 @@ smb3_tcon_ref_traces; ...@@ -85,6 +85,62 @@ smb3_tcon_ref_traces;
/* For logging errors in read or write */ /* For logging errors in read or write */
DECLARE_EVENT_CLASS(smb3_rw_err_class, DECLARE_EVENT_CLASS(smb3_rw_err_class,
TP_PROTO(unsigned int rreq_debug_id,
unsigned int rreq_debug_index,
unsigned int xid,
__u64 fid,
__u32 tid,
__u64 sesid,
__u64 offset,
__u32 len,
int rc),
TP_ARGS(rreq_debug_id, rreq_debug_index,
xid, fid, tid, sesid, offset, len, rc),
TP_STRUCT__entry(
__field(unsigned int, rreq_debug_id)
__field(unsigned int, rreq_debug_index)
__field(unsigned int, xid)
__field(__u64, fid)
__field(__u32, tid)
__field(__u64, sesid)
__field(__u64, offset)
__field(__u32, len)
__field(int, rc)
),
TP_fast_assign(
__entry->rreq_debug_id = rreq_debug_id;
__entry->rreq_debug_index = rreq_debug_index;
__entry->xid = xid;
__entry->fid = fid;
__entry->tid = tid;
__entry->sesid = sesid;
__entry->offset = offset;
__entry->len = len;
__entry->rc = rc;
),
TP_printk("\tR=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d",
__entry->rreq_debug_id, __entry->rreq_debug_index,
__entry->xid, __entry->sesid, __entry->tid, __entry->fid,
__entry->offset, __entry->len, __entry->rc)
)
#define DEFINE_SMB3_RW_ERR_EVENT(name) \
DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \
TP_PROTO(unsigned int rreq_debug_id, \
unsigned int rreq_debug_index, \
unsigned int xid, \
__u64 fid, \
__u32 tid, \
__u64 sesid, \
__u64 offset, \
__u32 len, \
int rc), \
TP_ARGS(rreq_debug_id, rreq_debug_index, xid, fid, tid, sesid, offset, len, rc))
DEFINE_SMB3_RW_ERR_EVENT(read_err);
/* For logging errors in other file I/O ops */
DECLARE_EVENT_CLASS(smb3_other_err_class,
TP_PROTO(unsigned int xid, TP_PROTO(unsigned int xid,
__u64 fid, __u64 fid,
__u32 tid, __u32 tid,
...@@ -116,8 +172,8 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class, ...@@ -116,8 +172,8 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class,
__entry->offset, __entry->len, __entry->rc) __entry->offset, __entry->len, __entry->rc)
) )
#define DEFINE_SMB3_RW_ERR_EVENT(name) \ #define DEFINE_SMB3_OTHER_ERR_EVENT(name) \
DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \ DEFINE_EVENT(smb3_other_err_class, smb3_##name, \
TP_PROTO(unsigned int xid, \ TP_PROTO(unsigned int xid, \
__u64 fid, \ __u64 fid, \
__u32 tid, \ __u32 tid, \
...@@ -127,15 +183,67 @@ DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \ ...@@ -127,15 +183,67 @@ DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \
int rc), \ int rc), \
TP_ARGS(xid, fid, tid, sesid, offset, len, rc)) TP_ARGS(xid, fid, tid, sesid, offset, len, rc))
DEFINE_SMB3_RW_ERR_EVENT(write_err); DEFINE_SMB3_OTHER_ERR_EVENT(write_err);
DEFINE_SMB3_RW_ERR_EVENT(read_err); DEFINE_SMB3_OTHER_ERR_EVENT(query_dir_err);
DEFINE_SMB3_RW_ERR_EVENT(query_dir_err); DEFINE_SMB3_OTHER_ERR_EVENT(zero_err);
DEFINE_SMB3_RW_ERR_EVENT(zero_err); DEFINE_SMB3_OTHER_ERR_EVENT(falloc_err);
DEFINE_SMB3_RW_ERR_EVENT(falloc_err);
/* For logging successful read or write */ /* For logging successful read or write */
DECLARE_EVENT_CLASS(smb3_rw_done_class, DECLARE_EVENT_CLASS(smb3_rw_done_class,
TP_PROTO(unsigned int rreq_debug_id,
unsigned int rreq_debug_index,
unsigned int xid,
__u64 fid,
__u32 tid,
__u64 sesid,
__u64 offset,
__u32 len),
TP_ARGS(rreq_debug_id, rreq_debug_index,
xid, fid, tid, sesid, offset, len),
TP_STRUCT__entry(
__field(unsigned int, rreq_debug_id)
__field(unsigned int, rreq_debug_index)
__field(unsigned int, xid)
__field(__u64, fid)
__field(__u32, tid)
__field(__u64, sesid)
__field(__u64, offset)
__field(__u32, len)
),
TP_fast_assign(
__entry->rreq_debug_id = rreq_debug_id;
__entry->rreq_debug_index = rreq_debug_index;
__entry->xid = xid;
__entry->fid = fid;
__entry->tid = tid;
__entry->sesid = sesid;
__entry->offset = offset;
__entry->len = len;
),
TP_printk("R=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x",
__entry->rreq_debug_id, __entry->rreq_debug_index,
__entry->xid, __entry->sesid, __entry->tid, __entry->fid,
__entry->offset, __entry->len)
)
#define DEFINE_SMB3_RW_DONE_EVENT(name) \
DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \
TP_PROTO(unsigned int rreq_debug_id, \
unsigned int rreq_debug_index, \
unsigned int xid, \
__u64 fid, \
__u32 tid, \
__u64 sesid, \
__u64 offset, \
__u32 len), \
TP_ARGS(rreq_debug_id, rreq_debug_index, xid, fid, tid, sesid, offset, len))
DEFINE_SMB3_RW_DONE_EVENT(read_enter);
DEFINE_SMB3_RW_DONE_EVENT(read_done);
/* For logging successful other op */
DECLARE_EVENT_CLASS(smb3_other_done_class,
TP_PROTO(unsigned int xid, TP_PROTO(unsigned int xid,
__u64 fid, __u64 fid,
__u32 tid, __u32 tid,
...@@ -164,8 +272,8 @@ DECLARE_EVENT_CLASS(smb3_rw_done_class, ...@@ -164,8 +272,8 @@ DECLARE_EVENT_CLASS(smb3_rw_done_class,
__entry->offset, __entry->len) __entry->offset, __entry->len)
) )
#define DEFINE_SMB3_RW_DONE_EVENT(name) \ #define DEFINE_SMB3_OTHER_DONE_EVENT(name) \
DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \ DEFINE_EVENT(smb3_other_done_class, smb3_##name, \
TP_PROTO(unsigned int xid, \ TP_PROTO(unsigned int xid, \
__u64 fid, \ __u64 fid, \
__u32 tid, \ __u32 tid, \
...@@ -174,16 +282,14 @@ DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \ ...@@ -174,16 +282,14 @@ DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \
__u32 len), \ __u32 len), \
TP_ARGS(xid, fid, tid, sesid, offset, len)) TP_ARGS(xid, fid, tid, sesid, offset, len))
DEFINE_SMB3_RW_DONE_EVENT(write_enter); DEFINE_SMB3_OTHER_DONE_EVENT(write_enter);
DEFINE_SMB3_RW_DONE_EVENT(read_enter); DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_enter);
DEFINE_SMB3_RW_DONE_EVENT(query_dir_enter); DEFINE_SMB3_OTHER_DONE_EVENT(zero_enter);
DEFINE_SMB3_RW_DONE_EVENT(zero_enter); DEFINE_SMB3_OTHER_DONE_EVENT(falloc_enter);
DEFINE_SMB3_RW_DONE_EVENT(falloc_enter); DEFINE_SMB3_OTHER_DONE_EVENT(write_done);
DEFINE_SMB3_RW_DONE_EVENT(write_done); DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_done);
DEFINE_SMB3_RW_DONE_EVENT(read_done); DEFINE_SMB3_OTHER_DONE_EVENT(zero_done);
DEFINE_SMB3_RW_DONE_EVENT(query_dir_done); DEFINE_SMB3_OTHER_DONE_EVENT(falloc_done);
DEFINE_SMB3_RW_DONE_EVENT(zero_done);
DEFINE_SMB3_RW_DONE_EVENT(falloc_done);
/* For logging successful set EOF (truncate) */ /* For logging successful set EOF (truncate) */
DECLARE_EVENT_CLASS(smb3_eof_class, DECLARE_EVENT_CLASS(smb3_eof_class,
......
...@@ -691,8 +691,8 @@ wait_for_compound_request(struct TCP_Server_Info *server, int num, ...@@ -691,8 +691,8 @@ wait_for_compound_request(struct TCP_Server_Info *server, int num,
} }
int int
cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, cifs_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
unsigned int *num, struct cifs_credits *credits) size_t *num, struct cifs_credits *credits)
{ {
*num = size; *num = size;
credits->value = 0; credits->value = 0;
...@@ -1692,7 +1692,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid, ...@@ -1692,7 +1692,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
static int static int
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{ {
struct cifs_readdata *rdata = mid->callback_data; struct cifs_io_subrequest *rdata = mid->callback_data;
return __cifs_readv_discard(server, mid, rdata->result); return __cifs_readv_discard(server, mid, rdata->result);
} }
...@@ -1702,13 +1702,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -1702,13 +1702,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{ {
int length, len; int length, len;
unsigned int data_offset, data_len; unsigned int data_offset, data_len;
struct cifs_readdata *rdata = mid->callback_data; struct cifs_io_subrequest *rdata = mid->callback_data;
char *buf = server->smallbuf; char *buf = server->smallbuf;
unsigned int buflen = server->pdu_size + HEADER_PREAMBLE_SIZE(server); unsigned int buflen = server->pdu_size + HEADER_PREAMBLE_SIZE(server);
bool use_rdma_mr = false; bool use_rdma_mr = false;
cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n", cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%zu\n",
__func__, mid->mid, rdata->offset, rdata->bytes); __func__, mid->mid, rdata->subreq.start, rdata->subreq.len);
/* /*
* read the rest of READ_RSP header (sans Data array), or whatever we * read the rest of READ_RSP header (sans Data array), or whatever we
...@@ -1813,8 +1813,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -1813,8 +1813,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
length = data_len; /* An RDMA read is already done. */ length = data_len; /* An RDMA read is already done. */
else else
#endif #endif
length = cifs_read_iter_from_socket(server, &rdata->iter, {
length = cifs_read_iter_from_socket(server, &rdata->subreq.io_iter,
data_len); data_len);
iov_iter_revert(&rdata->subreq.io_iter, data_len);
}
if (length > 0) if (length > 0)
rdata->got_bytes += length; rdata->got_bytes += length;
server->total_read += length; server->total_read += length;
......
...@@ -302,6 +302,7 @@ struct netfs_request_ops { ...@@ -302,6 +302,7 @@ struct netfs_request_ops {
/* Modification handling */ /* Modification handling */
void (*update_i_size)(struct inode *inode, loff_t i_size); void (*update_i_size)(struct inode *inode, loff_t i_size);
void (*post_modify)(struct inode *inode);
/* Write request handling */ /* Write request handling */
void (*begin_writeback)(struct netfs_io_request *wreq); void (*begin_writeback)(struct netfs_io_request *wreq);
......
...@@ -112,6 +112,7 @@ ...@@ -112,6 +112,7 @@
#define netfs_sreq_ref_traces \ #define netfs_sreq_ref_traces \
EM(netfs_sreq_trace_get_copy_to_cache, "GET COPY2C ") \ EM(netfs_sreq_trace_get_copy_to_cache, "GET COPY2C ") \
EM(netfs_sreq_trace_get_resubmit, "GET RESUBMIT") \ EM(netfs_sreq_trace_get_resubmit, "GET RESUBMIT") \
EM(netfs_sreq_trace_get_submit, "GET SUBMIT") \
EM(netfs_sreq_trace_get_short_read, "GET SHORTRD") \ EM(netfs_sreq_trace_get_short_read, "GET SHORTRD") \
EM(netfs_sreq_trace_new, "NEW ") \ EM(netfs_sreq_trace_new, "NEW ") \
EM(netfs_sreq_trace_put_cancel, "PUT CANCEL ") \ EM(netfs_sreq_trace_put_cancel, "PUT CANCEL ") \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment