diff options
| -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) |
