diff options
Diffstat (limited to 'fs/cifs/file.c')
| -rw-r--r-- | fs/cifs/file.c | 41 |
1 files changed, 16 insertions, 25 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 96b7e9b7706d..8fe1f7a21b3e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -366,6 +366,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 366 | struct cifsLockInfo *li, *tmp; | 366 | struct cifsLockInfo *li, *tmp; |
| 367 | struct cifs_fid fid; | 367 | struct cifs_fid fid; |
| 368 | struct cifs_pending_open open; | 368 | struct cifs_pending_open open; |
| 369 | bool oplock_break_cancelled; | ||
| 369 | 370 | ||
| 370 | spin_lock(&cifs_file_list_lock); | 371 | spin_lock(&cifs_file_list_lock); |
| 371 | if (--cifs_file->count > 0) { | 372 | if (--cifs_file->count > 0) { |
| @@ -397,7 +398,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 397 | } | 398 | } |
| 398 | spin_unlock(&cifs_file_list_lock); | 399 | spin_unlock(&cifs_file_list_lock); |
| 399 | 400 | ||
| 400 | cancel_work_sync(&cifs_file->oplock_break); | 401 | oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break); |
| 401 | 402 | ||
| 402 | if (!tcon->need_reconnect && !cifs_file->invalidHandle) { | 403 | if (!tcon->need_reconnect && !cifs_file->invalidHandle) { |
| 403 | struct TCP_Server_Info *server = tcon->ses->server; | 404 | struct TCP_Server_Info *server = tcon->ses->server; |
| @@ -409,6 +410,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 409 | _free_xid(xid); | 410 | _free_xid(xid); |
| 410 | } | 411 | } |
| 411 | 412 | ||
| 413 | if (oplock_break_cancelled) | ||
| 414 | cifs_done_oplock_break(cifsi); | ||
| 415 | |||
| 412 | cifs_del_pending_open(&open); | 416 | cifs_del_pending_open(&open); |
| 413 | 417 | ||
| 414 | /* | 418 | /* |
| @@ -1109,11 +1113,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
| 1109 | return rc; | 1113 | return rc; |
| 1110 | } | 1114 | } |
| 1111 | 1115 | ||
| 1112 | /* copied from fs/locks.c with a name change */ | ||
| 1113 | #define cifs_for_each_lock(inode, lockp) \ | ||
| 1114 | for (lockp = &inode->i_flock; *lockp != NULL; \ | ||
| 1115 | lockp = &(*lockp)->fl_next) | ||
| 1116 | |||
| 1117 | struct lock_to_push { | 1116 | struct lock_to_push { |
| 1118 | struct list_head llist; | 1117 | struct list_head llist; |
| 1119 | __u64 offset; | 1118 | __u64 offset; |
| @@ -1128,8 +1127,9 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
| 1128 | { | 1127 | { |
| 1129 | struct inode *inode = cfile->dentry->d_inode; | 1128 | struct inode *inode = cfile->dentry->d_inode; |
| 1130 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1129 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
| 1131 | struct file_lock *flock, **before; | 1130 | struct file_lock *flock; |
| 1132 | unsigned int count = 0, i = 0; | 1131 | struct file_lock_context *flctx = inode->i_flctx; |
| 1132 | unsigned int i; | ||
| 1133 | int rc = 0, xid, type; | 1133 | int rc = 0, xid, type; |
| 1134 | struct list_head locks_to_send, *el; | 1134 | struct list_head locks_to_send, *el; |
| 1135 | struct lock_to_push *lck, *tmp; | 1135 | struct lock_to_push *lck, *tmp; |
| @@ -1137,21 +1137,17 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
| 1137 | 1137 | ||
| 1138 | xid = get_xid(); | 1138 | xid = get_xid(); |
| 1139 | 1139 | ||
| 1140 | spin_lock(&inode->i_lock); | 1140 | if (!flctx) |
| 1141 | cifs_for_each_lock(inode, before) { | 1141 | goto out; |
| 1142 | if ((*before)->fl_flags & FL_POSIX) | ||
| 1143 | count++; | ||
| 1144 | } | ||
| 1145 | spin_unlock(&inode->i_lock); | ||
| 1146 | 1142 | ||
| 1147 | INIT_LIST_HEAD(&locks_to_send); | 1143 | INIT_LIST_HEAD(&locks_to_send); |
| 1148 | 1144 | ||
| 1149 | /* | 1145 | /* |
| 1150 | * Allocating count locks is enough because no FL_POSIX locks can be | 1146 | * Allocating flc_posix_cnt locks is enough because no FL_POSIX locks |
| 1151 | * added to the list while we are holding cinode->lock_sem that | 1147 | * can be added to the list while we are holding cinode->lock_sem that |
| 1152 | * protects locking operations of this inode. | 1148 | * protects locking operations of this inode. |
| 1153 | */ | 1149 | */ |
| 1154 | for (; i < count; i++) { | 1150 | for (i = 0; i < flctx->flc_posix_cnt; i++) { |
| 1155 | lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); | 1151 | lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); |
| 1156 | if (!lck) { | 1152 | if (!lck) { |
| 1157 | rc = -ENOMEM; | 1153 | rc = -ENOMEM; |
| @@ -1161,11 +1157,8 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
| 1161 | } | 1157 | } |
| 1162 | 1158 | ||
| 1163 | el = locks_to_send.next; | 1159 | el = locks_to_send.next; |
| 1164 | spin_lock(&inode->i_lock); | 1160 | spin_lock(&flctx->flc_lock); |
| 1165 | cifs_for_each_lock(inode, before) { | 1161 | list_for_each_entry(flock, &flctx->flc_posix, fl_list) { |
| 1166 | flock = *before; | ||
| 1167 | if ((flock->fl_flags & FL_POSIX) == 0) | ||
| 1168 | continue; | ||
| 1169 | if (el == &locks_to_send) { | 1162 | if (el == &locks_to_send) { |
| 1170 | /* | 1163 | /* |
| 1171 | * The list ended. We don't have enough allocated | 1164 | * The list ended. We don't have enough allocated |
| @@ -1185,9 +1178,8 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
| 1185 | lck->length = length; | 1178 | lck->length = length; |
| 1186 | lck->type = type; | 1179 | lck->type = type; |
| 1187 | lck->offset = flock->fl_start; | 1180 | lck->offset = flock->fl_start; |
| 1188 | el = el->next; | ||
| 1189 | } | 1181 | } |
| 1190 | spin_unlock(&inode->i_lock); | 1182 | spin_unlock(&flctx->flc_lock); |
| 1191 | 1183 | ||
| 1192 | list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { | 1184 | list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { |
| 1193 | int stored_rc; | 1185 | int stored_rc; |
| @@ -3244,7 +3236,6 @@ static struct vm_operations_struct cifs_file_vm_ops = { | |||
| 3244 | .fault = filemap_fault, | 3236 | .fault = filemap_fault, |
| 3245 | .map_pages = filemap_map_pages, | 3237 | .map_pages = filemap_map_pages, |
| 3246 | .page_mkwrite = cifs_page_mkwrite, | 3238 | .page_mkwrite = cifs_page_mkwrite, |
| 3247 | .remap_pages = generic_file_remap_pages, | ||
| 3248 | }; | 3239 | }; |
| 3249 | 3240 | ||
| 3250 | int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) | 3241 | int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) |
