diff options
| -rw-r--r-- | fs/cifs/cifsfs.c | 38 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 8 | ||||
| -rw-r--r-- | fs/cifs/file.c | 36 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 8 |
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 | ||
| 736 | const 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 | |||
| 736 | const struct file_operations cifs_file_direct_ops = { | 755 | const 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 | |||
| 754 | const struct file_operations cifs_file_nobrl_ops = { | 774 | const 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 | ||
| 792 | const 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 | |||
| 772 | const struct file_operations cifs_file_direct_nobrl_ops = { | 810 | const 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 *); |
| 62 | extern int cifs_revalidate_file(struct file *filp); | 62 | extern int cifs_revalidate_file(struct file *filp); |
| 63 | extern int cifs_revalidate_dentry(struct dentry *); | 63 | extern int cifs_revalidate_dentry(struct dentry *); |
| 64 | extern void cifs_invalidate_mapping(struct inode *inode); | ||
| 64 | extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 65 | extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
| 65 | extern int cifs_setattr(struct dentry *, struct iattr *); | 66 | extern 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 */ |
| 73 | extern const struct file_operations cifs_file_ops; | 74 | extern const struct file_operations cifs_file_ops; |
| 74 | extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ | 75 | extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ |
| 75 | extern const struct file_operations cifs_file_nobrl_ops; | 76 | extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */ |
| 76 | extern const struct file_operations cifs_file_direct_nobrl_ops; /* no brlocks */ | 77 | extern const struct file_operations cifs_file_nobrl_ops; /* no brlocks */ |
| 78 | extern const struct file_operations cifs_file_direct_nobrl_ops; | ||
| 79 | extern const struct file_operations cifs_file_strict_nobrl_ops; | ||
| 77 | extern int cifs_open(struct inode *inode, struct file *file); | 80 | extern int cifs_open(struct inode *inode, struct file *file); |
| 78 | extern int cifs_close(struct inode *inode, struct file *file); | 81 | extern int cifs_close(struct inode *inode, struct file *file); |
| 79 | extern int cifs_closedir(struct inode *inode, struct file *file); | 82 | extern 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); |
| 84 | extern int cifs_lock(struct file *, int, struct file_lock *); | 87 | extern int cifs_lock(struct file *, int, struct file_lock *); |
| 85 | extern int cifs_fsync(struct file *, int); | 88 | extern int cifs_fsync(struct file *, int); |
| 89 | extern int cifs_strict_fsync(struct file *, int); | ||
| 86 | extern int cifs_flush(struct file *, fl_owner_t id); | 90 | extern int cifs_flush(struct file *, fl_owner_t id); |
| 87 | extern int cifs_file_mmap(struct file * , struct vm_area_struct *); | 91 | extern int cifs_file_mmap(struct file * , struct vm_area_struct *); |
| 88 | extern const struct file_operations cifs_dir_ops; | 92 | extern 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 | ||
| 1531 | int cifs_fsync(struct file *file, int datasync) | 1531 | int 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 | |||
| 1556 | int 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 | /* |
