aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-09-22 01:53:59 -0400
committerSteve French <smfrench@gmail.com>2011-10-13 20:52:47 -0400
commitd59dad2be038132259ac99a2837d65a87fd90588 (patch)
treeba31d82b208981c6779a071217ff762cd3a1777e /fs/cifs
parentfe11e4ccb8479d92cd2a101d380d332544b84aaa (diff)
CIFS: Move byte range lock list from fd to inode
that let us do local lock checks before requesting to the server. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c3
-rw-r--r--fs/cifs/cifsglob.h7
-rw-r--r--fs/cifs/file.c30
3 files changed, 23 insertions, 17 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 5c2972106816..b0a2e1647390 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -945,7 +945,8 @@ cifs_init_once(void *inode)
945 struct cifsInodeInfo *cifsi = inode; 945 struct cifsInodeInfo *cifsi = inode;
946 946
947 inode_init_once(&cifsi->vfs_inode); 947 inode_init_once(&cifsi->vfs_inode);
948 INIT_LIST_HEAD(&cifsi->lockList); 948 INIT_LIST_HEAD(&cifsi->llist);
949 mutex_init(&cifsi->lock_mutex);
949} 950}
950 951
951static int 952static int
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 1f265ffe7e63..55ebf39fb3fd 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -494,6 +494,7 @@ struct cifsLockInfo {
494 __u64 length; 494 __u64 length;
495 __u32 pid; 495 __u32 pid;
496 __u8 type; 496 __u8 type;
497 __u16 netfid;
497}; 498};
498 499
499/* 500/*
@@ -526,8 +527,6 @@ struct cifsFileInfo {
526 struct dentry *dentry; 527 struct dentry *dentry;
527 unsigned int f_flags; 528 unsigned int f_flags;
528 struct tcon_link *tlink; 529 struct tcon_link *tlink;
529 struct mutex lock_mutex;
530 struct list_head llist; /* list of byte range locks we have. */
531 bool invalidHandle:1; /* file closed via session abend */ 530 bool invalidHandle:1; /* file closed via session abend */
532 bool oplock_break_cancelled:1; 531 bool oplock_break_cancelled:1;
533 int count; /* refcount protected by cifs_file_list_lock */ 532 int count; /* refcount protected by cifs_file_list_lock */
@@ -560,7 +559,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
560 */ 559 */
561 560
562struct cifsInodeInfo { 561struct cifsInodeInfo {
563 struct list_head lockList; 562 struct list_head llist; /* brlocks for this inode */
563 bool can_cache_brlcks;
564 struct mutex lock_mutex; /* protect two fields above */
564 /* BB add in lists for dirty pages i.e. write caching info for oplock */ 565 /* BB add in lists for dirty pages i.e. write caching info for oplock */
565 struct list_head openFileList; 566 struct list_head openFileList;
566 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ 567 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ab85699c5653..7f84ece116d0 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -262,8 +262,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
262 pCifsFile->invalidHandle = false; 262 pCifsFile->invalidHandle = false;
263 pCifsFile->tlink = cifs_get_tlink(tlink); 263 pCifsFile->tlink = cifs_get_tlink(tlink);
264 mutex_init(&pCifsFile->fh_mutex); 264 mutex_init(&pCifsFile->fh_mutex);
265 mutex_init(&pCifsFile->lock_mutex);
266 INIT_LIST_HEAD(&pCifsFile->llist);
267 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); 265 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
268 266
269 spin_lock(&cifs_file_list_lock); 267 spin_lock(&cifs_file_list_lock);
@@ -331,12 +329,14 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
331 /* Delete any outstanding lock records. We'll lose them when the file 329 /* Delete any outstanding lock records. We'll lose them when the file
332 * is closed anyway. 330 * is closed anyway.
333 */ 331 */
334 mutex_lock(&cifs_file->lock_mutex); 332 mutex_lock(&cifsi->lock_mutex);
335 list_for_each_entry_safe(li, tmp, &cifs_file->llist, llist) { 333 list_for_each_entry_safe(li, tmp, &cifsi->llist, llist) {
334 if (li->netfid != cifs_file->netfid)
335 continue;
336 list_del(&li->llist); 336 list_del(&li->llist);
337 kfree(li); 337 kfree(li);
338 } 338 }
339 mutex_unlock(&cifs_file->lock_mutex); 339 mutex_unlock(&cifsi->lock_mutex);
340 340
341 cifs_put_tlink(cifs_file->tlink); 341 cifs_put_tlink(cifs_file->tlink);
342 dput(cifs_file->dentry); 342 dput(cifs_file->dentry);
@@ -639,20 +639,21 @@ int cifs_closedir(struct inode *inode, struct file *file)
639 return rc; 639 return rc;
640} 640}
641 641
642static int store_file_lock(struct cifsFileInfo *cfile, __u64 len, 642static int store_file_lock(struct cifsInodeInfo *cinode, __u64 len,
643 __u64 offset, __u8 type, __u16 netfid) 643 __u64 offset, __u8 type, __u16 netfid)
644{ 644{
645 struct cifsLockInfo *li = 645 struct cifsLockInfo *li =
646 kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); 646 kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
647 if (li == NULL) 647 if (li == NULL)
648 return -ENOMEM; 648 return -ENOMEM;
649 li->netfid = netfid;
649 li->offset = offset; 650 li->offset = offset;
650 li->length = len; 651 li->length = len;
651 li->type = type; 652 li->type = type;
652 li->pid = current->tgid; 653 li->pid = current->tgid;
653 mutex_lock(&cfile->lock_mutex); 654 mutex_lock(&cinode->lock_mutex);
654 list_add_tail(&li->llist, &cfile->llist); 655 list_add_tail(&li->llist, &cinode->llist);
655 mutex_unlock(&cfile->lock_mutex); 656 mutex_unlock(&cinode->lock_mutex);
656 return 0; 657 return 0;
657} 658}
658 659
@@ -769,6 +770,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
769 __u64 length = 1 + flock->fl_end - flock->fl_start; 770 __u64 length = 1 + flock->fl_end - flock->fl_start;
770 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 771 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
771 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 772 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
773 struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode);
772 __u16 netfid = cfile->netfid; 774 __u16 netfid = cfile->netfid;
773 775
774 if (posix_lck) { 776 if (posix_lck) {
@@ -791,7 +793,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
791 flock->fl_start, 0, lock, type, wait_flag, 0); 793 flock->fl_start, 0, lock, type, wait_flag, 0);
792 if (rc == 0) { 794 if (rc == 0) {
793 /* For Windows locks we must store them. */ 795 /* For Windows locks we must store them. */
794 rc = store_file_lock(cfile, length, flock->fl_start, 796 rc = store_file_lock(cinode, length, flock->fl_start,
795 type, netfid); 797 type, netfid);
796 } 798 }
797 } else if (unlock) { 799 } else if (unlock) {
@@ -802,14 +804,16 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
802 int stored_rc = 0; 804 int stored_rc = 0;
803 struct cifsLockInfo *li, *tmp; 805 struct cifsLockInfo *li, *tmp;
804 806
805 mutex_lock(&cfile->lock_mutex); 807 mutex_lock(&cinode->lock_mutex);
806 list_for_each_entry_safe(li, tmp, &cfile->llist, llist) { 808 list_for_each_entry_safe(li, tmp, &cinode->llist, llist) {
807 if (flock->fl_start > li->offset || 809 if (flock->fl_start > li->offset ||
808 (flock->fl_start + length) < 810 (flock->fl_start + length) <
809 (li->offset + li->length)) 811 (li->offset + li->length))
810 continue; 812 continue;
811 if (current->tgid != li->pid) 813 if (current->tgid != li->pid)
812 continue; 814 continue;
815 if (cfile->netfid != li->netfid)
816 continue;
813 817
814 stored_rc = CIFSSMBLock(xid, tcon, netfid, 818 stored_rc = CIFSSMBLock(xid, tcon, netfid,
815 current->tgid, li->length, 819 current->tgid, li->length,
@@ -822,7 +826,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
822 kfree(li); 826 kfree(li);
823 } 827 }
824 } 828 }
825 mutex_unlock(&cfile->lock_mutex); 829 mutex_unlock(&cinode->lock_mutex);
826 } 830 }
827out: 831out:
828 if (flock->fl_flags & FL_POSIX) 832 if (flock->fl_flags & FL_POSIX)