diff mbox

[1/3] #6823 page reading with mandatory locking style

Message ID 201003311050.22864.piastry@etersoft.ru
State New
Headers show

Commit Message

piastry@etersoft.ru March 31, 2010, 6:50 a.m. UTC
В сообщении от 28 марта 2010 22:33:35 автор piastry@etersoft.ru написал:
> В сообщении от 27 марта 2010 04:57:28 вы написали:
> > On Wed, 24 Mar 2010 11:55:31 +0300
> > 
> > piastry@etersoft.ru wrote:
> > > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> > > index 5183bc2..2b894bd 100644
> > > --- a/fs/cifs/cifsfs.c
> > > +++ b/fs/cifs/cifsfs.c
> > > @@ -616,6 +616,51 @@ cifs_get_sb(struct file_system_type *fs_type,
> > > 
> > >  	return 0;
> > >  
> > >  }
> > > 
> > > +static ssize_t cifs_sync_read(struct file *filp, char __user *buf,
> > > +				size_t len, loff_t *ppos)
> > > +{
> > > +	int retval, read, posix_locking = 0;
> > > +	struct file_lock pfLock;
> > > +	struct cifsInodeInfo *cifsInode;
> > > +	struct cifs_sb_info *cifs_sb;
> > > +	struct cifsTconInfo *tcon;
> > > +
> > > +	cifs_sb = CIFS_SB(filp->f_path.dentry->d_sb);
> > > +	tcon = cifs_sb->tcon;
> > > +	if ((tcon->ses->capabilities & CAP_UNIX) &&
> > > +	    (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
> > > && +	    ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
> > > +		posix_locking = 1;
> > > +
> > > +	retval = cifs_revalidate(filp->f_path.dentry);
> > > +	if (retval < 0)
> > > +		return (ssize_t)retval;
> > > +
> > > +	memset(&pfLock, 0, sizeof(pfLock));
> > > +	pfLock.fl_type = F_RDLCK;
> > > +	pfLock.fl_start = *ppos;
> > > +	pfLock.fl_end = *ppos+len;
> > > +	cifsInode = CIFS_I(filp->f_path.dentry->d_inode);
> > > +	if (cifsInode == NULL)
> > > +		return -ENOENT;
> > > +
> > > +	if (!CIFS_I(filp->f_path.dentry->d_inode)->clientCanCacheRead &&
> > > +							!posix_locking) {
> > > +		retval = cifs_lock(filp, F_GETLK, &pfLock);
> > > +		if (retval < 0)
> > > +			return (ssize_t)retval;
> > > +		if (pfLock.fl_type == F_UNLCK)
> > > +			read = do_sync_read(filp, buf, len, ppos);
> > > +		else
> > > +			return -EACCES;
> > > +	} else
> > > +		read = do_sync_read(filp, buf, len, ppos);
> > > +
> > > +	if (read == -EACCES && !posix_locking)
> > > +		read = cifs_user_read(filp, buf, len, ppos);
> > > +	return read;
> > > +}
> > > +
> > > 
> > >  static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct
> > >  iovec *iov,
> > >  
> > >  				   unsigned long nr_segs, loff_t pos)
> > >  
> > >  {
> > > 
> > > @@ -737,7 +782,7 @@ const struct inode_operations
> > > cifs_symlink_inode_ops = {
> > > 
> > >  };
> > >  
> > >  const struct file_operations cifs_file_ops = {
> > > 
> > > -	.read = do_sync_read,
> > > +	.read = cifs_sync_read,
> > > 
> > >  	.write = do_sync_write,
> > >  	.aio_read = generic_file_aio_read,
> > >  	.aio_write = cifs_file_aio_write,
> > >  
> > >  Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com>
> > 
> > I have no clue what this patch is intended to do. Can you possibly
> > explain it, preferably in a resent patch with proper patch descripion
> > and signed-off-by line at the beginning?
> 
> [CIFS] Fix page reading error with mandatory locking style
> 
> If we lock file from one process from 1 to 2 and then try to read it
> from another from 0 to 1 without direct mount options, reading fails.
> That's why vfs tries to read whole page and fails due the lock from
> the first process.
> 
> Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com>
> 
> See patch in attachment.
> 
> --
> Best regards,
> Pavel Shilovsky.

Resend right variant of this patch.

--
Best regards,
Pavel Shilovsky.
diff mbox

Patch

From: Pavel Shilovsky <piastryyy@gmail.com>

[CIFS] Fix page reading error with mandatory locking style

If we lock file from one process from 1 to 2 and then try to read it
from another from 0 to 1 without direct mount options, reading fails.
That's why vfs tries to read whole page and fails due the lock from
the first process.

Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com>
---
 fs/cifs/cifsfs.c |   47 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index ded66be..94a3b1f 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -616,6 +616,51 @@  cifs_get_sb(struct file_system_type *fs_type,
 	return 0;
 }
 
+static ssize_t cifs_sync_read(struct file *filp, char __user *buf,
+				size_t len, loff_t *ppos)
+{
+	int retval, read, posix_locking = 0;
+	struct file_lock pfLock;
+	struct cifsInodeInfo *cifsInode;
+	struct cifs_sb_info *cifs_sb;
+	struct cifsTconInfo *tcon;
+
+	cifs_sb = CIFS_SB(filp->f_path.dentry->d_sb);
+	tcon = cifs_sb->tcon;
+	if ((tcon->ses->capabilities & CAP_UNIX) &&
+	    (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
+	    ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
+		posix_locking = 1;
+
+	retval = cifs_revalidate_file(filp);
+	if (retval < 0)
+		return (ssize_t)retval;
+
+	memset(&pfLock, 0, sizeof(pfLock));
+	pfLock.fl_type = F_RDLCK;
+	pfLock.fl_start = *ppos;
+	pfLock.fl_end = *ppos+len;
+	cifsInode = CIFS_I(filp->f_path.dentry->d_inode);
+	if (cifsInode == NULL)
+		return -ENOENT;
+
+	if (!CIFS_I(filp->f_path.dentry->d_inode)->clientCanCacheRead &&
+							!posix_locking) {
+		retval = cifs_lock(filp, F_GETLK, &pfLock);
+		if (retval < 0)
+			return (ssize_t)retval;
+		if (pfLock.fl_type == F_UNLCK)
+			read = do_sync_read(filp, buf, len, ppos);
+		else
+			return -EACCES;
+	} else
+		read = do_sync_read(filp, buf, len, ppos);
+
+	if (read == -EACCES && !posix_locking)
+		read = cifs_user_read(filp, buf, len, ppos);
+	return read;
+}
+
 static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 				   unsigned long nr_segs, loff_t pos)
 {
@@ -737,7 +782,7 @@  const struct inode_operations cifs_symlink_inode_ops = {
 };
 
 const struct file_operations cifs_file_ops = {
-	.read = do_sync_read,
+	.read = cifs_sync_read,
 	.write = do_sync_write,
 	.aio_read = generic_file_aio_read,
 	.aio_write = cifs_file_aio_write,
-- 
1.6.6.1