diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 413 |
1 files changed, 209 insertions, 204 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 9b11a8f56f3a..db11fdef0e92 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * vfs operations that deal with files | 4 | * vfs operations that deal with files |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2002,2007 | 6 | * Copyright (C) International Business Machines Corp., 2002,2010 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * Jeremy Allison (jra@samba.org) | 8 | * Jeremy Allison (jra@samba.org) |
9 | * | 9 | * |
@@ -40,6 +40,7 @@ | |||
40 | #include "cifs_unicode.h" | 40 | #include "cifs_unicode.h" |
41 | #include "cifs_debug.h" | 41 | #include "cifs_debug.h" |
42 | #include "cifs_fs_sb.h" | 42 | #include "cifs_fs_sb.h" |
43 | #include "fscache.h" | ||
43 | 44 | ||
44 | static inline int cifs_convert_flags(unsigned int flags) | 45 | static inline int cifs_convert_flags(unsigned int flags) |
45 | { | 46 | { |
@@ -108,8 +109,7 @@ static inline int cifs_get_disposition(unsigned int flags) | |||
108 | /* all arguments to this function must be checked for validity in caller */ | 109 | /* all arguments to this function must be checked for validity in caller */ |
109 | static inline int | 110 | static inline int |
110 | cifs_posix_open_inode_helper(struct inode *inode, struct file *file, | 111 | cifs_posix_open_inode_helper(struct inode *inode, struct file *file, |
111 | struct cifsInodeInfo *pCifsInode, | 112 | struct cifsInodeInfo *pCifsInode, __u32 oplock, |
112 | struct cifsFileInfo *pCifsFile, __u32 oplock, | ||
113 | u16 netfid) | 113 | u16 netfid) |
114 | { | 114 | { |
115 | 115 | ||
@@ -136,15 +136,15 @@ cifs_posix_open_inode_helper(struct inode *inode, struct file *file, | |||
136 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && | 136 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && |
137 | (file->f_path.dentry->d_inode->i_size == | 137 | (file->f_path.dentry->d_inode->i_size == |
138 | (loff_t)le64_to_cpu(buf->EndOfFile))) { | 138 | (loff_t)le64_to_cpu(buf->EndOfFile))) { |
139 | cFYI(1, ("inode unchanged on server")); | 139 | cFYI(1, "inode unchanged on server"); |
140 | } else { | 140 | } else { |
141 | if (file->f_path.dentry->d_inode->i_mapping) { | 141 | if (file->f_path.dentry->d_inode->i_mapping) { |
142 | rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); | 142 | rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); |
143 | if (rc != 0) | 143 | if (rc != 0) |
144 | CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; | 144 | CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; |
145 | } | 145 | } |
146 | cFYI(1, ("invalidating remote inode since open detected it " | 146 | cFYI(1, "invalidating remote inode since open detected it " |
147 | "changed")); | 147 | "changed"); |
148 | invalidate_remote_inode(file->f_path.dentry->d_inode); | 148 | invalidate_remote_inode(file->f_path.dentry->d_inode); |
149 | } */ | 149 | } */ |
150 | 150 | ||
@@ -152,8 +152,8 @@ psx_client_can_cache: | |||
152 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 152 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
153 | pCifsInode->clientCanCacheAll = true; | 153 | pCifsInode->clientCanCacheAll = true; |
154 | pCifsInode->clientCanCacheRead = true; | 154 | pCifsInode->clientCanCacheRead = true; |
155 | cFYI(1, ("Exclusive Oplock granted on inode %p", | 155 | cFYI(1, "Exclusive Oplock granted on inode %p", |
156 | file->f_path.dentry->d_inode)); | 156 | file->f_path.dentry->d_inode); |
157 | } else if ((oplock & 0xF) == OPLOCK_READ) | 157 | } else if ((oplock & 0xF) == OPLOCK_READ) |
158 | pCifsInode->clientCanCacheRead = true; | 158 | pCifsInode->clientCanCacheRead = true; |
159 | 159 | ||
@@ -163,44 +163,12 @@ psx_client_can_cache: | |||
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | static struct cifsFileInfo * | ||
167 | cifs_fill_filedata(struct file *file) | ||
168 | { | ||
169 | struct list_head *tmp; | ||
170 | struct cifsFileInfo *pCifsFile = NULL; | ||
171 | struct cifsInodeInfo *pCifsInode = NULL; | ||
172 | |||
173 | /* search inode for this file and fill in file->private_data */ | ||
174 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | ||
175 | read_lock(&GlobalSMBSeslock); | ||
176 | list_for_each(tmp, &pCifsInode->openFileList) { | ||
177 | pCifsFile = list_entry(tmp, struct cifsFileInfo, flist); | ||
178 | if ((pCifsFile->pfile == NULL) && | ||
179 | (pCifsFile->pid == current->tgid)) { | ||
180 | /* mode set in cifs_create */ | ||
181 | |||
182 | /* needed for writepage */ | ||
183 | pCifsFile->pfile = file; | ||
184 | file->private_data = pCifsFile; | ||
185 | break; | ||
186 | } | ||
187 | } | ||
188 | read_unlock(&GlobalSMBSeslock); | ||
189 | |||
190 | if (file->private_data != NULL) { | ||
191 | return pCifsFile; | ||
192 | } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) | ||
193 | cERROR(1, ("could not find file instance for " | ||
194 | "new file %p", file)); | ||
195 | return NULL; | ||
196 | } | ||
197 | |||
198 | /* all arguments to this function must be checked for validity in caller */ | 166 | /* all arguments to this function must be checked for validity in caller */ |
199 | static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | 167 | static inline int cifs_open_inode_helper(struct inode *inode, |
200 | struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, | ||
201 | struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, | 168 | struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, |
202 | char *full_path, int xid) | 169 | char *full_path, int xid) |
203 | { | 170 | { |
171 | struct cifsInodeInfo *pCifsInode = CIFS_I(inode); | ||
204 | struct timespec temp; | 172 | struct timespec temp; |
205 | int rc; | 173 | int rc; |
206 | 174 | ||
@@ -214,36 +182,35 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
214 | /* if not oplocked, invalidate inode pages if mtime or file | 182 | /* if not oplocked, invalidate inode pages if mtime or file |
215 | size changed */ | 183 | size changed */ |
216 | temp = cifs_NTtimeToUnix(buf->LastWriteTime); | 184 | temp = cifs_NTtimeToUnix(buf->LastWriteTime); |
217 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && | 185 | if (timespec_equal(&inode->i_mtime, &temp) && |
218 | (file->f_path.dentry->d_inode->i_size == | 186 | (inode->i_size == |
219 | (loff_t)le64_to_cpu(buf->EndOfFile))) { | 187 | (loff_t)le64_to_cpu(buf->EndOfFile))) { |
220 | cFYI(1, ("inode unchanged on server")); | 188 | cFYI(1, "inode unchanged on server"); |
221 | } else { | 189 | } else { |
222 | if (file->f_path.dentry->d_inode->i_mapping) { | 190 | if (inode->i_mapping) { |
223 | /* BB no need to lock inode until after invalidate | 191 | /* BB no need to lock inode until after invalidate |
224 | since namei code should already have it locked? */ | 192 | since namei code should already have it locked? */ |
225 | rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); | 193 | rc = filemap_write_and_wait(inode->i_mapping); |
226 | if (rc != 0) | 194 | if (rc != 0) |
227 | CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; | 195 | pCifsInode->write_behind_rc = rc; |
228 | } | 196 | } |
229 | cFYI(1, ("invalidating remote inode since open detected it " | 197 | cFYI(1, "invalidating remote inode since open detected it " |
230 | "changed")); | 198 | "changed"); |
231 | invalidate_remote_inode(file->f_path.dentry->d_inode); | 199 | invalidate_remote_inode(inode); |
232 | } | 200 | } |
233 | 201 | ||
234 | client_can_cache: | 202 | client_can_cache: |
235 | if (pTcon->unix_ext) | 203 | if (pTcon->unix_ext) |
236 | rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, | 204 | rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, |
237 | full_path, inode->i_sb, xid); | 205 | xid); |
238 | else | 206 | else |
239 | rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, | 207 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, |
240 | full_path, buf, inode->i_sb, xid, NULL); | 208 | xid, NULL); |
241 | 209 | ||
242 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 210 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
243 | pCifsInode->clientCanCacheAll = true; | 211 | pCifsInode->clientCanCacheAll = true; |
244 | pCifsInode->clientCanCacheRead = true; | 212 | pCifsInode->clientCanCacheRead = true; |
245 | cFYI(1, ("Exclusive Oplock granted on inode %p", | 213 | cFYI(1, "Exclusive Oplock granted on inode %p", inode); |
246 | file->f_path.dentry->d_inode)); | ||
247 | } else if ((*oplock & 0xF) == OPLOCK_READ) | 214 | } else if ((*oplock & 0xF) == OPLOCK_READ) |
248 | pCifsInode->clientCanCacheRead = true; | 215 | pCifsInode->clientCanCacheRead = true; |
249 | 216 | ||
@@ -257,7 +224,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
257 | __u32 oplock; | 224 | __u32 oplock; |
258 | struct cifs_sb_info *cifs_sb; | 225 | struct cifs_sb_info *cifs_sb; |
259 | struct cifsTconInfo *tcon; | 226 | struct cifsTconInfo *tcon; |
260 | struct cifsFileInfo *pCifsFile; | 227 | struct cifsFileInfo *pCifsFile = NULL; |
261 | struct cifsInodeInfo *pCifsInode; | 228 | struct cifsInodeInfo *pCifsInode; |
262 | char *full_path = NULL; | 229 | char *full_path = NULL; |
263 | int desiredAccess; | 230 | int desiredAccess; |
@@ -271,12 +238,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
271 | tcon = cifs_sb->tcon; | 238 | tcon = cifs_sb->tcon; |
272 | 239 | ||
273 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 240 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
274 | pCifsFile = cifs_fill_filedata(file); | ||
275 | if (pCifsFile) { | ||
276 | rc = 0; | ||
277 | FreeXid(xid); | ||
278 | return rc; | ||
279 | } | ||
280 | 241 | ||
281 | full_path = build_path_from_dentry(file->f_path.dentry); | 242 | full_path = build_path_from_dentry(file->f_path.dentry); |
282 | if (full_path == NULL) { | 243 | if (full_path == NULL) { |
@@ -285,8 +246,8 @@ int cifs_open(struct inode *inode, struct file *file) | |||
285 | return rc; | 246 | return rc; |
286 | } | 247 | } |
287 | 248 | ||
288 | cFYI(1, ("inode = 0x%p file flags are 0x%x for %s", | 249 | cFYI(1, "inode = 0x%p file flags are 0x%x for %s", |
289 | inode, file->f_flags, full_path)); | 250 | inode, file->f_flags, full_path); |
290 | 251 | ||
291 | if (oplockEnabled) | 252 | if (oplockEnabled) |
292 | oplock = REQ_OPLOCK; | 253 | oplock = REQ_OPLOCK; |
@@ -298,27 +259,42 @@ int cifs_open(struct inode *inode, struct file *file) | |||
298 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 259 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
299 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 260 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
300 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); | 261 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); |
262 | oflags |= SMB_O_CREAT; | ||
301 | /* can not refresh inode info since size could be stale */ | 263 | /* can not refresh inode info since size could be stale */ |
302 | rc = cifs_posix_open(full_path, &inode, file->f_path.mnt, | 264 | rc = cifs_posix_open(full_path, &inode, inode->i_sb, |
303 | cifs_sb->mnt_file_mode /* ignored */, | 265 | cifs_sb->mnt_file_mode /* ignored */, |
304 | oflags, &oplock, &netfid, xid); | 266 | oflags, &oplock, &netfid, xid); |
305 | if (rc == 0) { | 267 | if (rc == 0) { |
306 | cFYI(1, ("posix open succeeded")); | 268 | cFYI(1, "posix open succeeded"); |
307 | /* no need for special case handling of setting mode | 269 | /* no need for special case handling of setting mode |
308 | on read only files needed here */ | 270 | on read only files needed here */ |
309 | 271 | ||
310 | pCifsFile = cifs_fill_filedata(file); | 272 | rc = cifs_posix_open_inode_helper(inode, file, |
311 | cifs_posix_open_inode_helper(inode, file, pCifsInode, | 273 | pCifsInode, oplock, netfid); |
312 | pCifsFile, oplock, netfid); | 274 | if (rc != 0) { |
275 | CIFSSMBClose(xid, tcon, netfid); | ||
276 | goto out; | ||
277 | } | ||
278 | |||
279 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, | ||
280 | file->f_path.mnt, | ||
281 | oflags); | ||
282 | if (pCifsFile == NULL) { | ||
283 | CIFSSMBClose(xid, tcon, netfid); | ||
284 | rc = -ENOMEM; | ||
285 | } | ||
286 | |||
287 | cifs_fscache_set_inode_cookie(inode, file); | ||
288 | |||
313 | goto out; | 289 | goto out; |
314 | } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | 290 | } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
315 | if (tcon->ses->serverNOS) | 291 | if (tcon->ses->serverNOS) |
316 | cERROR(1, ("server %s of type %s returned" | 292 | cERROR(1, "server %s of type %s returned" |
317 | " unexpected error on SMB posix open" | 293 | " unexpected error on SMB posix open" |
318 | ", disabling posix open support." | 294 | ", disabling posix open support." |
319 | " Check if server update available.", | 295 | " Check if server update available.", |
320 | tcon->ses->serverName, | 296 | tcon->ses->serverName, |
321 | tcon->ses->serverNOS)); | 297 | tcon->ses->serverNOS); |
322 | tcon->broken_posix_open = true; | 298 | tcon->broken_posix_open = true; |
323 | } else if ((rc != -EIO) && (rc != -EREMOTE) && | 299 | } else if ((rc != -EIO) && (rc != -EREMOTE) && |
324 | (rc != -EOPNOTSUPP)) /* path not found or net err */ | 300 | (rc != -EOPNOTSUPP)) /* path not found or net err */ |
@@ -386,20 +362,22 @@ int cifs_open(struct inode *inode, struct file *file) | |||
386 | & CIFS_MOUNT_MAP_SPECIAL_CHR); | 362 | & CIFS_MOUNT_MAP_SPECIAL_CHR); |
387 | } | 363 | } |
388 | if (rc) { | 364 | if (rc) { |
389 | cFYI(1, ("cifs_open returned 0x%x", rc)); | 365 | cFYI(1, "cifs_open returned 0x%x", rc); |
390 | goto out; | 366 | goto out; |
391 | } | 367 | } |
392 | 368 | ||
369 | rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid); | ||
370 | if (rc != 0) | ||
371 | goto out; | ||
372 | |||
393 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, | 373 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, |
394 | file->f_flags); | 374 | file->f_flags); |
395 | file->private_data = pCifsFile; | 375 | if (pCifsFile == NULL) { |
396 | if (file->private_data == NULL) { | ||
397 | rc = -ENOMEM; | 376 | rc = -ENOMEM; |
398 | goto out; | 377 | goto out; |
399 | } | 378 | } |
400 | 379 | ||
401 | rc = cifs_open_inode_helper(inode, file, pCifsInode, pCifsFile, tcon, | 380 | cifs_fscache_set_inode_cookie(inode, file); |
402 | &oplock, buf, full_path, xid); | ||
403 | 381 | ||
404 | if (oplock & CIFS_CREATE_ACTION) { | 382 | if (oplock & CIFS_CREATE_ACTION) { |
405 | /* time to set mode which we can not set earlier due to | 383 | /* time to set mode which we can not set earlier due to |
@@ -455,7 +433,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush) | |||
455 | __u16 netfid; | 433 | __u16 netfid; |
456 | 434 | ||
457 | if (file->private_data) | 435 | if (file->private_data) |
458 | pCifsFile = (struct cifsFileInfo *)file->private_data; | 436 | pCifsFile = file->private_data; |
459 | else | 437 | else |
460 | return -EBADF; | 438 | return -EBADF; |
461 | 439 | ||
@@ -469,7 +447,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush) | |||
469 | } | 447 | } |
470 | 448 | ||
471 | if (file->f_path.dentry == NULL) { | 449 | if (file->f_path.dentry == NULL) { |
472 | cERROR(1, ("no valid name if dentry freed")); | 450 | cERROR(1, "no valid name if dentry freed"); |
473 | dump_stack(); | 451 | dump_stack(); |
474 | rc = -EBADF; | 452 | rc = -EBADF; |
475 | goto reopen_error_exit; | 453 | goto reopen_error_exit; |
@@ -477,7 +455,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush) | |||
477 | 455 | ||
478 | inode = file->f_path.dentry->d_inode; | 456 | inode = file->f_path.dentry->d_inode; |
479 | if (inode == NULL) { | 457 | if (inode == NULL) { |
480 | cERROR(1, ("inode not valid")); | 458 | cERROR(1, "inode not valid"); |
481 | dump_stack(); | 459 | dump_stack(); |
482 | rc = -EBADF; | 460 | rc = -EBADF; |
483 | goto reopen_error_exit; | 461 | goto reopen_error_exit; |
@@ -499,8 +477,8 @@ reopen_error_exit: | |||
499 | return rc; | 477 | return rc; |
500 | } | 478 | } |
501 | 479 | ||
502 | cFYI(1, ("inode = 0x%p file flags 0x%x for %s", | 480 | cFYI(1, "inode = 0x%p file flags 0x%x for %s", |
503 | inode, file->f_flags, full_path)); | 481 | inode, file->f_flags, full_path); |
504 | 482 | ||
505 | if (oplockEnabled) | 483 | if (oplockEnabled) |
506 | oplock = REQ_OPLOCK; | 484 | oplock = REQ_OPLOCK; |
@@ -512,11 +490,11 @@ reopen_error_exit: | |||
512 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 490 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
513 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); | 491 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); |
514 | /* can not refresh inode info since size could be stale */ | 492 | /* can not refresh inode info since size could be stale */ |
515 | rc = cifs_posix_open(full_path, NULL, file->f_path.mnt, | 493 | rc = cifs_posix_open(full_path, NULL, inode->i_sb, |
516 | cifs_sb->mnt_file_mode /* ignored */, | 494 | cifs_sb->mnt_file_mode /* ignored */, |
517 | oflags, &oplock, &netfid, xid); | 495 | oflags, &oplock, &netfid, xid); |
518 | if (rc == 0) { | 496 | if (rc == 0) { |
519 | cFYI(1, ("posix reopen succeeded")); | 497 | cFYI(1, "posix reopen succeeded"); |
520 | goto reopen_success; | 498 | goto reopen_success; |
521 | } | 499 | } |
522 | /* fallthrough to retry open the old way on errors, especially | 500 | /* fallthrough to retry open the old way on errors, especially |
@@ -537,8 +515,8 @@ reopen_error_exit: | |||
537 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 515 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
538 | if (rc) { | 516 | if (rc) { |
539 | mutex_unlock(&pCifsFile->fh_mutex); | 517 | mutex_unlock(&pCifsFile->fh_mutex); |
540 | cFYI(1, ("cifs_open returned 0x%x", rc)); | 518 | cFYI(1, "cifs_open returned 0x%x", rc); |
541 | cFYI(1, ("oplock: %d", oplock)); | 519 | cFYI(1, "oplock: %d", oplock); |
542 | } else { | 520 | } else { |
543 | reopen_success: | 521 | reopen_success: |
544 | pCifsFile->netfid = netfid; | 522 | pCifsFile->netfid = netfid; |
@@ -570,8 +548,8 @@ reopen_success: | |||
570 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 548 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
571 | pCifsInode->clientCanCacheAll = true; | 549 | pCifsInode->clientCanCacheAll = true; |
572 | pCifsInode->clientCanCacheRead = true; | 550 | pCifsInode->clientCanCacheRead = true; |
573 | cFYI(1, ("Exclusive Oplock granted on inode %p", | 551 | cFYI(1, "Exclusive Oplock granted on inode %p", |
574 | file->f_path.dentry->d_inode)); | 552 | file->f_path.dentry->d_inode); |
575 | } else if ((oplock & 0xF) == OPLOCK_READ) { | 553 | } else if ((oplock & 0xF) == OPLOCK_READ) { |
576 | pCifsInode->clientCanCacheRead = true; | 554 | pCifsInode->clientCanCacheRead = true; |
577 | pCifsInode->clientCanCacheAll = false; | 555 | pCifsInode->clientCanCacheAll = false; |
@@ -593,8 +571,7 @@ int cifs_close(struct inode *inode, struct file *file) | |||
593 | int xid, timeout; | 571 | int xid, timeout; |
594 | struct cifs_sb_info *cifs_sb; | 572 | struct cifs_sb_info *cifs_sb; |
595 | struct cifsTconInfo *pTcon; | 573 | struct cifsTconInfo *pTcon; |
596 | struct cifsFileInfo *pSMBFile = | 574 | struct cifsFileInfo *pSMBFile = file->private_data; |
597 | (struct cifsFileInfo *)file->private_data; | ||
598 | 575 | ||
599 | xid = GetXid(); | 576 | xid = GetXid(); |
600 | 577 | ||
@@ -619,8 +596,7 @@ int cifs_close(struct inode *inode, struct file *file) | |||
619 | the struct would be in each open file, | 596 | the struct would be in each open file, |
620 | but this should give enough time to | 597 | but this should give enough time to |
621 | clear the socket */ | 598 | clear the socket */ |
622 | cFYI(DBG2, | 599 | cFYI(DBG2, "close delay, write pending"); |
623 | ("close delay, write pending")); | ||
624 | msleep(timeout); | 600 | msleep(timeout); |
625 | timeout *= 4; | 601 | timeout *= 4; |
626 | } | 602 | } |
@@ -653,7 +629,7 @@ int cifs_close(struct inode *inode, struct file *file) | |||
653 | 629 | ||
654 | read_lock(&GlobalSMBSeslock); | 630 | read_lock(&GlobalSMBSeslock); |
655 | if (list_empty(&(CIFS_I(inode)->openFileList))) { | 631 | if (list_empty(&(CIFS_I(inode)->openFileList))) { |
656 | cFYI(1, ("closing last open instance for inode %p", inode)); | 632 | cFYI(1, "closing last open instance for inode %p", inode); |
657 | /* if the file is not open we do not know if we can cache info | 633 | /* if the file is not open we do not know if we can cache info |
658 | on this inode, much less write behind and read ahead */ | 634 | on this inode, much less write behind and read ahead */ |
659 | CIFS_I(inode)->clientCanCacheRead = false; | 635 | CIFS_I(inode)->clientCanCacheRead = false; |
@@ -670,11 +646,10 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
670 | { | 646 | { |
671 | int rc = 0; | 647 | int rc = 0; |
672 | int xid; | 648 | int xid; |
673 | struct cifsFileInfo *pCFileStruct = | 649 | struct cifsFileInfo *pCFileStruct = file->private_data; |
674 | (struct cifsFileInfo *)file->private_data; | ||
675 | char *ptmp; | 650 | char *ptmp; |
676 | 651 | ||
677 | cFYI(1, ("Closedir inode = 0x%p", inode)); | 652 | cFYI(1, "Closedir inode = 0x%p", inode); |
678 | 653 | ||
679 | xid = GetXid(); | 654 | xid = GetXid(); |
680 | 655 | ||
@@ -685,22 +660,22 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
685 | 660 | ||
686 | pTcon = cifs_sb->tcon; | 661 | pTcon = cifs_sb->tcon; |
687 | 662 | ||
688 | cFYI(1, ("Freeing private data in close dir")); | 663 | cFYI(1, "Freeing private data in close dir"); |
689 | write_lock(&GlobalSMBSeslock); | 664 | write_lock(&GlobalSMBSeslock); |
690 | if (!pCFileStruct->srch_inf.endOfSearch && | 665 | if (!pCFileStruct->srch_inf.endOfSearch && |
691 | !pCFileStruct->invalidHandle) { | 666 | !pCFileStruct->invalidHandle) { |
692 | pCFileStruct->invalidHandle = true; | 667 | pCFileStruct->invalidHandle = true; |
693 | write_unlock(&GlobalSMBSeslock); | 668 | write_unlock(&GlobalSMBSeslock); |
694 | rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); | 669 | rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); |
695 | cFYI(1, ("Closing uncompleted readdir with rc %d", | 670 | cFYI(1, "Closing uncompleted readdir with rc %d", |
696 | rc)); | 671 | rc); |
697 | /* not much we can do if it fails anyway, ignore rc */ | 672 | /* not much we can do if it fails anyway, ignore rc */ |
698 | rc = 0; | 673 | rc = 0; |
699 | } else | 674 | } else |
700 | write_unlock(&GlobalSMBSeslock); | 675 | write_unlock(&GlobalSMBSeslock); |
701 | ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; | 676 | ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; |
702 | if (ptmp) { | 677 | if (ptmp) { |
703 | cFYI(1, ("closedir free smb buf in srch struct")); | 678 | cFYI(1, "closedir free smb buf in srch struct"); |
704 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; | 679 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; |
705 | if (pCFileStruct->srch_inf.smallBuf) | 680 | if (pCFileStruct->srch_inf.smallBuf) |
706 | cifs_small_buf_release(ptmp); | 681 | cifs_small_buf_release(ptmp); |
@@ -748,49 +723,49 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
748 | rc = -EACCES; | 723 | rc = -EACCES; |
749 | xid = GetXid(); | 724 | xid = GetXid(); |
750 | 725 | ||
751 | cFYI(1, ("Lock parm: 0x%x flockflags: " | 726 | cFYI(1, "Lock parm: 0x%x flockflags: " |
752 | "0x%x flocktype: 0x%x start: %lld end: %lld", | 727 | "0x%x flocktype: 0x%x start: %lld end: %lld", |
753 | cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, | 728 | cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, |
754 | pfLock->fl_end)); | 729 | pfLock->fl_end); |
755 | 730 | ||
756 | if (pfLock->fl_flags & FL_POSIX) | 731 | if (pfLock->fl_flags & FL_POSIX) |
757 | cFYI(1, ("Posix")); | 732 | cFYI(1, "Posix"); |
758 | if (pfLock->fl_flags & FL_FLOCK) | 733 | if (pfLock->fl_flags & FL_FLOCK) |
759 | cFYI(1, ("Flock")); | 734 | cFYI(1, "Flock"); |
760 | if (pfLock->fl_flags & FL_SLEEP) { | 735 | if (pfLock->fl_flags & FL_SLEEP) { |
761 | cFYI(1, ("Blocking lock")); | 736 | cFYI(1, "Blocking lock"); |
762 | wait_flag = true; | 737 | wait_flag = true; |
763 | } | 738 | } |
764 | if (pfLock->fl_flags & FL_ACCESS) | 739 | if (pfLock->fl_flags & FL_ACCESS) |
765 | cFYI(1, ("Process suspended by mandatory locking - " | 740 | cFYI(1, "Process suspended by mandatory locking - " |
766 | "not implemented yet")); | 741 | "not implemented yet"); |
767 | if (pfLock->fl_flags & FL_LEASE) | 742 | if (pfLock->fl_flags & FL_LEASE) |
768 | cFYI(1, ("Lease on file - not implemented yet")); | 743 | cFYI(1, "Lease on file - not implemented yet"); |
769 | if (pfLock->fl_flags & | 744 | if (pfLock->fl_flags & |
770 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) | 745 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) |
771 | cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags)); | 746 | cFYI(1, "Unknown lock flags 0x%x", pfLock->fl_flags); |
772 | 747 | ||
773 | if (pfLock->fl_type == F_WRLCK) { | 748 | if (pfLock->fl_type == F_WRLCK) { |
774 | cFYI(1, ("F_WRLCK ")); | 749 | cFYI(1, "F_WRLCK "); |
775 | numLock = 1; | 750 | numLock = 1; |
776 | } else if (pfLock->fl_type == F_UNLCK) { | 751 | } else if (pfLock->fl_type == F_UNLCK) { |
777 | cFYI(1, ("F_UNLCK")); | 752 | cFYI(1, "F_UNLCK"); |
778 | numUnlock = 1; | 753 | numUnlock = 1; |
779 | /* Check if unlock includes more than | 754 | /* Check if unlock includes more than |
780 | one lock range */ | 755 | one lock range */ |
781 | } else if (pfLock->fl_type == F_RDLCK) { | 756 | } else if (pfLock->fl_type == F_RDLCK) { |
782 | cFYI(1, ("F_RDLCK")); | 757 | cFYI(1, "F_RDLCK"); |
783 | lockType |= LOCKING_ANDX_SHARED_LOCK; | 758 | lockType |= LOCKING_ANDX_SHARED_LOCK; |
784 | numLock = 1; | 759 | numLock = 1; |
785 | } else if (pfLock->fl_type == F_EXLCK) { | 760 | } else if (pfLock->fl_type == F_EXLCK) { |
786 | cFYI(1, ("F_EXLCK")); | 761 | cFYI(1, "F_EXLCK"); |
787 | numLock = 1; | 762 | numLock = 1; |
788 | } else if (pfLock->fl_type == F_SHLCK) { | 763 | } else if (pfLock->fl_type == F_SHLCK) { |
789 | cFYI(1, ("F_SHLCK")); | 764 | cFYI(1, "F_SHLCK"); |
790 | lockType |= LOCKING_ANDX_SHARED_LOCK; | 765 | lockType |= LOCKING_ANDX_SHARED_LOCK; |
791 | numLock = 1; | 766 | numLock = 1; |
792 | } else | 767 | } else |
793 | cFYI(1, ("Unknown type of lock")); | 768 | cFYI(1, "Unknown type of lock"); |
794 | 769 | ||
795 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 770 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
796 | tcon = cifs_sb->tcon; | 771 | tcon = cifs_sb->tcon; |
@@ -833,8 +808,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
833 | 0 /* wait flag */ ); | 808 | 0 /* wait flag */ ); |
834 | pfLock->fl_type = F_UNLCK; | 809 | pfLock->fl_type = F_UNLCK; |
835 | if (rc != 0) | 810 | if (rc != 0) |
836 | cERROR(1, ("Error unlocking previously locked " | 811 | cERROR(1, "Error unlocking previously locked " |
837 | "range %d during test of lock", rc)); | 812 | "range %d during test of lock", rc); |
838 | rc = 0; | 813 | rc = 0; |
839 | 814 | ||
840 | } else { | 815 | } else { |
@@ -856,9 +831,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
856 | 0 /* wait flag */); | 831 | 0 /* wait flag */); |
857 | pfLock->fl_type = F_RDLCK; | 832 | pfLock->fl_type = F_RDLCK; |
858 | if (rc != 0) | 833 | if (rc != 0) |
859 | cERROR(1, ("Error unlocking " | 834 | cERROR(1, "Error unlocking " |
860 | "previously locked range %d " | 835 | "previously locked range %d " |
861 | "during test of lock", rc)); | 836 | "during test of lock", rc); |
862 | rc = 0; | 837 | rc = 0; |
863 | } else { | 838 | } else { |
864 | pfLock->fl_type = F_WRLCK; | 839 | pfLock->fl_type = F_WRLCK; |
@@ -892,8 +867,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
892 | length, pfLock, | 867 | length, pfLock, |
893 | posix_lock_type, wait_flag); | 868 | posix_lock_type, wait_flag); |
894 | } else { | 869 | } else { |
895 | struct cifsFileInfo *fid = | 870 | struct cifsFileInfo *fid = file->private_data; |
896 | (struct cifsFileInfo *)file->private_data; | ||
897 | 871 | ||
898 | if (numLock) { | 872 | if (numLock) { |
899 | rc = CIFSSMBLock(xid, tcon, netfid, length, | 873 | rc = CIFSSMBLock(xid, tcon, netfid, length, |
@@ -923,9 +897,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
923 | 1, 0, li->type, false); | 897 | 1, 0, li->type, false); |
924 | if (stored_rc) | 898 | if (stored_rc) |
925 | rc = stored_rc; | 899 | rc = stored_rc; |
926 | 900 | else { | |
927 | list_del(&li->llist); | 901 | list_del(&li->llist); |
928 | kfree(li); | 902 | kfree(li); |
903 | } | ||
929 | } | 904 | } |
930 | } | 905 | } |
931 | mutex_unlock(&fid->lock_mutex); | 906 | mutex_unlock(&fid->lock_mutex); |
@@ -988,13 +963,12 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
988 | 963 | ||
989 | pTcon = cifs_sb->tcon; | 964 | pTcon = cifs_sb->tcon; |
990 | 965 | ||
991 | /* cFYI(1, | 966 | /* cFYI(1, " write %d bytes to offset %lld of %s", write_size, |
992 | (" write %d bytes to offset %lld of %s", write_size, | 967 | *poffset, file->f_path.dentry->d_name.name); */ |
993 | *poffset, file->f_path.dentry->d_name.name)); */ | ||
994 | 968 | ||
995 | if (file->private_data == NULL) | 969 | if (file->private_data == NULL) |
996 | return -EBADF; | 970 | return -EBADF; |
997 | open_file = (struct cifsFileInfo *) file->private_data; | 971 | open_file = file->private_data; |
998 | 972 | ||
999 | rc = generic_write_checks(file, poffset, &write_size, 0); | 973 | rc = generic_write_checks(file, poffset, &write_size, 0); |
1000 | if (rc) | 974 | if (rc) |
@@ -1091,12 +1065,12 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
1091 | 1065 | ||
1092 | pTcon = cifs_sb->tcon; | 1066 | pTcon = cifs_sb->tcon; |
1093 | 1067 | ||
1094 | cFYI(1, ("write %zd bytes to offset %lld of %s", write_size, | 1068 | cFYI(1, "write %zd bytes to offset %lld of %s", write_size, |
1095 | *poffset, file->f_path.dentry->d_name.name)); | 1069 | *poffset, file->f_path.dentry->d_name.name); |
1096 | 1070 | ||
1097 | if (file->private_data == NULL) | 1071 | if (file->private_data == NULL) |
1098 | return -EBADF; | 1072 | return -EBADF; |
1099 | open_file = (struct cifsFileInfo *)file->private_data; | 1073 | open_file = file->private_data; |
1100 | 1074 | ||
1101 | xid = GetXid(); | 1075 | xid = GetXid(); |
1102 | 1076 | ||
@@ -1233,7 +1207,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1233 | it being zero) during stress testcases so we need to check for it */ | 1207 | it being zero) during stress testcases so we need to check for it */ |
1234 | 1208 | ||
1235 | if (cifs_inode == NULL) { | 1209 | if (cifs_inode == NULL) { |
1236 | cERROR(1, ("Null inode passed to cifs_writeable_file")); | 1210 | cERROR(1, "Null inode passed to cifs_writeable_file"); |
1237 | dump_stack(); | 1211 | dump_stack(); |
1238 | return NULL; | 1212 | return NULL; |
1239 | } | 1213 | } |
@@ -1277,7 +1251,7 @@ refind_writable: | |||
1277 | again. Note that it would be bad | 1251 | again. Note that it would be bad |
1278 | to hold up writepages here (rather than | 1252 | to hold up writepages here (rather than |
1279 | in caller) with continuous retries */ | 1253 | in caller) with continuous retries */ |
1280 | cFYI(1, ("wp failed on reopen file")); | 1254 | cFYI(1, "wp failed on reopen file"); |
1281 | read_lock(&GlobalSMBSeslock); | 1255 | read_lock(&GlobalSMBSeslock); |
1282 | /* can not use this handle, no write | 1256 | /* can not use this handle, no write |
1283 | pending on this one after all */ | 1257 | pending on this one after all */ |
@@ -1353,7 +1327,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1353 | else if (bytes_written < 0) | 1327 | else if (bytes_written < 0) |
1354 | rc = bytes_written; | 1328 | rc = bytes_written; |
1355 | } else { | 1329 | } else { |
1356 | cFYI(1, ("No writeable filehandles for inode")); | 1330 | cFYI(1, "No writeable filehandles for inode"); |
1357 | rc = -EIO; | 1331 | rc = -EIO; |
1358 | } | 1332 | } |
1359 | 1333 | ||
@@ -1525,7 +1499,7 @@ retry: | |||
1525 | */ | 1499 | */ |
1526 | open_file = find_writable_file(CIFS_I(mapping->host)); | 1500 | open_file = find_writable_file(CIFS_I(mapping->host)); |
1527 | if (!open_file) { | 1501 | if (!open_file) { |
1528 | cERROR(1, ("No writable handles for inode")); | 1502 | cERROR(1, "No writable handles for inode"); |
1529 | rc = -EBADF; | 1503 | rc = -EBADF; |
1530 | } else { | 1504 | } else { |
1531 | long_op = cifs_write_timeout(cifsi, offset); | 1505 | long_op = cifs_write_timeout(cifsi, offset); |
@@ -1538,8 +1512,8 @@ retry: | |||
1538 | cifs_update_eof(cifsi, offset, bytes_written); | 1512 | cifs_update_eof(cifsi, offset, bytes_written); |
1539 | 1513 | ||
1540 | if (rc || bytes_written < bytes_to_write) { | 1514 | if (rc || bytes_written < bytes_to_write) { |
1541 | cERROR(1, ("Write2 ret %d, wrote %d", | 1515 | cERROR(1, "Write2 ret %d, wrote %d", |
1542 | rc, bytes_written)); | 1516 | rc, bytes_written); |
1543 | /* BB what if continued retry is | 1517 | /* BB what if continued retry is |
1544 | requested via mount flags? */ | 1518 | requested via mount flags? */ |
1545 | if (rc == -ENOSPC) | 1519 | if (rc == -ENOSPC) |
@@ -1600,7 +1574,7 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc) | |||
1600 | /* BB add check for wbc flags */ | 1574 | /* BB add check for wbc flags */ |
1601 | page_cache_get(page); | 1575 | page_cache_get(page); |
1602 | if (!PageUptodate(page)) | 1576 | if (!PageUptodate(page)) |
1603 | cFYI(1, ("ppw - page not up to date")); | 1577 | cFYI(1, "ppw - page not up to date"); |
1604 | 1578 | ||
1605 | /* | 1579 | /* |
1606 | * Set the "writeback" flag, and clear "dirty" in the radix tree. | 1580 | * Set the "writeback" flag, and clear "dirty" in the radix tree. |
@@ -1629,8 +1603,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
1629 | int rc; | 1603 | int rc; |
1630 | struct inode *inode = mapping->host; | 1604 | struct inode *inode = mapping->host; |
1631 | 1605 | ||
1632 | cFYI(1, ("write_end for page %p from pos %lld with %d bytes", | 1606 | cFYI(1, "write_end for page %p from pos %lld with %d bytes", |
1633 | page, pos, copied)); | 1607 | page, pos, copied); |
1634 | 1608 | ||
1635 | if (PageChecked(page)) { | 1609 | if (PageChecked(page)) { |
1636 | if (copied == len) | 1610 | if (copied == len) |
@@ -1675,19 +1649,18 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
1675 | return rc; | 1649 | return rc; |
1676 | } | 1650 | } |
1677 | 1651 | ||
1678 | int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | 1652 | int cifs_fsync(struct file *file, int datasync) |
1679 | { | 1653 | { |
1680 | int xid; | 1654 | int xid; |
1681 | int rc = 0; | 1655 | int rc = 0; |
1682 | struct cifsTconInfo *tcon; | 1656 | struct cifsTconInfo *tcon; |
1683 | struct cifsFileInfo *smbfile = | 1657 | struct cifsFileInfo *smbfile = file->private_data; |
1684 | (struct cifsFileInfo *)file->private_data; | ||
1685 | struct inode *inode = file->f_path.dentry->d_inode; | 1658 | struct inode *inode = file->f_path.dentry->d_inode; |
1686 | 1659 | ||
1687 | xid = GetXid(); | 1660 | xid = GetXid(); |
1688 | 1661 | ||
1689 | cFYI(1, ("Sync file - name: %s datasync: 0x%x", | 1662 | cFYI(1, "Sync file - name: %s datasync: 0x%x", |
1690 | dentry->d_name.name, datasync)); | 1663 | file->f_path.dentry->d_name.name, datasync); |
1691 | 1664 | ||
1692 | rc = filemap_write_and_wait(inode->i_mapping); | 1665 | rc = filemap_write_and_wait(inode->i_mapping); |
1693 | if (rc == 0) { | 1666 | if (rc == 0) { |
@@ -1711,7 +1684,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1711 | unsigned int rpages = 0; | 1684 | unsigned int rpages = 0; |
1712 | int rc = 0; | 1685 | int rc = 0; |
1713 | 1686 | ||
1714 | cFYI(1, ("sync page %p",page)); | 1687 | cFYI(1, "sync page %p", page); |
1715 | mapping = page->mapping; | 1688 | mapping = page->mapping; |
1716 | if (!mapping) | 1689 | if (!mapping) |
1717 | return 0; | 1690 | return 0; |
@@ -1722,7 +1695,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1722 | /* fill in rpages then | 1695 | /* fill in rpages then |
1723 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ | 1696 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ |
1724 | 1697 | ||
1725 | /* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); | 1698 | /* cFYI(1, "rpages is %d for sync page of Index %ld", rpages, index); |
1726 | 1699 | ||
1727 | #if 0 | 1700 | #if 0 |
1728 | if (rc < 0) | 1701 | if (rc < 0) |
@@ -1756,7 +1729,7 @@ int cifs_flush(struct file *file, fl_owner_t id) | |||
1756 | CIFS_I(inode)->write_behind_rc = 0; | 1729 | CIFS_I(inode)->write_behind_rc = 0; |
1757 | } | 1730 | } |
1758 | 1731 | ||
1759 | cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc)); | 1732 | cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc); |
1760 | 1733 | ||
1761 | return rc; | 1734 | return rc; |
1762 | } | 1735 | } |
@@ -1785,10 +1758,10 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1785 | FreeXid(xid); | 1758 | FreeXid(xid); |
1786 | return rc; | 1759 | return rc; |
1787 | } | 1760 | } |
1788 | open_file = (struct cifsFileInfo *)file->private_data; | 1761 | open_file = file->private_data; |
1789 | 1762 | ||
1790 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1763 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1791 | cFYI(1, ("attempting read on write only file instance")); | 1764 | cFYI(1, "attempting read on write only file instance"); |
1792 | 1765 | ||
1793 | for (total_read = 0, current_offset = read_data; | 1766 | for (total_read = 0, current_offset = read_data; |
1794 | read_size > total_read; | 1767 | read_size > total_read; |
@@ -1866,10 +1839,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1866 | FreeXid(xid); | 1839 | FreeXid(xid); |
1867 | return rc; | 1840 | return rc; |
1868 | } | 1841 | } |
1869 | open_file = (struct cifsFileInfo *)file->private_data; | 1842 | open_file = file->private_data; |
1870 | 1843 | ||
1871 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1844 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1872 | cFYI(1, ("attempting read on write only file instance")); | 1845 | cFYI(1, "attempting read on write only file instance"); |
1873 | 1846 | ||
1874 | for (total_read = 0, current_offset = read_data; | 1847 | for (total_read = 0, current_offset = read_data; |
1875 | read_size > total_read; | 1848 | read_size > total_read; |
@@ -1920,7 +1893,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
1920 | xid = GetXid(); | 1893 | xid = GetXid(); |
1921 | rc = cifs_revalidate_file(file); | 1894 | rc = cifs_revalidate_file(file); |
1922 | if (rc) { | 1895 | if (rc) { |
1923 | cFYI(1, ("Validation prior to mmap failed, error=%d", rc)); | 1896 | cFYI(1, "Validation prior to mmap failed, error=%d", rc); |
1924 | FreeXid(xid); | 1897 | FreeXid(xid); |
1925 | return rc; | 1898 | return rc; |
1926 | } | 1899 | } |
@@ -1931,8 +1904,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
1931 | 1904 | ||
1932 | 1905 | ||
1933 | static void cifs_copy_cache_pages(struct address_space *mapping, | 1906 | static void cifs_copy_cache_pages(struct address_space *mapping, |
1934 | struct list_head *pages, int bytes_read, char *data, | 1907 | struct list_head *pages, int bytes_read, char *data) |
1935 | struct pagevec *plru_pvec) | ||
1936 | { | 1908 | { |
1937 | struct page *page; | 1909 | struct page *page; |
1938 | char *target; | 1910 | char *target; |
@@ -1944,14 +1916,15 @@ static void cifs_copy_cache_pages(struct address_space *mapping, | |||
1944 | page = list_entry(pages->prev, struct page, lru); | 1916 | page = list_entry(pages->prev, struct page, lru); |
1945 | list_del(&page->lru); | 1917 | list_del(&page->lru); |
1946 | 1918 | ||
1947 | if (add_to_page_cache(page, mapping, page->index, | 1919 | if (add_to_page_cache_lru(page, mapping, page->index, |
1948 | GFP_KERNEL)) { | 1920 | GFP_KERNEL)) { |
1949 | page_cache_release(page); | 1921 | page_cache_release(page); |
1950 | cFYI(1, ("Add page cache failed")); | 1922 | cFYI(1, "Add page cache failed"); |
1951 | data += PAGE_CACHE_SIZE; | 1923 | data += PAGE_CACHE_SIZE; |
1952 | bytes_read -= PAGE_CACHE_SIZE; | 1924 | bytes_read -= PAGE_CACHE_SIZE; |
1953 | continue; | 1925 | continue; |
1954 | } | 1926 | } |
1927 | page_cache_release(page); | ||
1955 | 1928 | ||
1956 | target = kmap_atomic(page, KM_USER0); | 1929 | target = kmap_atomic(page, KM_USER0); |
1957 | 1930 | ||
@@ -1970,9 +1943,10 @@ static void cifs_copy_cache_pages(struct address_space *mapping, | |||
1970 | flush_dcache_page(page); | 1943 | flush_dcache_page(page); |
1971 | SetPageUptodate(page); | 1944 | SetPageUptodate(page); |
1972 | unlock_page(page); | 1945 | unlock_page(page); |
1973 | if (!pagevec_add(plru_pvec, page)) | ||
1974 | __pagevec_lru_add_file(plru_pvec); | ||
1975 | data += PAGE_CACHE_SIZE; | 1946 | data += PAGE_CACHE_SIZE; |
1947 | |||
1948 | /* add page to FS-Cache */ | ||
1949 | cifs_readpage_to_fscache(mapping->host, page); | ||
1976 | } | 1950 | } |
1977 | return; | 1951 | return; |
1978 | } | 1952 | } |
@@ -1990,7 +1964,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1990 | unsigned int read_size, i; | 1964 | unsigned int read_size, i; |
1991 | char *smb_read_data = NULL; | 1965 | char *smb_read_data = NULL; |
1992 | struct smb_com_read_rsp *pSMBr; | 1966 | struct smb_com_read_rsp *pSMBr; |
1993 | struct pagevec lru_pvec; | ||
1994 | struct cifsFileInfo *open_file; | 1967 | struct cifsFileInfo *open_file; |
1995 | int buf_type = CIFS_NO_BUFFER; | 1968 | int buf_type = CIFS_NO_BUFFER; |
1996 | 1969 | ||
@@ -2000,12 +1973,20 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2000 | FreeXid(xid); | 1973 | FreeXid(xid); |
2001 | return rc; | 1974 | return rc; |
2002 | } | 1975 | } |
2003 | open_file = (struct cifsFileInfo *)file->private_data; | 1976 | open_file = file->private_data; |
2004 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 1977 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
2005 | pTcon = cifs_sb->tcon; | 1978 | pTcon = cifs_sb->tcon; |
2006 | 1979 | ||
2007 | pagevec_init(&lru_pvec, 0); | 1980 | /* |
2008 | cFYI(DBG2, ("rpages: num pages %d", num_pages)); | 1981 | * Reads as many pages as possible from fscache. Returns -ENOBUFS |
1982 | * immediately if the cookie is negative | ||
1983 | */ | ||
1984 | rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list, | ||
1985 | &num_pages); | ||
1986 | if (rc == 0) | ||
1987 | goto read_complete; | ||
1988 | |||
1989 | cFYI(DBG2, "rpages: num pages %d", num_pages); | ||
2009 | for (i = 0; i < num_pages; ) { | 1990 | for (i = 0; i < num_pages; ) { |
2010 | unsigned contig_pages; | 1991 | unsigned contig_pages; |
2011 | struct page *tmp_page; | 1992 | struct page *tmp_page; |
@@ -2038,8 +2019,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2038 | /* Read size needs to be in multiples of one page */ | 2019 | /* Read size needs to be in multiples of one page */ |
2039 | read_size = min_t(const unsigned int, read_size, | 2020 | read_size = min_t(const unsigned int, read_size, |
2040 | cifs_sb->rsize & PAGE_CACHE_MASK); | 2021 | cifs_sb->rsize & PAGE_CACHE_MASK); |
2041 | cFYI(DBG2, ("rpages: read size 0x%x contiguous pages %d", | 2022 | cFYI(DBG2, "rpages: read size 0x%x contiguous pages %d", |
2042 | read_size, contig_pages)); | 2023 | read_size, contig_pages); |
2043 | rc = -EAGAIN; | 2024 | rc = -EAGAIN; |
2044 | while (rc == -EAGAIN) { | 2025 | while (rc == -EAGAIN) { |
2045 | if ((open_file->invalidHandle) && | 2026 | if ((open_file->invalidHandle) && |
@@ -2066,14 +2047,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2066 | } | 2047 | } |
2067 | } | 2048 | } |
2068 | if ((rc < 0) || (smb_read_data == NULL)) { | 2049 | if ((rc < 0) || (smb_read_data == NULL)) { |
2069 | cFYI(1, ("Read error in readpages: %d", rc)); | 2050 | cFYI(1, "Read error in readpages: %d", rc); |
2070 | break; | 2051 | break; |
2071 | } else if (bytes_read > 0) { | 2052 | } else if (bytes_read > 0) { |
2072 | task_io_account_read(bytes_read); | 2053 | task_io_account_read(bytes_read); |
2073 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; | 2054 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; |
2074 | cifs_copy_cache_pages(mapping, page_list, bytes_read, | 2055 | cifs_copy_cache_pages(mapping, page_list, bytes_read, |
2075 | smb_read_data + 4 /* RFC1001 hdr */ + | 2056 | smb_read_data + 4 /* RFC1001 hdr */ + |
2076 | le16_to_cpu(pSMBr->DataOffset), &lru_pvec); | 2057 | le16_to_cpu(pSMBr->DataOffset)); |
2077 | 2058 | ||
2078 | i += bytes_read >> PAGE_CACHE_SHIFT; | 2059 | i += bytes_read >> PAGE_CACHE_SHIFT; |
2079 | cifs_stats_bytes_read(pTcon, bytes_read); | 2060 | cifs_stats_bytes_read(pTcon, bytes_read); |
@@ -2089,9 +2070,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2089 | /* break; */ | 2070 | /* break; */ |
2090 | } | 2071 | } |
2091 | } else { | 2072 | } else { |
2092 | cFYI(1, ("No bytes read (%d) at offset %lld . " | 2073 | cFYI(1, "No bytes read (%d) at offset %lld . " |
2093 | "Cleaning remaining pages from readahead list", | 2074 | "Cleaning remaining pages from readahead list", |
2094 | bytes_read, offset)); | 2075 | bytes_read, offset); |
2095 | /* BB turn off caching and do new lookup on | 2076 | /* BB turn off caching and do new lookup on |
2096 | file size at server? */ | 2077 | file size at server? */ |
2097 | break; | 2078 | break; |
@@ -2106,8 +2087,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2106 | bytes_read = 0; | 2087 | bytes_read = 0; |
2107 | } | 2088 | } |
2108 | 2089 | ||
2109 | pagevec_lru_add_file(&lru_pvec); | ||
2110 | |||
2111 | /* need to free smb_read_data buf before exit */ | 2090 | /* need to free smb_read_data buf before exit */ |
2112 | if (smb_read_data) { | 2091 | if (smb_read_data) { |
2113 | if (buf_type == CIFS_SMALL_BUFFER) | 2092 | if (buf_type == CIFS_SMALL_BUFFER) |
@@ -2117,6 +2096,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2117 | smb_read_data = NULL; | 2096 | smb_read_data = NULL; |
2118 | } | 2097 | } |
2119 | 2098 | ||
2099 | read_complete: | ||
2120 | FreeXid(xid); | 2100 | FreeXid(xid); |
2121 | return rc; | 2101 | return rc; |
2122 | } | 2102 | } |
@@ -2127,6 +2107,11 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
2127 | char *read_data; | 2107 | char *read_data; |
2128 | int rc; | 2108 | int rc; |
2129 | 2109 | ||
2110 | /* Is the page cached? */ | ||
2111 | rc = cifs_readpage_from_fscache(file->f_path.dentry->d_inode, page); | ||
2112 | if (rc == 0) | ||
2113 | goto read_complete; | ||
2114 | |||
2130 | page_cache_get(page); | 2115 | page_cache_get(page); |
2131 | read_data = kmap(page); | 2116 | read_data = kmap(page); |
2132 | /* for reads over a certain size could initiate async read ahead */ | 2117 | /* for reads over a certain size could initiate async read ahead */ |
@@ -2136,7 +2121,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
2136 | if (rc < 0) | 2121 | if (rc < 0) |
2137 | goto io_error; | 2122 | goto io_error; |
2138 | else | 2123 | else |
2139 | cFYI(1, ("Bytes read %d", rc)); | 2124 | cFYI(1, "Bytes read %d", rc); |
2140 | 2125 | ||
2141 | file->f_path.dentry->d_inode->i_atime = | 2126 | file->f_path.dentry->d_inode->i_atime = |
2142 | current_fs_time(file->f_path.dentry->d_inode->i_sb); | 2127 | current_fs_time(file->f_path.dentry->d_inode->i_sb); |
@@ -2146,11 +2131,17 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
2146 | 2131 | ||
2147 | flush_dcache_page(page); | 2132 | flush_dcache_page(page); |
2148 | SetPageUptodate(page); | 2133 | SetPageUptodate(page); |
2134 | |||
2135 | /* send this page to the cache */ | ||
2136 | cifs_readpage_to_fscache(file->f_path.dentry->d_inode, page); | ||
2137 | |||
2149 | rc = 0; | 2138 | rc = 0; |
2150 | 2139 | ||
2151 | io_error: | 2140 | io_error: |
2152 | kunmap(page); | 2141 | kunmap(page); |
2153 | page_cache_release(page); | 2142 | page_cache_release(page); |
2143 | |||
2144 | read_complete: | ||
2154 | return rc; | 2145 | return rc; |
2155 | } | 2146 | } |
2156 | 2147 | ||
@@ -2168,8 +2159,8 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
2168 | return rc; | 2159 | return rc; |
2169 | } | 2160 | } |
2170 | 2161 | ||
2171 | cFYI(1, ("readpage %p at offset %d 0x%x\n", | 2162 | cFYI(1, "readpage %p at offset %d 0x%x\n", |
2172 | page, (int)offset, (int)offset)); | 2163 | page, (int)offset, (int)offset); |
2173 | 2164 | ||
2174 | rc = cifs_readpage_worker(file, page, &offset); | 2165 | rc = cifs_readpage_worker(file, page, &offset); |
2175 | 2166 | ||
@@ -2239,7 +2230,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, | |||
2239 | struct page *page; | 2230 | struct page *page; |
2240 | int rc = 0; | 2231 | int rc = 0; |
2241 | 2232 | ||
2242 | cFYI(1, ("write_begin from %lld len %d", (long long)pos, len)); | 2233 | cFYI(1, "write_begin from %lld len %d", (long long)pos, len); |
2243 | 2234 | ||
2244 | page = grab_cache_page_write_begin(mapping, index, flags); | 2235 | page = grab_cache_page_write_begin(mapping, index, flags); |
2245 | if (!page) { | 2236 | if (!page) { |
@@ -2300,8 +2291,23 @@ out: | |||
2300 | return rc; | 2291 | return rc; |
2301 | } | 2292 | } |
2302 | 2293 | ||
2303 | static void | 2294 | static int cifs_release_page(struct page *page, gfp_t gfp) |
2304 | cifs_oplock_break(struct slow_work *work) | 2295 | { |
2296 | if (PagePrivate(page)) | ||
2297 | return 0; | ||
2298 | |||
2299 | return cifs_fscache_release_page(page, gfp); | ||
2300 | } | ||
2301 | |||
2302 | static void cifs_invalidate_page(struct page *page, unsigned long offset) | ||
2303 | { | ||
2304 | struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host); | ||
2305 | |||
2306 | if (offset == 0) | ||
2307 | cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); | ||
2308 | } | ||
2309 | |||
2310 | void cifs_oplock_break(struct work_struct *work) | ||
2305 | { | 2311 | { |
2306 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | 2312 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, |
2307 | oplock_break); | 2313 | oplock_break); |
@@ -2311,12 +2317,10 @@ cifs_oplock_break(struct slow_work *work) | |||
2311 | int rc, waitrc = 0; | 2317 | int rc, waitrc = 0; |
2312 | 2318 | ||
2313 | if (inode && S_ISREG(inode->i_mode)) { | 2319 | if (inode && S_ISREG(inode->i_mode)) { |
2314 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 2320 | if (cinode->clientCanCacheRead) |
2315 | if (cinode->clientCanCacheAll == 0) | ||
2316 | break_lease(inode, O_RDONLY); | 2321 | break_lease(inode, O_RDONLY); |
2317 | else if (cinode->clientCanCacheRead == 0) | 2322 | else |
2318 | break_lease(inode, O_WRONLY); | 2323 | break_lease(inode, O_WRONLY); |
2319 | #endif | ||
2320 | rc = filemap_fdatawrite(inode->i_mapping); | 2324 | rc = filemap_fdatawrite(inode->i_mapping); |
2321 | if (cinode->clientCanCacheRead == 0) { | 2325 | if (cinode->clientCanCacheRead == 0) { |
2322 | waitrc = filemap_fdatawait(inode->i_mapping); | 2326 | waitrc = filemap_fdatawait(inode->i_mapping); |
@@ -2326,7 +2330,7 @@ cifs_oplock_break(struct slow_work *work) | |||
2326 | rc = waitrc; | 2330 | rc = waitrc; |
2327 | if (rc) | 2331 | if (rc) |
2328 | cinode->write_behind_rc = rc; | 2332 | cinode->write_behind_rc = rc; |
2329 | cFYI(1, ("Oplock flush inode %p rc %d", inode, rc)); | 2333 | cFYI(1, "Oplock flush inode %p rc %d", inode, rc); |
2330 | } | 2334 | } |
2331 | 2335 | ||
2332 | /* | 2336 | /* |
@@ -2338,35 +2342,32 @@ cifs_oplock_break(struct slow_work *work) | |||
2338 | if (!cfile->closePend && !cfile->oplock_break_cancelled) { | 2342 | if (!cfile->closePend && !cfile->oplock_break_cancelled) { |
2339 | rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0, | 2343 | rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0, |
2340 | LOCKING_ANDX_OPLOCK_RELEASE, false); | 2344 | LOCKING_ANDX_OPLOCK_RELEASE, false); |
2341 | cFYI(1, ("Oplock release rc = %d", rc)); | 2345 | cFYI(1, "Oplock release rc = %d", rc); |
2342 | } | 2346 | } |
2347 | |||
2348 | /* | ||
2349 | * We might have kicked in before is_valid_oplock_break() | ||
2350 | * finished grabbing reference for us. Make sure it's done by | ||
2351 | * waiting for GlobalSMSSeslock. | ||
2352 | */ | ||
2353 | write_lock(&GlobalSMBSeslock); | ||
2354 | write_unlock(&GlobalSMBSeslock); | ||
2355 | |||
2356 | cifs_oplock_break_put(cfile); | ||
2343 | } | 2357 | } |
2344 | 2358 | ||
2345 | static int | 2359 | void cifs_oplock_break_get(struct cifsFileInfo *cfile) |
2346 | cifs_oplock_break_get(struct slow_work *work) | ||
2347 | { | 2360 | { |
2348 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | ||
2349 | oplock_break); | ||
2350 | mntget(cfile->mnt); | 2361 | mntget(cfile->mnt); |
2351 | cifsFileInfo_get(cfile); | 2362 | cifsFileInfo_get(cfile); |
2352 | return 0; | ||
2353 | } | 2363 | } |
2354 | 2364 | ||
2355 | static void | 2365 | void cifs_oplock_break_put(struct cifsFileInfo *cfile) |
2356 | cifs_oplock_break_put(struct slow_work *work) | ||
2357 | { | 2366 | { |
2358 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | ||
2359 | oplock_break); | ||
2360 | mntput(cfile->mnt); | 2367 | mntput(cfile->mnt); |
2361 | cifsFileInfo_put(cfile); | 2368 | cifsFileInfo_put(cfile); |
2362 | } | 2369 | } |
2363 | 2370 | ||
2364 | const struct slow_work_ops cifs_oplock_break_ops = { | ||
2365 | .get_ref = cifs_oplock_break_get, | ||
2366 | .put_ref = cifs_oplock_break_put, | ||
2367 | .execute = cifs_oplock_break, | ||
2368 | }; | ||
2369 | |||
2370 | const struct address_space_operations cifs_addr_ops = { | 2371 | const struct address_space_operations cifs_addr_ops = { |
2371 | .readpage = cifs_readpage, | 2372 | .readpage = cifs_readpage, |
2372 | .readpages = cifs_readpages, | 2373 | .readpages = cifs_readpages, |
@@ -2375,6 +2376,8 @@ const struct address_space_operations cifs_addr_ops = { | |||
2375 | .write_begin = cifs_write_begin, | 2376 | .write_begin = cifs_write_begin, |
2376 | .write_end = cifs_write_end, | 2377 | .write_end = cifs_write_end, |
2377 | .set_page_dirty = __set_page_dirty_nobuffers, | 2378 | .set_page_dirty = __set_page_dirty_nobuffers, |
2379 | .releasepage = cifs_release_page, | ||
2380 | .invalidatepage = cifs_invalidate_page, | ||
2378 | /* .sync_page = cifs_sync_page, */ | 2381 | /* .sync_page = cifs_sync_page, */ |
2379 | /* .direct_IO = */ | 2382 | /* .direct_IO = */ |
2380 | }; | 2383 | }; |
@@ -2391,6 +2394,8 @@ const struct address_space_operations cifs_addr_ops_smallbuf = { | |||
2391 | .write_begin = cifs_write_begin, | 2394 | .write_begin = cifs_write_begin, |
2392 | .write_end = cifs_write_end, | 2395 | .write_end = cifs_write_end, |
2393 | .set_page_dirty = __set_page_dirty_nobuffers, | 2396 | .set_page_dirty = __set_page_dirty_nobuffers, |
2397 | .releasepage = cifs_release_page, | ||
2398 | .invalidatepage = cifs_invalidate_page, | ||
2394 | /* .sync_page = cifs_sync_page, */ | 2399 | /* .sync_page = cifs_sync_page, */ |
2395 | /* .direct_IO = */ | 2400 | /* .direct_IO = */ |
2396 | }; | 2401 | }; |