Commit 69c3c023 authored by David Howells's avatar David Howells
Browse files

cifs: Implement netfslib hooks



Provide implementation of the netfslib hooks that will be used by netfslib
to ask cifs to set up and perform operations.  Of particular note are

 (*) cifs_clamp_length() - This is used to negotiate the size of the next
     subrequest in a read request, taking into account the credit available
     and the rsize.  The credits are attached to the subrequest.

 (*) cifs_req_issue_read() - This is used to issue a subrequest that has
     been set up and clamped.

 (*) cifs_prepare_write() - This prepares to fill a subrequest by picking a
     channel, reopening the file and requesting credits so that we can set
     the maximum size of the subrequest and also sets the maximum number of
     segments if we're doing RDMA.

 (*) cifs_issue_write() - This releases any unneeded credits and issues an
     asynchronous data write for the contiguous slice of file covered by
     the subrequest.  This should possibly be folded in to all
     ->async_writev() ops and that called directly.

 (*) cifs_begin_writeback() - This gets the cached writable handle through
     which we do writeback (this does not affect writethrough, unbuffered
     or direct writes).

At this point, cifs is not wired up to actually *use* netfslib; that will
be done in a subsequent patch.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Shyam Prasad N <nspmangalore@gmail.com>
cc: Rohith Surabattula <rohiths.msft@gmail.com>
cc: Jeff Layton <jlayton@kernel.org>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
cc: linux-mm@kvack.org
parent c20c0d73
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -405,6 +405,9 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
	} while (iov_iter_count(iter));

out:
	if (likely(written) && ctx->ops->post_modify)
		ctx->ops->post_modify(inode);

	if (unlikely(wreq)) {
		ret2 = netfs_end_writethrough(wreq, &wbc, writethrough);
		wbc_detach_inode(&wbc);
@@ -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 file *file = vmf->vma->vm_file;
	struct inode *inode = file_inode(file);
	struct netfs_inode *ictx = netfs_inode(inode);
	vm_fault_t ret = VM_FAULT_RETRY;
	int err;

@@ -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);
	netfs_set_group(folio, netfs_group);
	file_update_time(file);
	if (ictx->ops->post_modify)
		ictx->ops->post_modify(inode);
	ret = VM_FAULT_LOCKED;
out:
	sb_end_pagefault(inode->i_sb);
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
config CIFS
	tristate "SMB3 and CIFS support (advanced network filesystem)"
	depends on INET
	select NETFS_SUPPORT
	select NLS
	select NLS_UCS2_UTILS
	select CRYPTO
+1 −1
Original line number Diff line number Diff line
@@ -1758,7 +1758,7 @@ static int cifs_init_netfs(void)
{
	cifs_io_request_cachep =
		kmem_cache_create("cifs_io_request",
				  sizeof(struct netfs_io_request), 0,
				  sizeof(struct cifs_io_request), 0,
				  SLAB_HWCACHE_ALIGN, NULL);
	if (!cifs_io_request_cachep)
		goto nomem_req;
+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ extern const struct inode_operations cifs_namespace_inode_operations;


/* 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_direct_ops; /* if directio mnt */
extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */
+19 −9
Original line number Diff line number Diff line
@@ -1491,15 +1491,24 @@ struct cifs_aio_ctx {
	bool			direct_io;
};

struct cifs_io_request {
	struct netfs_io_request		rreq;
	struct cifsFileInfo		*cfile;
};

/* asynchronous read support */
struct cifs_io_subrequest {
	union {
		struct netfs_io_subrequest subreq;
	struct cifsFileInfo		*cfile;
	struct address_space		*mapping;
	struct cifs_aio_ctx		*ctx;
		struct netfs_io_request *rreq;
		struct cifs_io_request *req;
	};
	ssize_t				got_bytes;
	pid_t				pid;
	unsigned int			xid;
	int				result;
	bool				have_xid;
	bool				replay;
	struct kvec			iov[2];
	struct TCP_Server_Info		*server;
#ifdef CONFIG_CIFS_SMB_DIRECT
@@ -1507,15 +1516,16 @@ struct cifs_io_subrequest {
#endif
	struct cifs_credits		credits;

	enum writeback_sync_modes	sync_mode;
	bool				uncached;
	bool				replay;
	struct bio_vec			*bv;

	// TODO: Remove following elements
	struct list_head		list;
	struct completion		done;
	struct work_struct		work;
	struct cifsFileInfo		*cfile;
	struct address_space		*mapping;
	struct cifs_aio_ctx		*ctx;
	enum writeback_sync_modes	sync_mode;
	bool				uncached;
	struct bio_vec			*bv;
};

/*
Loading