Commit 8be7e6ba authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French

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: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarPavel Shilovsky <piastryyy@gmail.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 4f8ba8a0
...@@ -733,6 +733,25 @@ const struct file_operations cifs_file_ops = { ...@@ -733,6 +733,25 @@ const struct file_operations cifs_file_ops = {
.setlease = cifs_setlease, .setlease = cifs_setlease,
}; };
const struct file_operations cifs_file_strict_ops = {
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write,
.open = cifs_open,
.release = cifs_close,
.lock = cifs_lock,
.fsync = cifs_strict_fsync,
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.splice_read = generic_file_splice_read,
.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
.unlocked_ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
.setlease = cifs_setlease,
};
const struct file_operations cifs_file_direct_ops = { const struct file_operations cifs_file_direct_ops = {
/* no aio, no readv - /* no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */ BB reevaluate whether they can be done with directio, no cache */
...@@ -751,6 +770,7 @@ const struct file_operations cifs_file_direct_ops = { ...@@ -751,6 +770,7 @@ const struct file_operations cifs_file_direct_ops = {
.llseek = cifs_llseek, .llseek = cifs_llseek,
.setlease = cifs_setlease, .setlease = cifs_setlease,
}; };
const struct file_operations cifs_file_nobrl_ops = { const struct file_operations cifs_file_nobrl_ops = {
.read = do_sync_read, .read = do_sync_read,
.write = do_sync_write, .write = do_sync_write,
...@@ -769,6 +789,24 @@ const struct file_operations cifs_file_nobrl_ops = { ...@@ -769,6 +789,24 @@ const struct file_operations cifs_file_nobrl_ops = {
.setlease = cifs_setlease, .setlease = cifs_setlease,
}; };
const struct file_operations cifs_file_strict_nobrl_ops = {
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write,
.open = cifs_open,
.release = cifs_close,
.fsync = cifs_strict_fsync,
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.splice_read = generic_file_splice_read,
.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
.unlocked_ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
.setlease = cifs_setlease,
};
const struct file_operations cifs_file_direct_nobrl_ops = { const struct file_operations cifs_file_direct_nobrl_ops = {
/* no mmap, no aio, no readv - /* no mmap, no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */ BB reevaluate whether they can be done with directio, no cache */
......
...@@ -61,6 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *, ...@@ -61,6 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
struct dentry *); struct dentry *);
extern int cifs_revalidate_file(struct file *filp); extern int cifs_revalidate_file(struct file *filp);
extern int cifs_revalidate_dentry(struct dentry *); extern int cifs_revalidate_dentry(struct dentry *);
extern void cifs_invalidate_mapping(struct inode *inode);
extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int cifs_setattr(struct dentry *, struct iattr *); extern int cifs_setattr(struct dentry *, struct iattr *);
...@@ -72,8 +73,10 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations; ...@@ -72,8 +73,10 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations;
/* Functions related to files and directories */ /* Functions related to files and directories */
extern const struct file_operations cifs_file_ops; extern const struct file_operations cifs_file_ops;
extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
extern const struct file_operations cifs_file_nobrl_ops; extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */
extern const struct file_operations cifs_file_direct_nobrl_ops; /* no brlocks */ extern const struct file_operations cifs_file_nobrl_ops; /* no brlocks */
extern const struct file_operations cifs_file_direct_nobrl_ops;
extern const struct file_operations cifs_file_strict_nobrl_ops;
extern int cifs_open(struct inode *inode, struct file *file); extern int cifs_open(struct inode *inode, struct file *file);
extern int cifs_close(struct inode *inode, struct file *file); extern int cifs_close(struct inode *inode, struct file *file);
extern int cifs_closedir(struct inode *inode, struct file *file); 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,6 +86,7 @@ extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
size_t write_size, loff_t *poffset); size_t write_size, loff_t *poffset);
extern int cifs_lock(struct file *, int, struct file_lock *); extern int cifs_lock(struct file *, int, struct file_lock *);
extern int cifs_fsync(struct file *, int); extern int cifs_fsync(struct file *, int);
extern int cifs_strict_fsync(struct file *, int);
extern int cifs_flush(struct file *, fl_owner_t id); extern int cifs_flush(struct file *, fl_owner_t id);
extern int cifs_file_mmap(struct file * , struct vm_area_struct *); extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
extern const struct file_operations cifs_dir_ops; extern const struct file_operations cifs_dir_ops;
......
...@@ -1528,27 +1528,47 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, ...@@ -1528,27 +1528,47 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
return rc; return rc;
} }
int cifs_fsync(struct file *file, int datasync) int cifs_strict_fsync(struct file *file, int datasync)
{ {
int xid; int xid;
int rc = 0; int rc = 0;
struct cifsTconInfo *tcon; struct cifsTconInfo *tcon;
struct cifsFileInfo *smbfile = file->private_data; struct cifsFileInfo *smbfile = file->private_data;
struct inode *inode = file->f_path.dentry->d_inode; struct inode *inode = file->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
xid = GetXid(); xid = GetXid();
cFYI(1, "Sync file - name: %s datasync: 0x%x", cFYI(1, "Sync file - name: %s datasync: 0x%x",
file->f_path.dentry->d_name.name, datasync); file->f_path.dentry->d_name.name, datasync);
rc = filemap_write_and_wait(inode->i_mapping); if (!CIFS_I(inode)->clientCanCacheRead)
if (rc == 0) { cifs_invalidate_mapping(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
tcon = tlink_tcon(smbfile->tlink); tcon = tlink_tcon(smbfile->tlink);
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
}
FreeXid(xid);
return rc;
}
int cifs_fsync(struct file *file, int datasync)
{
int xid;
int rc = 0;
struct cifsTconInfo *tcon;
struct cifsFileInfo *smbfile = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
xid = GetXid();
cFYI(1, "Sync file - name: %s datasync: 0x%x",
file->f_path.dentry->d_name.name, datasync);
tcon = tlink_tcon(smbfile->tlink);
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
......
...@@ -44,13 +44,17 @@ static void cifs_set_ops(struct inode *inode) ...@@ -44,13 +44,17 @@ static void cifs_set_ops(struct inode *inode)
inode->i_fop = &cifs_file_direct_nobrl_ops; inode->i_fop = &cifs_file_direct_nobrl_ops;
else else
inode->i_fop = &cifs_file_direct_ops; inode->i_fop = &cifs_file_direct_ops;
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop = &cifs_file_strict_nobrl_ops;
else
inode->i_fop = &cifs_file_strict_ops;
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop = &cifs_file_nobrl_ops; inode->i_fop = &cifs_file_nobrl_ops;
else { /* not direct, send byte range locks */ else { /* not direct, send byte range locks */
inode->i_fop = &cifs_file_ops; inode->i_fop = &cifs_file_ops;
} }
/* check if server can support readpages */ /* check if server can support readpages */
if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf < if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
...@@ -1679,7 +1683,7 @@ cifs_inode_needs_reval(struct inode *inode) ...@@ -1679,7 +1683,7 @@ cifs_inode_needs_reval(struct inode *inode)
/* /*
* Zap the cache. Called when invalid_mapping flag is set. * Zap the cache. Called when invalid_mapping flag is set.
*/ */
static void void
cifs_invalidate_mapping(struct inode *inode) cifs_invalidate_mapping(struct inode *inode)
{ {
int rc; int rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment