diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-09-22 01:53:59 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2011-10-13 20:52:47 -0400 |
commit | d59dad2be038132259ac99a2837d65a87fd90588 (patch) | |
tree | ba31d82b208981c6779a071217ff762cd3a1777e /fs/cifs | |
parent | fe11e4ccb8479d92cd2a101d380d332544b84aaa (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.c | 3 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 7 | ||||
-rw-r--r-- | fs/cifs/file.c | 30 |
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 | ||
951 | static int | 952 | static 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 | ||
562 | struct cifsInodeInfo { | 561 | struct 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 | ||
642 | static int store_file_lock(struct cifsFileInfo *cfile, __u64 len, | 642 | static 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 | } |
827 | out: | 831 | out: |
828 | if (flock->fl_flags & FL_POSIX) | 832 | if (flock->fl_flags & FL_POSIX) |