Skip to content

Commit

Permalink
[CIFS] Allow local filesize for file that is open for write to be upd…
Browse files Browse the repository at this point in the history
…ated

from server when mount forcedirectio.

Allowing update of file size with non forcedirectio mounts should be
allowed in the fiture but requires carefully writing out the
last page in the local file if it is a partial page in order to
avoid corruption and careful serialization

Thanks to Maximiliano Curia who suggested similar changes and provided
a testcase.

Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Steve French committed Jan 12, 2006
1 parent f3f6ec4 commit c32a0b6
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
17 changes: 15 additions & 2 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
return written;
}

static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
{
/* origin == SEEK_END => we must revalidate the cached file length */
if (origin == 2) {
int retval = cifs_revalidate(file->f_dentry);
if (retval < 0)
return (loff_t)retval;
}
return remote_llseek(file, offset, origin);
}

static struct file_system_type cifs_fs_type = {
.owner = THIS_MODULE,
.name = "cifs",
Expand Down Expand Up @@ -586,6 +597,7 @@ struct file_operations cifs_file_ops = {
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
Expand All @@ -609,7 +621,7 @@ struct file_operations cifs_file_direct_ops = {
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */

.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
Expand All @@ -627,6 +639,7 @@ struct file_operations cifs_file_nobrl_ops = {
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
Expand All @@ -649,7 +662,7 @@ struct file_operations cifs_file_direct_nobrl_ops = {
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */

.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
Expand Down
10 changes: 10 additions & 0 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1835,10 +1835,20 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
open_file = find_writable_file(cifsInode);

if(open_file) {
struct cifs_sb_info *cifs_sb;

/* there is not actually a write pending so let
this handle go free and allow it to
be closable if needed */
atomic_dec(&open_file->wrtPending);

cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
/* since no page cache to corrupt on directio
we can change size safely */
return 1;
}

return 0;
} else
return 1;
Expand Down

0 comments on commit c32a0b6

Please sign in to comment.