aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastryyy@gmail.com>2010-12-12 05:11:13 -0500
committerSteve French <sfrench@us.ibm.com>2011-01-20 16:42:21 -0500
commit8be7e6ba142423e6ad98fed293c96f196f685229 (patch)
tree25bd7ce4aed4740082f0a472a8eed35127d9d61e /fs
parent4f8ba8a0c095933dd54a2c281750c8a85b329b26 (diff)
CIFS: Implement cifs_strict_fsync
Invalidate inode mapping if we don't have at least Level II oplock in cifs_strict_fsync. Also remove filemap_write_and_wait call from cifs_fsync because it is previously called from vfs_fsync_range. Add file operations' structures for strict cache mode. Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsfs.c38
-rw-r--r--fs/cifs/cifsfs.h8
-rw-r--r--fs/cifs/file.c36
-rw-r--r--fs/cifs/inode.c8
4 files changed, 78 insertions, 12 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 99d777a03dd0..f6093e401c5a 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -733,6 +733,25 @@ const struct file_operations cifs_file_ops = {
733 .setlease = cifs_setlease, 733 .setlease = cifs_setlease,
734}; 734};
735 735
736const struct file_operations cifs_file_strict_ops = {
737 .read = do_sync_read,
738 .write = do_sync_write,
739 .aio_read = generic_file_aio_read,
740 .aio_write = cifs_file_aio_write,
741 .open = cifs_open,
742 .release = cifs_close,
743 .lock = cifs_lock,
744 .fsync = cifs_strict_fsync,
745 .flush = cifs_flush,
746 .mmap = cifs_file_mmap,
747 .splice_read = generic_file_splice_read,
748 .llseek = cifs_llseek,
749#ifdef CONFIG_CIFS_POSIX
750 .unlocked_ioctl = cifs_ioctl,
751#endif /* CONFIG_CIFS_POSIX */
752 .setlease = cifs_setlease,
753};
754
736const struct file_operations cifs_file_direct_ops = { 755const struct file_operations cifs_file_direct_ops = {
737 /* no aio, no readv - 756 /* no aio, no readv -
738 BB reevaluate whether they can be done with directio, no cache */ 757 BB reevaluate whether they can be done with directio, no cache */
@@ -751,6 +770,7 @@ const struct file_operations cifs_file_direct_ops = {
751 .llseek = cifs_llseek, 770 .llseek = cifs_llseek,
752 .setlease = cifs_setlease, 771 .setlease = cifs_setlease,
753}; 772};
773
754const struct file_operations cifs_file_nobrl_ops = { 774const struct file_operations cifs_file_nobrl_ops = {
755 .read = do_sync_read, 775 .read = do_sync_read,
756 .write = do_sync_write, 776 .write = do_sync_write,
@@ -769,6 +789,24 @@ const struct file_operations cifs_file_nobrl_ops = {
769 .setlease = cifs_setlease, 789 .setlease = cifs_setlease,
770}; 790};
771 791
792const struct file_operations cifs_file_strict_nobrl_ops = {
793 .read = do_sync_read,
794 .write = do_sync_write,
795 .aio_read = generic_file_aio_read,
796 .aio_write = cifs_file_aio_write,
797 .open = cifs_open,
798 .release = cifs_close,
799 .fsync = cifs_strict_fsync,
800 .flush = cifs_flush,
801 .mmap = cifs_file_mmap,
802 .splice_read = generic_file_splice_read,
803 .llseek = cifs_llseek,
804#ifdef CONFIG_CIFS_POSIX
805 .unlocked_ioctl = cifs_ioctl,
806#endif /* CONFIG_CIFS_POSIX */
807 .setlease = cifs_setlease,
808};
809
772const struct file_operations cifs_file_direct_nobrl_ops = { 810const struct file_operations cifs_file_direct_nobrl_ops = {
773 /* no mmap, no aio, no readv - 811 /* no mmap, no aio, no readv -
774 BB reevaluate whether they can be done with directio, no cache */ 812 BB reevaluate whether they can be done with directio, no cache */
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 4739a531cded..10c4303c282d 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -61,6 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
61 struct dentry *); 61 struct dentry *);
62extern int cifs_revalidate_file(struct file *filp); 62extern int cifs_revalidate_file(struct file *filp);
63extern int cifs_revalidate_dentry(struct dentry *); 63extern int cifs_revalidate_dentry(struct dentry *);
64extern void cifs_invalidate_mapping(struct inode *inode);
64extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); 65extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
65extern int cifs_setattr(struct dentry *, struct iattr *); 66extern int cifs_setattr(struct dentry *, struct iattr *);
66 67
@@ -72,8 +73,10 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations;
72/* Functions related to files and directories */ 73/* Functions related to files and directories */
73extern const struct file_operations cifs_file_ops; 74extern const struct file_operations cifs_file_ops;
74extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ 75extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
75extern const struct file_operations cifs_file_nobrl_ops; 76extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */
76extern const struct file_operations cifs_file_direct_nobrl_ops; /* no brlocks */ 77extern const struct file_operations cifs_file_nobrl_ops; /* no brlocks */
78extern const struct file_operations cifs_file_direct_nobrl_ops;
79extern const struct file_operations cifs_file_strict_nobrl_ops;
77extern int cifs_open(struct inode *inode, struct file *file); 80extern int cifs_open(struct inode *inode, struct file *file);
78extern int cifs_close(struct inode *inode, struct file *file); 81extern int cifs_close(struct inode *inode, struct file *file);
79extern int cifs_closedir(struct inode *inode, struct file *file); 82extern int cifs_closedir(struct inode *inode, struct file *file);
@@ -83,6 +86,7 @@ extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
83 size_t write_size, loff_t *poffset); 86 size_t write_size, loff_t *poffset);
84extern int cifs_lock(struct file *, int, struct file_lock *); 87extern int cifs_lock(struct file *, int, struct file_lock *);
85extern int cifs_fsync(struct file *, int); 88extern int cifs_fsync(struct file *, int);
89extern int cifs_strict_fsync(struct file *, int);
86extern int cifs_flush(struct file *, fl_owner_t id); 90extern int cifs_flush(struct file *, fl_owner_t id);
87extern int cifs_file_mmap(struct file * , struct vm_area_struct *); 91extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
88extern const struct file_operations cifs_dir_ops; 92extern const struct file_operations cifs_dir_ops;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 1b26c2717599..5790fab7349b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1528,27 +1528,47 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
1528 return rc; 1528 return rc;
1529} 1529}
1530 1530
1531int cifs_fsync(struct file *file, int datasync) 1531int cifs_strict_fsync(struct file *file, int datasync)
1532{ 1532{
1533 int xid; 1533 int xid;
1534 int rc = 0; 1534 int rc = 0;
1535 struct cifsTconInfo *tcon; 1535 struct cifsTconInfo *tcon;
1536 struct cifsFileInfo *smbfile = file->private_data; 1536 struct cifsFileInfo *smbfile = file->private_data;
1537 struct inode *inode = file->f_path.dentry->d_inode; 1537 struct inode *inode = file->f_path.dentry->d_inode;
1538 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1538 1539
1539 xid = GetXid(); 1540 xid = GetXid();
1540 1541
1541 cFYI(1, "Sync file - name: %s datasync: 0x%x", 1542 cFYI(1, "Sync file - name: %s datasync: 0x%x",
1542 file->f_path.dentry->d_name.name, datasync); 1543 file->f_path.dentry->d_name.name, datasync);
1543 1544
1544 rc = filemap_write_and_wait(inode->i_mapping); 1545 if (!CIFS_I(inode)->clientCanCacheRead)
1545 if (rc == 0) { 1546 cifs_invalidate_mapping(inode);
1546 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1547 1547
1548 tcon = tlink_tcon(smbfile->tlink); 1548 tcon = tlink_tcon(smbfile->tlink);
1549 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) 1549 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1550 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1550 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1551 } 1551
1552 FreeXid(xid);
1553 return rc;
1554}
1555
1556int cifs_fsync(struct file *file, int datasync)
1557{
1558 int xid;
1559 int rc = 0;
1560 struct cifsTconInfo *tcon;
1561 struct cifsFileInfo *smbfile = file->private_data;
1562 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1563
1564 xid = GetXid();
1565
1566 cFYI(1, "Sync file - name: %s datasync: 0x%x",
1567 file->f_path.dentry->d_name.name, datasync);
1568
1569 tcon = tlink_tcon(smbfile->tlink);
1570 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1571 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1552 1572
1553 FreeXid(xid); 1573 FreeXid(xid);
1554 return rc; 1574 return rc;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 6c9ee8014ff0..8852470b4fbb 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -44,13 +44,17 @@ static void cifs_set_ops(struct inode *inode)
44 inode->i_fop = &cifs_file_direct_nobrl_ops; 44 inode->i_fop = &cifs_file_direct_nobrl_ops;
45 else 45 else
46 inode->i_fop = &cifs_file_direct_ops; 46 inode->i_fop = &cifs_file_direct_ops;
47 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
48 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
49 inode->i_fop = &cifs_file_strict_nobrl_ops;
50 else
51 inode->i_fop = &cifs_file_strict_ops;
47 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 52 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
48 inode->i_fop = &cifs_file_nobrl_ops; 53 inode->i_fop = &cifs_file_nobrl_ops;
49 else { /* not direct, send byte range locks */ 54 else { /* not direct, send byte range locks */
50 inode->i_fop = &cifs_file_ops; 55 inode->i_fop = &cifs_file_ops;
51 } 56 }
52 57
53
54 /* check if server can support readpages */ 58 /* check if server can support readpages */
55 if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf < 59 if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
56 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 60 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
@@ -1679,7 +1683,7 @@ cifs_inode_needs_reval(struct inode *inode)
1679/* 1683/*
1680 * Zap the cache. Called when invalid_mapping flag is set. 1684 * Zap the cache. Called when invalid_mapping flag is set.
1681 */ 1685 */
1682static void 1686void
1683cifs_invalidate_mapping(struct inode *inode) 1687cifs_invalidate_mapping(struct inode *inode)
1684{ 1688{
1685 int rc; 1689 int rc;