diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:43:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:43:36 -0400 |
commit | db563fc2e80534f98c7f9121a6f7dfe41f177a79 (patch) | |
tree | c97acbb983530b070e28c70825e0eedbbdb97ab2 /fs/cifs/cifsfs.c | |
parent | eb81071584bed0b04adcaf57e525638d0f92e1e1 (diff) | |
parent | b1c8d2b421376bc941823ee93e36cb491609b02c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
cifs: handle the TCP_Server_Info->tsk field more carefully
cifs: fix unlinking of rename target when server doesn't support open file renames
[CIFS] improve setlease handling
[CIFS] fix saving of resume key before CIFSFindNext
cifs: make cifs_rename handle -EACCES errors
[CIFS] fix build error
[CIFS] undo changes in cifs_rename_pending_delete if it errors out
cifs: track DeletePending flag in cifsInodeInfo
cifs: don't use CREATE_DELETE_ON_CLOSE in cifs_rename_pending_delete
[CIFS] eliminate usage of kthread_stop for cifsd
[CIFS] Add nodfs mount option
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 84cc011a16e4..ac5915d61dca 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -312,6 +312,7 @@ cifs_alloc_inode(struct super_block *sb) | |||
312 | file data or metadata */ | 312 | file data or metadata */ |
313 | cifs_inode->clientCanCacheRead = false; | 313 | cifs_inode->clientCanCacheRead = false; |
314 | cifs_inode->clientCanCacheAll = false; | 314 | cifs_inode->clientCanCacheAll = false; |
315 | cifs_inode->delete_pending = false; | ||
315 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ | 316 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ |
316 | 317 | ||
317 | /* Can not set i_flags here - they get immediately overwritten | 318 | /* Can not set i_flags here - they get immediately overwritten |
@@ -620,6 +621,37 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) | |||
620 | return generic_file_llseek_unlocked(file, offset, origin); | 621 | return generic_file_llseek_unlocked(file, offset, origin); |
621 | } | 622 | } |
622 | 623 | ||
624 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
625 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | ||
626 | { | ||
627 | /* note that this is called by vfs setlease with the BKL held | ||
628 | although I doubt that BKL is needed here in cifs */ | ||
629 | struct inode *inode = file->f_path.dentry->d_inode; | ||
630 | |||
631 | if (!(S_ISREG(inode->i_mode))) | ||
632 | return -EINVAL; | ||
633 | |||
634 | /* check if file is oplocked */ | ||
635 | if (((arg == F_RDLCK) && | ||
636 | (CIFS_I(inode)->clientCanCacheRead)) || | ||
637 | ((arg == F_WRLCK) && | ||
638 | (CIFS_I(inode)->clientCanCacheAll))) | ||
639 | return generic_setlease(file, arg, lease); | ||
640 | else if (CIFS_SB(inode->i_sb)->tcon->local_lease && | ||
641 | !CIFS_I(inode)->clientCanCacheRead) | ||
642 | /* If the server claims to support oplock on this | ||
643 | file, then we still need to check oplock even | ||
644 | if the local_lease mount option is set, but there | ||
645 | are servers which do not support oplock for which | ||
646 | this mount option may be useful if the user | ||
647 | knows that the file won't be changed on the server | ||
648 | by anyone else */ | ||
649 | return generic_setlease(file, arg, lease); | ||
650 | else | ||
651 | return -EAGAIN; | ||
652 | } | ||
653 | #endif | ||
654 | |||
623 | struct file_system_type cifs_fs_type = { | 655 | struct file_system_type cifs_fs_type = { |
624 | .owner = THIS_MODULE, | 656 | .owner = THIS_MODULE, |
625 | .name = "cifs", | 657 | .name = "cifs", |
@@ -698,6 +730,7 @@ const struct file_operations cifs_file_ops = { | |||
698 | 730 | ||
699 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 731 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
700 | .dir_notify = cifs_dir_notify, | 732 | .dir_notify = cifs_dir_notify, |
733 | .setlease = cifs_setlease, | ||
701 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 734 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
702 | }; | 735 | }; |
703 | 736 | ||
@@ -718,6 +751,7 @@ const struct file_operations cifs_file_direct_ops = { | |||
718 | .llseek = cifs_llseek, | 751 | .llseek = cifs_llseek, |
719 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 752 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
720 | .dir_notify = cifs_dir_notify, | 753 | .dir_notify = cifs_dir_notify, |
754 | .setlease = cifs_setlease, | ||
721 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 755 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
722 | }; | 756 | }; |
723 | const struct file_operations cifs_file_nobrl_ops = { | 757 | const struct file_operations cifs_file_nobrl_ops = { |
@@ -738,6 +772,7 @@ const struct file_operations cifs_file_nobrl_ops = { | |||
738 | 772 | ||
739 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 773 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
740 | .dir_notify = cifs_dir_notify, | 774 | .dir_notify = cifs_dir_notify, |
775 | .setlease = cifs_setlease, | ||
741 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 776 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
742 | }; | 777 | }; |
743 | 778 | ||
@@ -757,6 +792,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { | |||
757 | .llseek = cifs_llseek, | 792 | .llseek = cifs_llseek, |
758 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 793 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
759 | .dir_notify = cifs_dir_notify, | 794 | .dir_notify = cifs_dir_notify, |
795 | .setlease = cifs_setlease, | ||
760 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 796 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
761 | }; | 797 | }; |
762 | 798 | ||
@@ -949,6 +985,12 @@ static int cifs_oplock_thread(void *dummyarg) | |||
949 | the call */ | 985 | the call */ |
950 | /* mutex_lock(&inode->i_mutex);*/ | 986 | /* mutex_lock(&inode->i_mutex);*/ |
951 | if (S_ISREG(inode->i_mode)) { | 987 | if (S_ISREG(inode->i_mode)) { |
988 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
989 | if (CIFS_I(inode)->clientCanCacheAll == 0) | ||
990 | break_lease(inode, FMODE_READ); | ||
991 | else if (CIFS_I(inode)->clientCanCacheRead == 0) | ||
992 | break_lease(inode, FMODE_WRITE); | ||
993 | #endif | ||
952 | rc = filemap_fdatawrite(inode->i_mapping); | 994 | rc = filemap_fdatawrite(inode->i_mapping); |
953 | if (CIFS_I(inode)->clientCanCacheRead == 0) { | 995 | if (CIFS_I(inode)->clientCanCacheRead == 0) { |
954 | waitrc = filemap_fdatawait( | 996 | waitrc = filemap_fdatawait( |