linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Naveen Mamindlapalli <naveenm@marvell.com>
To: David Howells <dhowells@redhat.com>, Steve French <smfrench@gmail.com>
Cc: Jeff Layton <jlayton@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	Paulo Alcantara <pc@manguebit.com>,
	Shyam Prasad N <sprasad@microsoft.com>,
	Tom Talpey <tom@talpey.com>,
	Christian Brauner <christian@brauner.io>,
	"netfs@lists.linux.dev" <netfs@lists.linux.dev>,
	"linux-cifs@vger.kernel.org" <linux-cifs@vger.kernel.org>,
	"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
	"linux-mm@kvack.org" <linux-mm@kvack.org>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Steve French <sfrench@samba.org>,
	Shyam Prasad N <nspmangalore@gmail.com>,
	Rohith Surabattula <rohiths.msft@gmail.com>
Subject: RE: [PATCH v6 11/15] cifs: When caching, try to open O_WRONLY file rdwr on server
Date: Fri, 29 Mar 2024 09:58:28 +0000	[thread overview]
Message-ID: <SJ2PR18MB5635CA3F5A382FC12D6CE58FA23A2@SJ2PR18MB5635.namprd18.prod.outlook.com> (raw)
In-Reply-To: <20240328165845.2782259-12-dhowells@redhat.com>


> -----Original Message-----
> From: David Howells <dhowells@redhat.com>
> Sent: Thursday, March 28, 2024 10:28 PM
> To: Steve French <smfrench@gmail.com>
> Cc: David Howells <dhowells@redhat.com>; Jeff Layton <jlayton@kernel.org>;
> Matthew Wilcox <willy@infradead.org>; Paulo Alcantara <pc@manguebit.com>;
> Shyam Prasad N <sprasad@microsoft.com>; Tom Talpey <tom@talpey.com>;
> Christian Brauner <christian@brauner.io>; netfs@lists.linux.dev; linux-
> cifs@vger.kernel.org; linux-fsdevel@vger.kernel.org; linux-mm@kvack.org;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Steve French
> <sfrench@samba.org>; Shyam Prasad N <nspmangalore@gmail.com>; Rohith
> Surabattula <rohiths.msft@gmail.com>
> Subject: [PATCH v6 11/15] cifs: When caching, try to open
> O_WRONLY file rdwr on server
> 
> When we're engaged in local caching of a cifs filesystem, we cannot perform
> caching of a partially written cache granule unless we can read the rest of the
> granule.  To deal with this, if a file is opened O_WRONLY locally, but the mount
> was given the "-o fsc" flag, try first opening the remote file with
> GENERIC_READ|GENERIC_WRITE and if that returns -EACCES, try dropping
> the GENERIC_READ and doing the open again.  If that last succeeds, invalidate
> the cache for that file as for O_DIRECT.
> 
> Signed-off-by: David 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
> ---
>  fs/smb/client/dir.c     | 15 ++++++++++++
>  fs/smb/client/file.c    | 51 +++++++++++++++++++++++++++++++++--------
>  fs/smb/client/fscache.h |  6 +++++
>  3 files changed, 62 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index
> 89333d9bce36..37897b919dd5 100644
> --- a/fs/smb/client/dir.c
> +++ b/fs/smb/client/dir.c
> @@ -189,6 +189,7 @@ static int cifs_do_create(struct inode *inode, struct dentry
> *direntry, unsigned
>  	int disposition;
>  	struct TCP_Server_Info *server = tcon->ses->server;
>  	struct cifs_open_parms oparms;
> +	int rdwr_for_fscache = 0;
> 
>  	*oplock = 0;
>  	if (tcon->ses->server->oplocks)
> @@ -200,6 +201,10 @@ static int cifs_do_create(struct inode *inode, struct
> dentry *direntry, unsigned
>  		return PTR_ERR(full_path);
>  	}
> 
> +	/* If we're caching, we need to be able to fill in around partial writes. */
> +	if (cifs_fscache_enabled(inode) && (oflags & O_ACCMODE) ==
> O_WRONLY)
> +		rdwr_for_fscache = 1;
> +
>  #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
>  	if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open
> &&
>  	    (CIFS_UNIX_POSIX_PATH_OPS_CAP &
> @@ -276,6 +281,8 @@ static int cifs_do_create(struct inode *inode, struct dentry
> *direntry, unsigned
>  		desired_access |= GENERIC_READ; /* is this too little? */
>  	if (OPEN_FMODE(oflags) & FMODE_WRITE)
>  		desired_access |= GENERIC_WRITE;
> +	if (rdwr_for_fscache == 1)
> +		desired_access |= GENERIC_READ;
> 
>  	disposition = FILE_OVERWRITE_IF;
>  	if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) @@ -
> 304,6 +311,7 @@ static int cifs_do_create(struct inode *inode, struct dentry
> *direntry, unsigned
>  	if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
>  		create_options |= CREATE_OPTION_READONLY;
> 
> +retry_open:
>  	oparms = (struct cifs_open_parms) {
>  		.tcon = tcon,
>  		.cifs_sb = cifs_sb,
> @@ -317,8 +325,15 @@ static int cifs_do_create(struct inode *inode, struct
> dentry *direntry, unsigned
>  	rc = server->ops->open(xid, &oparms, oplock, buf);
>  	if (rc) {
>  		cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc);
> +		if (rc == -EACCES && rdwr_for_fscache == 1) {
> +			desired_access &= ~GENERIC_READ;
> +			rdwr_for_fscache = 2;
> +			goto retry_open;
> +		}
>  		goto out;
>  	}
> +	if (rdwr_for_fscache == 2)
> +		cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE);
> 
>  #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
>  	/*
> diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index
> 73573dadf90e..761a80963f76 100644
> --- a/fs/smb/client/file.c
> +++ b/fs/smb/client/file.c
> @@ -521,12 +521,12 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
>  	 */
>  }
> 
> -static inline int cifs_convert_flags(unsigned int flags)
> +static inline int cifs_convert_flags(unsigned int flags, int
> +rdwr_for_fscache)
>  {
>  	if ((flags & O_ACCMODE) == O_RDONLY)
>  		return GENERIC_READ;
>  	else if ((flags & O_ACCMODE) == O_WRONLY)
> -		return GENERIC_WRITE;
> +		return rdwr_for_fscache == 1 ? (GENERIC_READ |
> GENERIC_WRITE) :
> +GENERIC_WRITE;
>  	else if ((flags & O_ACCMODE) == O_RDWR) {
>  		/* GENERIC_ALL is too much permission to request
>  		   can cause unnecessary access denied on create */ @@ -
> 663,11 +663,16 @@ static int cifs_nt_open(const char *full_path, struct inode
> *inode, struct cifs_
>  	int create_options = CREATE_NOT_DIR;
>  	struct TCP_Server_Info *server = tcon->ses->server;
>  	struct cifs_open_parms oparms;
> +	int rdwr_for_fscache = 0;
> 
>  	if (!server->ops->open)
>  		return -ENOSYS;
> 
> -	desired_access = cifs_convert_flags(f_flags);
> +	/* If we're caching, we need to be able to fill in around partial writes. */
> +	if (cifs_fscache_enabled(inode) && (f_flags & O_ACCMODE) ==
> O_WRONLY)
> +		rdwr_for_fscache = 1;
> +
> +	desired_access = cifs_convert_flags(f_flags, rdwr_for_fscache);
> 
>  /*********************************************************************
>   *  open flag mapping table:
> @@ -704,6 +709,7 @@ static int cifs_nt_open(const char *full_path, struct inode
> *inode, struct cifs_
>  	if (f_flags & O_DIRECT)
>  		create_options |= CREATE_NO_BUFFER;
> 
> +retry_open:
>  	oparms = (struct cifs_open_parms) {
>  		.tcon = tcon,
>  		.cifs_sb = cifs_sb,
> @@ -715,8 +721,16 @@ static int cifs_nt_open(const char *full_path, struct inode
> *inode, struct cifs_
>  	};
> 
>  	rc = server->ops->open(xid, &oparms, oplock, buf);
> -	if (rc)
> +	if (rc) {
> +		if (rc == -EACCES && rdwr_for_fscache == 1) {
> +			desired_access = cifs_convert_flags(f_flags, 0);
> +			rdwr_for_fscache = 2;
> +			goto retry_open;
> +		}
>  		return rc;
> +	}
> +	if (rdwr_for_fscache == 2)
> +		cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE);
> 
>  	/* TODO: Add support for calling posix query info but with passing in fid */
>  	if (tcon->unix_ext)
> @@ -1149,11 +1163,14 @@ int cifs_open(struct inode *inode, struct file *file)
>  use_cache:
>  	fscache_use_cookie(cifs_inode_cookie(file_inode(file)),
>  			   file->f_mode & FMODE_WRITE);
> -	if (file->f_flags & O_DIRECT &&
> -	    (!((file->f_flags & O_ACCMODE) != O_RDONLY) ||
> -	     file->f_flags & O_APPEND))
> -		cifs_invalidate_cache(file_inode(file),
> -				      FSCACHE_INVAL_DIO_WRITE);
> +	//if ((file->f_flags & O_ACCMODE) == O_WRONLY)
> +	//	goto inval;

Why to keep unused code?

Thanks,
Naveen

> +	if (!(file->f_flags & O_DIRECT))
> +		goto out;
> +	if ((file->f_flags & (O_ACCMODE | O_APPEND)) == O_RDONLY)
> +		goto out;
> +//inval:
> +	cifs_invalidate_cache(file_inode(file), FSCACHE_INVAL_DIO_WRITE);
> 
>  out:
>  	free_dentry_path(page);
> @@ -1218,6 +1235,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool
> can_flush)
>  	int disposition = FILE_OPEN;
>  	int create_options = CREATE_NOT_DIR;
>  	struct cifs_open_parms oparms;
> +	int rdwr_for_fscache = 0;
> 
>  	xid = get_xid();
>  	mutex_lock(&cfile->fh_mutex);
> @@ -1281,7 +1299,11 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool
> can_flush)
>  	}
>  #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
> 
> -	desired_access = cifs_convert_flags(cfile->f_flags);
> +	/* If we're caching, we need to be able to fill in around partial writes. */
> +	if (cifs_fscache_enabled(inode) && (cfile->f_flags & O_ACCMODE) ==
> O_WRONLY)
> +		rdwr_for_fscache = 1;
> +
> +	desired_access = cifs_convert_flags(cfile->f_flags, rdwr_for_fscache);
> 
>  	/* O_SYNC also has bit for O_DSYNC so following check picks up either
> */
>  	if (cfile->f_flags & O_SYNC)
> @@ -1293,6 +1315,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool
> can_flush)
>  	if (server->ops->get_lease_key)
>  		server->ops->get_lease_key(inode, &cfile->fid);
> 
> +retry_open:
>  	oparms = (struct cifs_open_parms) {
>  		.tcon = tcon,
>  		.cifs_sb = cifs_sb,
> @@ -1318,6 +1341,11 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool
> can_flush)
>  		/* indicate that we need to relock the file */
>  		oparms.reconnect = true;
>  	}
> +	if (rc == -EACCES && rdwr_for_fscache == 1) {
> +		desired_access = cifs_convert_flags(cfile->f_flags, 0);
> +		rdwr_for_fscache = 2;
> +		goto retry_open;
> +	}
> 
>  	if (rc) {
>  		mutex_unlock(&cfile->fh_mutex);
> @@ -1326,6 +1354,9 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool
> can_flush)
>  		goto reopen_error_exit;
>  	}
> 
> +	if (rdwr_for_fscache == 2)
> +		cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE);
> +
>  #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
>  reopen_success:
>  #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ diff --git
> a/fs/smb/client/fscache.h b/fs/smb/client/fscache.h index
> a3d73720914f..1f2ea9f5cc9a 100644
> --- a/fs/smb/client/fscache.h
> +++ b/fs/smb/client/fscache.h
> @@ -109,6 +109,11 @@ static inline void cifs_readahead_to_fscache(struct
> inode *inode,
>  		__cifs_readahead_to_fscache(inode, pos, len);  }
> 
> +static inline bool cifs_fscache_enabled(struct inode *inode) {
> +	return fscache_cookie_enabled(cifs_inode_cookie(inode));
> +}
> +
>  #else /* CONFIG_CIFS_FSCACHE */
>  static inline
>  void cifs_fscache_fill_coherency(struct inode *inode, @@ -124,6 +129,7 @@
> static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}  static
> inline void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) {}
> static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { return
> NULL; }  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 int cifs_fscache_query_occupancy(struct inode *inode,
>  					       pgoff_t first, unsigned int nr_pages,
> 


  reply	other threads:[~2024-03-29  9:59 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-28 16:57 [PATCH v6 00/15] netfs, cifs: Delegate high-level I/O to netfslib David Howells
2024-03-28 16:57 ` [PATCH v6 01/15] cifs: Replace cifs_readdata with a wrapper around netfs_io_subrequest David Howells
2024-03-28 16:57 ` [PATCH v6 02/15] cifs: Replace cifs_writedata " David Howells
2024-03-28 16:57 ` [PATCH v6 03/15] cifs: Use more fields from netfs_io_subrequest David Howells
2024-03-28 16:57 ` [PATCH v6 04/15] cifs: Make wait_mtu_credits take size_t args David Howells
2024-03-28 16:57 ` [PATCH v6 05/15] cifs: Replace the writedata replay bool with a netfs sreq flag David Howells
2024-03-28 16:57 ` [PATCH v6 06/15] cifs: Move cifs_loose_read_iter() and cifs_file_write_iter() to file.c David Howells
2024-03-28 16:57 ` [PATCH v6 07/15] cifs: Set zero_point in the copy_file_range() and remap_file_range() David Howells
2024-03-28 16:57 ` [PATCH v6 08/15] cifs: Add mempools for cifs_io_request and cifs_io_subrequest structs David Howells
2024-03-28 16:58 ` [PATCH v6 09/15] cifs: Make add_credits_and_wake_if() clear deducted credits David Howells
2024-03-28 16:58 ` [PATCH v6 10/15] cifs: Implement netfslib hooks David Howells
2024-03-28 16:58 ` [PATCH v6 11/15] cifs: When caching, try to open O_WRONLY file rdwr on server David Howells
2024-03-29  9:58   ` Naveen Mamindlapalli [this message]
2024-03-28 16:58 ` [PATCH v6 12/15] cifs: Cut over to using netfslib David Howells
2024-03-28 16:58 ` [PATCH v6 13/15] cifs: Remove some code that's no longer used, part 1 David Howells
2024-03-28 16:58 ` [PATCH v6 14/15] cifs: Remove some code that's no longer used, part 2 David Howells
2024-03-28 16:58 ` [PATCH v6 15/15] cifs: Remove some code that's no longer used, part 3 David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=SJ2PR18MB5635CA3F5A382FC12D6CE58FA23A2@SJ2PR18MB5635.namprd18.prod.outlook.com \
    --to=naveenm@marvell.com \
    --cc=christian@brauner.io \
    --cc=dhowells@redhat.com \
    --cc=jlayton@kernel.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=netdev@vger.kernel.org \
    --cc=netfs@lists.linux.dev \
    --cc=nspmangalore@gmail.com \
    --cc=pc@manguebit.com \
    --cc=rohiths.msft@gmail.com \
    --cc=sfrench@samba.org \
    --cc=smfrench@gmail.com \
    --cc=sprasad@microsoft.com \
    --cc=tom@talpey.com \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).