linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@redhat.com>
To: "Steve French" <smfrench@gmail.com>
Cc: linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	"linux-cifs-client@lists.samba.org"
	<linux-cifs-client@lists.samba.org>
Subject: Re: [PATCH] do not attempt to close cifs files which are already closed due to session reconnect
Date: Wed, 19 Nov 2008 07:04:29 -0500	[thread overview]
Message-ID: <20081119070429.1d977f72@tleilax.poochiereds.net> (raw)
In-Reply-To: <524f69650811181946s79fdba88w11c8c4c6677df1db@mail.gmail.com>

On Tue, 18 Nov 2008 21:46:59 -0600
"Steve French" <smfrench@gmail.com> wrote:

> In hunting down why we could get EBADF returned on close in some cases
> after reconnect, I found out that cifs_close was checking to see if
> the share (mounted server export) was valid (didn't need reconnect due
> to session crash/timeout) but we weren't checking if the handle was
> valid (ie the share was reconnected, but the file handle was not
> reopened yet).  It also adds some locking around the updates/checks of
> the cifs_file->invalidHandle flag
> 
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 6449e1a..cd975fe 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -512,8 +512,9 @@ int cifs_close(struct inode *inode, struct file *file)
>  				if (atomic_read(&pSMBFile->wrtPending))
>  					cERROR(1,
>  						("close with pending writes"));
> -				rc = CIFSSMBClose(xid, pTcon,
> -						  pSMBFile->netfid);
> +				if (!pSMBFile->invalidHandle)
> +					rc = CIFSSMBClose(xid, pTcon,
> +							  pSMBFile->netfid);


Do we need a lock around this check for invalidHandle? Could this race
with mark_open_files_invalid()?

>  			}
>  		}
> 
> @@ -587,15 +588,18 @@ int cifs_closedir(struct inode *inode, struct file *file)
>  		pTcon = cifs_sb->tcon;
> 
>  		cFYI(1, ("Freeing private data in close dir"));
> +		write_lock(&GlobalSMBSeslock);
>  		if (!pCFileStruct->srch_inf.endOfSearch &&
>  		    !pCFileStruct->invalidHandle) {
>  			pCFileStruct->invalidHandle = true;
> +			write_unlock(&GlobalSMBSeslock);
>  			rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
>  			cFYI(1, ("Closing uncompleted readdir with rc %d",
>  				 rc));
>  			/* not much we can do if it fails anyway, ignore rc */
>  			rc = 0;
> -		}
> +		} else
> +			write_unlock(&GlobalSMBSeslock);
>  		ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
>  		if (ptmp) {
>  			cFYI(1, ("closedir free smb buf in srch struct"));
> diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
> index addd1dc..9ee3f68 100644
> --- a/fs/cifs/misc.c
> +++ b/fs/cifs/misc.c
> @@ -555,12 +555,14 @@ is_valid_oplock_break(struct smb_hdr *buf,
> struct TCP_Server_Info *srv)
>  				continue;
> 
>  			cifs_stats_inc(&tcon->num_oplock_brks);
> +			write_lock(&GlobalSMBSeslock);
>  			list_for_each(tmp2, &tcon->openFileList) {
>  				netfile = list_entry(tmp2, struct cifsFileInfo,
>  						     tlist);
>  				if (pSMB->Fid != netfile->netfid)
>  					continue;
> 
> +				write_unlock(&GlobalSMBSeslock);
>  				read_unlock(&cifs_tcp_ses_lock);
>  				cFYI(1, ("file id match, oplock break"));
>  				pCifsInode = CIFS_I(netfile->pInode);
> @@ -576,6 +578,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct
> TCP_Server_Info *srv)
> 
>  				return true;
>  			}
> +			write_unlock(&GlobalSMBSeslock);
>  			read_unlock(&cifs_tcp_ses_lock);
>  			cFYI(1, ("No matching file for oplock break"));
>  			return true;
> diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
> index 58d5729..9f51f9b 100644
> --- a/fs/cifs/readdir.c
> +++ b/fs/cifs/readdir.c
> @@ -741,11 +741,14 @@ static int find_cifs_entry(const int xid, struct
> cifsTconInfo *pTcon,
>  	   (index_to_find < first_entry_in_buffer)) {
>  		/* close and restart search */
>  		cFYI(1, ("search backing up - close and restart search"));
> +		write_lock(&GlobalSMBSeslock);
>  		if (!cifsFile->srch_inf.endOfSearch &&
>  		    !cifsFile->invalidHandle) {
>  			cifsFile->invalidHandle = true;
> +			write_unlock(&GlobalSMBSeslock);
>  			CIFSFindClose(xid, pTcon, cifsFile->netfid);
> -		}
> +		} else
> +			write_unlock(&GlobalSMBSeslock);
>  		if (cifsFile->srch_inf.ntwrk_buf_start) {
>  			cFYI(1, ("freeing SMB ff cache buf on search rewind"));
>  			if (cifsFile->srch_inf.smallBuf)
> 
> 
> 

Also, initiate_cifs_search() allocates a cifsFileInfo struct and then
sets invalidHandle to true. Is there a possible race between those
operations? It may be safe, but it might be nice to comment why that
is. In hindsight it might have been better to invert this flag (i.e.
validHandle) so that it would be false immediately after kzalloc()
until it is set true...

-- 
Jeff Layton <jlayton@redhat.com>

  reply	other threads:[~2008-11-19 12:04 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-19  3:46 [PATCH] do not attempt to close cifs files which are already closed due to session reconnect Steve French
2008-11-19 12:04 ` Jeff Layton [this message]
2008-11-19 16:05   ` Steve French
2008-11-20  5:24   ` Steve French
2008-11-20 13:02     ` Jeff Layton
2008-11-20 14:04       ` Steve French
2008-11-20 14:39         ` Jeff Layton
2008-11-20 16:43           ` Steve French
2008-11-20 18:55             ` Steve French

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=20081119070429.1d977f72@tleilax.poochiereds.net \
    --to=jlayton@redhat.com \
    --cc=linux-cifs-client@lists.samba.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=smfrench@gmail.com \
    /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).