diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 245 |
1 files changed, 125 insertions, 120 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5f1b707188f8..7d6fb6f3adeb 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * fs/cifs/file.c | 2 | * fs/cifs/file.c |
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,2003 | 6 | * Copyright (C) International Business Machines Corp., 2002,2007 |
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 | * |
@@ -45,7 +45,7 @@ static inline struct cifsFileInfo *cifs_init_private( | |||
45 | { | 45 | { |
46 | memset(private_data, 0, sizeof(struct cifsFileInfo)); | 46 | memset(private_data, 0, sizeof(struct cifsFileInfo)); |
47 | private_data->netfid = netfid; | 47 | private_data->netfid = netfid; |
48 | private_data->pid = current->tgid; | 48 | private_data->pid = current->tgid; |
49 | init_MUTEX(&private_data->fh_sem); | 49 | init_MUTEX(&private_data->fh_sem); |
50 | mutex_init(&private_data->lock_mutex); | 50 | mutex_init(&private_data->lock_mutex); |
51 | INIT_LIST_HEAD(&private_data->llist); | 51 | INIT_LIST_HEAD(&private_data->llist); |
@@ -57,7 +57,7 @@ static inline struct cifsFileInfo *cifs_init_private( | |||
57 | does not tell us which handle the write is for so there can | 57 | does not tell us which handle the write is for so there can |
58 | be a close (overlapping with write) of the filehandle that | 58 | be a close (overlapping with write) of the filehandle that |
59 | cifs_writepages chose to use */ | 59 | cifs_writepages chose to use */ |
60 | atomic_set(&private_data->wrtPending,0); | 60 | atomic_set(&private_data->wrtPending, 0); |
61 | 61 | ||
62 | return private_data; | 62 | return private_data; |
63 | } | 63 | } |
@@ -105,7 +105,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
105 | in the list so we do not have to walk the | 105 | in the list so we do not have to walk the |
106 | list to search for one in prepare_write */ | 106 | list to search for one in prepare_write */ |
107 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { | 107 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { |
108 | list_add_tail(&pCifsFile->flist, | 108 | list_add_tail(&pCifsFile->flist, |
109 | &pCifsInode->openFileList); | 109 | &pCifsInode->openFileList); |
110 | } else { | 110 | } else { |
111 | list_add(&pCifsFile->flist, | 111 | list_add(&pCifsFile->flist, |
@@ -218,9 +218,9 @@ int cifs_open(struct inode *inode, struct file *file) | |||
218 | 218 | ||
219 | /********************************************************************* | 219 | /********************************************************************* |
220 | * open flag mapping table: | 220 | * open flag mapping table: |
221 | * | 221 | * |
222 | * POSIX Flag CIFS Disposition | 222 | * POSIX Flag CIFS Disposition |
223 | * ---------- ---------------- | 223 | * ---------- ---------------- |
224 | * O_CREAT FILE_OPEN_IF | 224 | * O_CREAT FILE_OPEN_IF |
225 | * O_CREAT | O_EXCL FILE_CREATE | 225 | * O_CREAT | O_EXCL FILE_CREATE |
226 | * O_CREAT | O_TRUNC FILE_OVERWRITE_IF | 226 | * O_CREAT | O_TRUNC FILE_OVERWRITE_IF |
@@ -228,12 +228,12 @@ int cifs_open(struct inode *inode, struct file *file) | |||
228 | * none of the above FILE_OPEN | 228 | * none of the above FILE_OPEN |
229 | * | 229 | * |
230 | * Note that there is not a direct match between disposition | 230 | * Note that there is not a direct match between disposition |
231 | * FILE_SUPERSEDE (ie create whether or not file exists although | 231 | * FILE_SUPERSEDE (ie create whether or not file exists although |
232 | * O_CREAT | O_TRUNC is similar but truncates the existing | 232 | * O_CREAT | O_TRUNC is similar but truncates the existing |
233 | * file rather than creating a new file as FILE_SUPERSEDE does | 233 | * file rather than creating a new file as FILE_SUPERSEDE does |
234 | * (which uses the attributes / metadata passed in on open call) | 234 | * (which uses the attributes / metadata passed in on open call) |
235 | *? | 235 | *? |
236 | *? O_SYNC is a reasonable match to CIFS writethrough flag | 236 | *? O_SYNC is a reasonable match to CIFS writethrough flag |
237 | *? and the read write flags match reasonably. O_LARGEFILE | 237 | *? and the read write flags match reasonably. O_LARGEFILE |
238 | *? is irrelevant because largefile support is always used | 238 | *? is irrelevant because largefile support is always used |
239 | *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, | 239 | *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, |
@@ -253,8 +253,8 @@ int cifs_open(struct inode *inode, struct file *file) | |||
253 | and calling get_inode_info with returned buf (at least helps | 253 | and calling get_inode_info with returned buf (at least helps |
254 | non-Unix server case) */ | 254 | non-Unix server case) */ |
255 | 255 | ||
256 | /* BB we can not do this if this is the second open of a file | 256 | /* BB we can not do this if this is the second open of a file |
257 | and the first handle has writebehind data, we might be | 257 | and the first handle has writebehind data, we might be |
258 | able to simply do a filemap_fdatawrite/filemap_fdatawait first */ | 258 | able to simply do a filemap_fdatawrite/filemap_fdatawait first */ |
259 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 259 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
260 | if (!buf) { | 260 | if (!buf) { |
@@ -263,7 +263,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
263 | } | 263 | } |
264 | 264 | ||
265 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) | 265 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) |
266 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | 266 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, |
267 | desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, | 267 | desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, |
268 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags | 268 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags |
269 | & CIFS_MOUNT_MAP_SPECIAL_CHR); | 269 | & CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -300,7 +300,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
300 | write_unlock(&GlobalSMBSeslock); | 300 | write_unlock(&GlobalSMBSeslock); |
301 | } | 301 | } |
302 | 302 | ||
303 | if (oplock & CIFS_CREATE_ACTION) { | 303 | if (oplock & CIFS_CREATE_ACTION) { |
304 | /* time to set mode which we can not set earlier due to | 304 | /* time to set mode which we can not set earlier due to |
305 | problems creating new read-only files */ | 305 | problems creating new read-only files */ |
306 | if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { | 306 | if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { |
@@ -308,7 +308,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
308 | inode->i_mode, | 308 | inode->i_mode, |
309 | (__u64)-1, (__u64)-1, 0 /* dev */, | 309 | (__u64)-1, (__u64)-1, 0 /* dev */, |
310 | cifs_sb->local_nls, | 310 | cifs_sb->local_nls, |
311 | cifs_sb->mnt_cifs_flags & | 311 | cifs_sb->mnt_cifs_flags & |
312 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 312 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
313 | } else { | 313 | } else { |
314 | /* BB implement via Windows security descriptors eg | 314 | /* BB implement via Windows security descriptors eg |
@@ -345,7 +345,7 @@ static int cifs_reopen_file(struct file *file, int can_flush) | |||
345 | struct cifsTconInfo *pTcon; | 345 | struct cifsTconInfo *pTcon; |
346 | struct cifsFileInfo *pCifsFile; | 346 | struct cifsFileInfo *pCifsFile; |
347 | struct cifsInodeInfo *pCifsInode; | 347 | struct cifsInodeInfo *pCifsInode; |
348 | struct inode * inode; | 348 | struct inode *inode; |
349 | char *full_path = NULL; | 349 | char *full_path = NULL; |
350 | int desiredAccess; | 350 | int desiredAccess; |
351 | int disposition = FILE_OPEN; | 351 | int disposition = FILE_OPEN; |
@@ -372,7 +372,7 @@ static int cifs_reopen_file(struct file *file, int can_flush) | |||
372 | } | 372 | } |
373 | 373 | ||
374 | inode = file->f_path.dentry->d_inode; | 374 | inode = file->f_path.dentry->d_inode; |
375 | if(inode == NULL) { | 375 | if (inode == NULL) { |
376 | cERROR(1, ("inode not valid")); | 376 | cERROR(1, ("inode not valid")); |
377 | dump_stack(); | 377 | dump_stack(); |
378 | rc = -EBADF; | 378 | rc = -EBADF; |
@@ -396,7 +396,7 @@ reopen_error_exit: | |||
396 | } | 396 | } |
397 | 397 | ||
398 | cFYI(1, ("inode = 0x%p file flags 0x%x for %s", | 398 | cFYI(1, ("inode = 0x%p file flags 0x%x for %s", |
399 | inode, file->f_flags,full_path)); | 399 | inode, file->f_flags, full_path)); |
400 | desiredAccess = cifs_convert_flags(file->f_flags); | 400 | desiredAccess = cifs_convert_flags(file->f_flags); |
401 | 401 | ||
402 | if (oplockEnabled) | 402 | if (oplockEnabled) |
@@ -405,14 +405,14 @@ reopen_error_exit: | |||
405 | oplock = FALSE; | 405 | oplock = FALSE; |
406 | 406 | ||
407 | /* Can not refresh inode by passing in file_info buf to be returned | 407 | /* Can not refresh inode by passing in file_info buf to be returned |
408 | by SMBOpen and then calling get_inode_info with returned buf | 408 | by SMBOpen and then calling get_inode_info with returned buf |
409 | since file might have write behind data that needs to be flushed | 409 | since file might have write behind data that needs to be flushed |
410 | and server version of file size can be stale. If we knew for sure | 410 | and server version of file size can be stale. If we knew for sure |
411 | that inode was not dirty locally we could do this */ | 411 | that inode was not dirty locally we could do this */ |
412 | 412 | ||
413 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, | 413 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, |
414 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | 414 | CREATE_NOT_DIR, &netfid, &oplock, NULL, |
415 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 415 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
416 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 416 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
417 | if (rc) { | 417 | if (rc) { |
418 | up(&pCifsFile->fh_sem); | 418 | up(&pCifsFile->fh_sem); |
@@ -486,22 +486,22 @@ int cifs_close(struct inode *inode, struct file *file) | |||
486 | already closed */ | 486 | already closed */ |
487 | if (pTcon->tidStatus != CifsNeedReconnect) { | 487 | if (pTcon->tidStatus != CifsNeedReconnect) { |
488 | int timeout = 2; | 488 | int timeout = 2; |
489 | while((atomic_read(&pSMBFile->wrtPending) != 0) | 489 | while ((atomic_read(&pSMBFile->wrtPending) != 0) |
490 | && (timeout < 1000) ) { | 490 | && (timeout < 1000) ) { |
491 | /* Give write a better chance to get to | 491 | /* Give write a better chance to get to |
492 | server ahead of the close. We do not | 492 | server ahead of the close. We do not |
493 | want to add a wait_q here as it would | 493 | want to add a wait_q here as it would |
494 | increase the memory utilization as | 494 | increase the memory utilization as |
495 | the struct would be in each open file, | 495 | the struct would be in each open file, |
496 | but this should give enough time to | 496 | but this should give enough time to |
497 | clear the socket */ | 497 | clear the socket */ |
498 | #ifdef CONFIG_CIFS_DEBUG2 | 498 | #ifdef CONFIG_CIFS_DEBUG2 |
499 | cFYI(1,("close delay, write pending")); | 499 | cFYI(1, ("close delay, write pending")); |
500 | #endif /* DEBUG2 */ | 500 | #endif /* DEBUG2 */ |
501 | msleep(timeout); | 501 | msleep(timeout); |
502 | timeout *= 4; | 502 | timeout *= 4; |
503 | } | 503 | } |
504 | if(atomic_read(&pSMBFile->wrtPending)) | 504 | if (atomic_read(&pSMBFile->wrtPending)) |
505 | cERROR(1,("close with pending writes")); | 505 | cERROR(1,("close with pending writes")); |
506 | rc = CIFSSMBClose(xid, pTcon, | 506 | rc = CIFSSMBClose(xid, pTcon, |
507 | pSMBFile->netfid); | 507 | pSMBFile->netfid); |
@@ -534,7 +534,7 @@ int cifs_close(struct inode *inode, struct file *file) | |||
534 | CIFS_I(inode)->clientCanCacheRead = FALSE; | 534 | CIFS_I(inode)->clientCanCacheRead = FALSE; |
535 | CIFS_I(inode)->clientCanCacheAll = FALSE; | 535 | CIFS_I(inode)->clientCanCacheAll = FALSE; |
536 | } | 536 | } |
537 | if ((rc ==0) && CIFS_I(inode)->write_behind_rc) | 537 | if ((rc == 0) && CIFS_I(inode)->write_behind_rc) |
538 | rc = CIFS_I(inode)->write_behind_rc; | 538 | rc = CIFS_I(inode)->write_behind_rc; |
539 | FreeXid(xid); | 539 | FreeXid(xid); |
540 | return rc; | 540 | return rc; |
@@ -554,7 +554,8 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
554 | 554 | ||
555 | if (pCFileStruct) { | 555 | if (pCFileStruct) { |
556 | struct cifsTconInfo *pTcon; | 556 | struct cifsTconInfo *pTcon; |
557 | struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 557 | struct cifs_sb_info *cifs_sb = |
558 | CIFS_SB(file->f_path.dentry->d_sb); | ||
558 | 559 | ||
559 | pTcon = cifs_sb->tcon; | 560 | pTcon = cifs_sb->tcon; |
560 | 561 | ||
@@ -572,7 +573,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
572 | if (ptmp) { | 573 | if (ptmp) { |
573 | cFYI(1, ("closedir free smb buf in srch struct")); | 574 | cFYI(1, ("closedir free smb buf in srch struct")); |
574 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; | 575 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; |
575 | if(pCFileStruct->srch_inf.smallBuf) | 576 | if (pCFileStruct->srch_inf.smallBuf) |
576 | cifs_small_buf_release(ptmp); | 577 | cifs_small_buf_release(ptmp); |
577 | else | 578 | else |
578 | cifs_buf_release(ptmp); | 579 | cifs_buf_release(ptmp); |
@@ -594,7 +595,8 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
594 | static int store_file_lock(struct cifsFileInfo *fid, __u64 len, | 595 | static int store_file_lock(struct cifsFileInfo *fid, __u64 len, |
595 | __u64 offset, __u8 lockType) | 596 | __u64 offset, __u8 lockType) |
596 | { | 597 | { |
597 | struct cifsLockInfo *li = kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); | 598 | struct cifsLockInfo *li = |
599 | kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); | ||
598 | if (li == NULL) | 600 | if (li == NULL) |
599 | return -ENOMEM; | 601 | return -ENOMEM; |
600 | li->offset = offset; | 602 | li->offset = offset; |
@@ -625,8 +627,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
625 | 627 | ||
626 | cFYI(1, ("Lock parm: 0x%x flockflags: " | 628 | cFYI(1, ("Lock parm: 0x%x flockflags: " |
627 | "0x%x flocktype: 0x%x start: %lld end: %lld", | 629 | "0x%x flocktype: 0x%x start: %lld end: %lld", |
628 | cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, | 630 | cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, |
629 | pfLock->fl_end)); | 631 | pfLock->fl_end)); |
630 | 632 | ||
631 | if (pfLock->fl_flags & FL_POSIX) | 633 | if (pfLock->fl_flags & FL_POSIX) |
632 | cFYI(1, ("Posix")); | 634 | cFYI(1, ("Posix")); |
@@ -641,7 +643,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
641 | "not implemented yet")); | 643 | "not implemented yet")); |
642 | if (pfLock->fl_flags & FL_LEASE) | 644 | if (pfLock->fl_flags & FL_LEASE) |
643 | cFYI(1, ("Lease on file - not implemented yet")); | 645 | cFYI(1, ("Lease on file - not implemented yet")); |
644 | if (pfLock->fl_flags & | 646 | if (pfLock->fl_flags & |
645 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) | 647 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) |
646 | cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags)); | 648 | cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags)); |
647 | 649 | ||
@@ -683,9 +685,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
683 | account for negative length which we can not accept over the | 685 | account for negative length which we can not accept over the |
684 | wire */ | 686 | wire */ |
685 | if (IS_GETLK(cmd)) { | 687 | if (IS_GETLK(cmd)) { |
686 | if(posix_locking) { | 688 | if (posix_locking) { |
687 | int posix_lock_type; | 689 | int posix_lock_type; |
688 | if(lockType & LOCKING_ANDX_SHARED_LOCK) | 690 | if (lockType & LOCKING_ANDX_SHARED_LOCK) |
689 | posix_lock_type = CIFS_RDLCK; | 691 | posix_lock_type = CIFS_RDLCK; |
690 | else | 692 | else |
691 | posix_lock_type = CIFS_WRLCK; | 693 | posix_lock_type = CIFS_WRLCK; |
@@ -700,7 +702,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
700 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | 702 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, |
701 | 0, 1, lockType, 0 /* wait flag */ ); | 703 | 0, 1, lockType, 0 /* wait flag */ ); |
702 | if (rc == 0) { | 704 | if (rc == 0) { |
703 | rc = CIFSSMBLock(xid, pTcon, netfid, length, | 705 | rc = CIFSSMBLock(xid, pTcon, netfid, length, |
704 | pfLock->fl_start, 1 /* numUnlock */ , | 706 | pfLock->fl_start, 1 /* numUnlock */ , |
705 | 0 /* numLock */ , lockType, | 707 | 0 /* numLock */ , lockType, |
706 | 0 /* wait flag */ ); | 708 | 0 /* wait flag */ ); |
@@ -729,22 +731,24 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
729 | 731 | ||
730 | if (posix_locking) { | 732 | if (posix_locking) { |
731 | int posix_lock_type; | 733 | int posix_lock_type; |
732 | if(lockType & LOCKING_ANDX_SHARED_LOCK) | 734 | if (lockType & LOCKING_ANDX_SHARED_LOCK) |
733 | posix_lock_type = CIFS_RDLCK; | 735 | posix_lock_type = CIFS_RDLCK; |
734 | else | 736 | else |
735 | posix_lock_type = CIFS_WRLCK; | 737 | posix_lock_type = CIFS_WRLCK; |
736 | 738 | ||
737 | if(numUnlock == 1) | 739 | if (numUnlock == 1) |
738 | posix_lock_type = CIFS_UNLCK; | 740 | posix_lock_type = CIFS_UNLCK; |
739 | 741 | ||
740 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, | 742 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, |
741 | length, pfLock, | 743 | length, pfLock, |
742 | posix_lock_type, wait_flag); | 744 | posix_lock_type, wait_flag); |
743 | } else { | 745 | } else { |
744 | struct cifsFileInfo *fid = (struct cifsFileInfo *)file->private_data; | 746 | struct cifsFileInfo *fid = |
747 | (struct cifsFileInfo *)file->private_data; | ||
745 | 748 | ||
746 | if (numLock) { | 749 | if (numLock) { |
747 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | 750 | rc = CIFSSMBLock(xid, pTcon, netfid, length, |
751 | pfLock->fl_start, | ||
748 | 0, numLock, lockType, wait_flag); | 752 | 0, numLock, lockType, wait_flag); |
749 | 753 | ||
750 | if (rc == 0) { | 754 | if (rc == 0) { |
@@ -763,7 +767,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
763 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { | 767 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { |
764 | if (pfLock->fl_start <= li->offset && | 768 | if (pfLock->fl_start <= li->offset && |
765 | length >= li->length) { | 769 | length >= li->length) { |
766 | stored_rc = CIFSSMBLock(xid, pTcon, netfid, | 770 | stored_rc = CIFSSMBLock(xid, pTcon, |
771 | netfid, | ||
767 | li->length, li->offset, | 772 | li->length, li->offset, |
768 | 1, 0, li->type, FALSE); | 773 | 1, 0, li->type, FALSE); |
769 | if (stored_rc) | 774 | if (stored_rc) |
@@ -824,7 +829,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
824 | and blocked, and the file has been freed on us while | 829 | and blocked, and the file has been freed on us while |
825 | we blocked so return what we managed to write */ | 830 | we blocked so return what we managed to write */ |
826 | return total_written; | 831 | return total_written; |
827 | } | 832 | } |
828 | if (open_file->closePend) { | 833 | if (open_file->closePend) { |
829 | FreeXid(xid); | 834 | FreeXid(xid); |
830 | if (total_written) | 835 | if (total_written) |
@@ -867,8 +872,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
867 | /* since the write may have blocked check these pointers again */ | 872 | /* since the write may have blocked check these pointers again */ |
868 | if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { | 873 | if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { |
869 | struct inode *inode = file->f_path.dentry->d_inode; | 874 | struct inode *inode = file->f_path.dentry->d_inode; |
870 | /* Do not update local mtime - server will set its actual value on write | 875 | /* Do not update local mtime - server will set its actual value on write |
871 | * inode->i_ctime = inode->i_mtime = | 876 | * inode->i_ctime = inode->i_mtime = |
872 | * current_fs_time(inode->i_sb);*/ | 877 | * current_fs_time(inode->i_sb);*/ |
873 | if (total_written > 0) { | 878 | if (total_written > 0) { |
874 | spin_lock(&inode->i_lock); | 879 | spin_lock(&inode->i_lock); |
@@ -877,7 +882,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
877 | *poffset); | 882 | *poffset); |
878 | spin_unlock(&inode->i_lock); | 883 | spin_unlock(&inode->i_lock); |
879 | } | 884 | } |
880 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); | 885 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); |
881 | } | 886 | } |
882 | FreeXid(xid); | 887 | FreeXid(xid); |
883 | return total_written; | 888 | return total_written; |
@@ -898,7 +903,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
898 | 903 | ||
899 | pTcon = cifs_sb->tcon; | 904 | pTcon = cifs_sb->tcon; |
900 | 905 | ||
901 | cFYI(1,("write %zd bytes to offset %lld of %s", write_size, | 906 | cFYI(1, ("write %zd bytes to offset %lld of %s", write_size, |
902 | *poffset, file->f_path.dentry->d_name.name)); | 907 | *poffset, file->f_path.dentry->d_name.name)); |
903 | 908 | ||
904 | if (file->private_data == NULL) | 909 | if (file->private_data == NULL) |
@@ -921,10 +926,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
921 | FreeXid(xid); | 926 | FreeXid(xid); |
922 | /* if we have gotten here we have written some data | 927 | /* if we have gotten here we have written some data |
923 | and blocked, and the file has been freed on us | 928 | and blocked, and the file has been freed on us |
924 | while we blocked so return what we managed to | 929 | while we blocked so return what we managed to |
925 | write */ | 930 | write */ |
926 | return total_written; | 931 | return total_written; |
927 | } | 932 | } |
928 | if (open_file->closePend) { | 933 | if (open_file->closePend) { |
929 | FreeXid(xid); | 934 | FreeXid(xid); |
930 | if (total_written) | 935 | if (total_written) |
@@ -935,14 +940,14 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
935 | if (open_file->invalidHandle) { | 940 | if (open_file->invalidHandle) { |
936 | /* we could deadlock if we called | 941 | /* we could deadlock if we called |
937 | filemap_fdatawait from here so tell | 942 | filemap_fdatawait from here so tell |
938 | reopen_file not to flush data to | 943 | reopen_file not to flush data to |
939 | server now */ | 944 | server now */ |
940 | rc = cifs_reopen_file(file, FALSE); | 945 | rc = cifs_reopen_file(file, FALSE); |
941 | if (rc != 0) | 946 | if (rc != 0) |
942 | break; | 947 | break; |
943 | } | 948 | } |
944 | if(experimEnabled || (pTcon->ses->server && | 949 | if (experimEnabled || (pTcon->ses->server && |
945 | ((pTcon->ses->server->secMode & | 950 | ((pTcon->ses->server->secMode & |
946 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 951 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
947 | == 0))) { | 952 | == 0))) { |
948 | struct kvec iov[2]; | 953 | struct kvec iov[2]; |
@@ -976,7 +981,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
976 | } | 981 | } |
977 | } else | 982 | } else |
978 | *poffset += bytes_written; | 983 | *poffset += bytes_written; |
979 | long_op = FALSE; /* subsequent writes fast - | 984 | long_op = FALSE; /* subsequent writes fast - |
980 | 15 seconds is plenty */ | 985 | 15 seconds is plenty */ |
981 | } | 986 | } |
982 | 987 | ||
@@ -1009,8 +1014,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1009 | the VFS or MM) should not happen but we had reports of on oops (due to | 1014 | the VFS or MM) should not happen but we had reports of on oops (due to |
1010 | it being zero) during stress testcases so we need to check for it */ | 1015 | it being zero) during stress testcases so we need to check for it */ |
1011 | 1016 | ||
1012 | if(cifs_inode == NULL) { | 1017 | if (cifs_inode == NULL) { |
1013 | cERROR(1,("Null inode passed to cifs_writeable_file")); | 1018 | cERROR(1, ("Null inode passed to cifs_writeable_file")); |
1014 | dump_stack(); | 1019 | dump_stack(); |
1015 | return NULL; | 1020 | return NULL; |
1016 | } | 1021 | } |
@@ -1024,13 +1029,13 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1024 | (open_file->pfile->f_flags & O_WRONLY))) { | 1029 | (open_file->pfile->f_flags & O_WRONLY))) { |
1025 | atomic_inc(&open_file->wrtPending); | 1030 | atomic_inc(&open_file->wrtPending); |
1026 | read_unlock(&GlobalSMBSeslock); | 1031 | read_unlock(&GlobalSMBSeslock); |
1027 | if((open_file->invalidHandle) && | 1032 | if ((open_file->invalidHandle) && |
1028 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { | 1033 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { |
1029 | rc = cifs_reopen_file(open_file->pfile, FALSE); | 1034 | rc = cifs_reopen_file(open_file->pfile, FALSE); |
1030 | /* if it fails, try another handle - might be */ | 1035 | /* if it fails, try another handle - might be */ |
1031 | /* dangerous to hold up writepages with retry */ | 1036 | /* dangerous to hold up writepages with retry */ |
1032 | if(rc) { | 1037 | if (rc) { |
1033 | cFYI(1,("failed on reopen file in wp")); | 1038 | cFYI(1, ("failed on reopen file in wp")); |
1034 | read_lock(&GlobalSMBSeslock); | 1039 | read_lock(&GlobalSMBSeslock); |
1035 | /* can not use this handle, no write | 1040 | /* can not use this handle, no write |
1036 | pending on this one after all */ | 1041 | pending on this one after all */ |
@@ -1082,7 +1087,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1082 | 1087 | ||
1083 | /* check to make sure that we are not extending the file */ | 1088 | /* check to make sure that we are not extending the file */ |
1084 | if (mapping->host->i_size - offset < (loff_t)to) | 1089 | if (mapping->host->i_size - offset < (loff_t)to) |
1085 | to = (unsigned)(mapping->host->i_size - offset); | 1090 | to = (unsigned)(mapping->host->i_size - offset); |
1086 | 1091 | ||
1087 | open_file = find_writable_file(CIFS_I(mapping->host)); | 1092 | open_file = find_writable_file(CIFS_I(mapping->host)); |
1088 | if (open_file) { | 1093 | if (open_file) { |
@@ -1116,8 +1121,8 @@ static int cifs_writepages(struct address_space *mapping, | |||
1116 | int done = 0; | 1121 | int done = 0; |
1117 | pgoff_t end; | 1122 | pgoff_t end; |
1118 | pgoff_t index; | 1123 | pgoff_t index; |
1119 | int range_whole = 0; | 1124 | int range_whole = 0; |
1120 | struct kvec * iov; | 1125 | struct kvec *iov; |
1121 | int len; | 1126 | int len; |
1122 | int n_iov = 0; | 1127 | int n_iov = 0; |
1123 | pgoff_t next; | 1128 | pgoff_t next; |
@@ -1139,14 +1144,14 @@ static int cifs_writepages(struct address_space *mapping, | |||
1139 | if (cifs_sb->wsize < PAGE_CACHE_SIZE) | 1144 | if (cifs_sb->wsize < PAGE_CACHE_SIZE) |
1140 | return generic_writepages(mapping, wbc); | 1145 | return generic_writepages(mapping, wbc); |
1141 | 1146 | ||
1142 | if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) | 1147 | if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) |
1143 | if(cifs_sb->tcon->ses->server->secMode & | 1148 | if (cifs_sb->tcon->ses->server->secMode & |
1144 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 1149 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
1145 | if(!experimEnabled) | 1150 | if (!experimEnabled) |
1146 | return generic_writepages(mapping, wbc); | 1151 | return generic_writepages(mapping, wbc); |
1147 | 1152 | ||
1148 | iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); | 1153 | iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); |
1149 | if(iov == NULL) | 1154 | if (iov == NULL) |
1150 | return generic_writepages(mapping, wbc); | 1155 | return generic_writepages(mapping, wbc); |
1151 | 1156 | ||
1152 | 1157 | ||
@@ -1295,8 +1300,8 @@ retry: | |||
1295 | success rc but too little data written? */ | 1300 | success rc but too little data written? */ |
1296 | /* BB investigate retry logic on temporary | 1301 | /* BB investigate retry logic on temporary |
1297 | server crash cases and how recovery works | 1302 | server crash cases and how recovery works |
1298 | when page marked as error */ | 1303 | when page marked as error */ |
1299 | if(rc) | 1304 | if (rc) |
1300 | SetPageError(page); | 1305 | SetPageError(page); |
1301 | kunmap(page); | 1306 | kunmap(page); |
1302 | unlock_page(page); | 1307 | unlock_page(page); |
@@ -1326,7 +1331,7 @@ retry: | |||
1326 | return rc; | 1331 | return rc; |
1327 | } | 1332 | } |
1328 | 1333 | ||
1329 | static int cifs_writepage(struct page* page, struct writeback_control *wbc) | 1334 | static int cifs_writepage(struct page *page, struct writeback_control *wbc) |
1330 | { | 1335 | { |
1331 | int rc = -EFAULT; | 1336 | int rc = -EFAULT; |
1332 | int xid; | 1337 | int xid; |
@@ -1334,7 +1339,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc) | |||
1334 | xid = GetXid(); | 1339 | xid = GetXid(); |
1335 | /* BB add check for wbc flags */ | 1340 | /* BB add check for wbc flags */ |
1336 | page_cache_get(page); | 1341 | page_cache_get(page); |
1337 | if (!PageUptodate(page)) { | 1342 | if (!PageUptodate(page)) { |
1338 | cFYI(1, ("ppw - page not up to date")); | 1343 | cFYI(1, ("ppw - page not up to date")); |
1339 | } | 1344 | } |
1340 | 1345 | ||
@@ -1348,7 +1353,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc) | |||
1348 | * Just unlocking the page will cause the radix tree tag-bits | 1353 | * Just unlocking the page will cause the radix tree tag-bits |
1349 | * to fail to update with the state of the page correctly. | 1354 | * to fail to update with the state of the page correctly. |
1350 | */ | 1355 | */ |
1351 | set_page_writeback(page); | 1356 | set_page_writeback(page); |
1352 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); | 1357 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); |
1353 | SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ | 1358 | SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ |
1354 | unlock_page(page); | 1359 | unlock_page(page); |
@@ -1368,7 +1373,7 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
1368 | char *page_data; | 1373 | char *page_data; |
1369 | 1374 | ||
1370 | xid = GetXid(); | 1375 | xid = GetXid(); |
1371 | cFYI(1, ("commit write for page %p up to position %lld for %d", | 1376 | cFYI(1, ("commit write for page %p up to position %lld for %d", |
1372 | page, position, to)); | 1377 | page, position, to)); |
1373 | spin_lock(&inode->i_lock); | 1378 | spin_lock(&inode->i_lock); |
1374 | if (position > inode->i_size) { | 1379 | if (position > inode->i_size) { |
@@ -1396,7 +1401,7 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
1396 | rc = 0; | 1401 | rc = 0; |
1397 | /* else if (rc < 0) should we set writebehind rc? */ | 1402 | /* else if (rc < 0) should we set writebehind rc? */ |
1398 | kunmap(page); | 1403 | kunmap(page); |
1399 | } else { | 1404 | } else { |
1400 | set_page_dirty(page); | 1405 | set_page_dirty(page); |
1401 | } | 1406 | } |
1402 | 1407 | ||
@@ -1412,7 +1417,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1412 | 1417 | ||
1413 | xid = GetXid(); | 1418 | xid = GetXid(); |
1414 | 1419 | ||
1415 | cFYI(1, ("Sync file - name: %s datasync: 0x%x", | 1420 | cFYI(1, ("Sync file - name: %s datasync: 0x%x", |
1416 | dentry->d_name.name, datasync)); | 1421 | dentry->d_name.name, datasync)); |
1417 | 1422 | ||
1418 | rc = filemap_fdatawrite(inode->i_mapping); | 1423 | rc = filemap_fdatawrite(inode->i_mapping); |
@@ -1438,7 +1443,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1438 | if (!inode) | 1443 | if (!inode) |
1439 | return; */ | 1444 | return; */ |
1440 | 1445 | ||
1441 | /* fill in rpages then | 1446 | /* fill in rpages then |
1442 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ | 1447 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ |
1443 | 1448 | ||
1444 | /* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); | 1449 | /* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); |
@@ -1456,7 +1461,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1456 | */ | 1461 | */ |
1457 | int cifs_flush(struct file *file, fl_owner_t id) | 1462 | int cifs_flush(struct file *file, fl_owner_t id) |
1458 | { | 1463 | { |
1459 | struct inode * inode = file->f_path.dentry->d_inode; | 1464 | struct inode *inode = file->f_path.dentry->d_inode; |
1460 | int rc = 0; | 1465 | int rc = 0; |
1461 | 1466 | ||
1462 | /* Rather than do the steps manually: | 1467 | /* Rather than do the steps manually: |
@@ -1472,7 +1477,7 @@ int cifs_flush(struct file *file, fl_owner_t id) | |||
1472 | if (!rc) /* reset wb rc if we were able to write out dirty pages */ | 1477 | if (!rc) /* reset wb rc if we were able to write out dirty pages */ |
1473 | CIFS_I(inode)->write_behind_rc = 0; | 1478 | CIFS_I(inode)->write_behind_rc = 0; |
1474 | 1479 | ||
1475 | cFYI(1, ("Flush inode %p file %p rc %d",inode,file,rc)); | 1480 | cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc)); |
1476 | 1481 | ||
1477 | return rc; | 1482 | return rc; |
1478 | } | 1483 | } |
@@ -1508,13 +1513,13 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1508 | for (total_read = 0, current_offset = read_data; | 1513 | for (total_read = 0, current_offset = read_data; |
1509 | read_size > total_read; | 1514 | read_size > total_read; |
1510 | total_read += bytes_read, current_offset += bytes_read) { | 1515 | total_read += bytes_read, current_offset += bytes_read) { |
1511 | current_read_size = min_t(const int, read_size - total_read, | 1516 | current_read_size = min_t(const int, read_size - total_read, |
1512 | cifs_sb->rsize); | 1517 | cifs_sb->rsize); |
1513 | rc = -EAGAIN; | 1518 | rc = -EAGAIN; |
1514 | smb_read_data = NULL; | 1519 | smb_read_data = NULL; |
1515 | while (rc == -EAGAIN) { | 1520 | while (rc == -EAGAIN) { |
1516 | int buf_type = CIFS_NO_BUFFER; | 1521 | int buf_type = CIFS_NO_BUFFER; |
1517 | if ((open_file->invalidHandle) && | 1522 | if ((open_file->invalidHandle) && |
1518 | (!open_file->closePend)) { | 1523 | (!open_file->closePend)) { |
1519 | rc = cifs_reopen_file(file, TRUE); | 1524 | rc = cifs_reopen_file(file, TRUE); |
1520 | if (rc != 0) | 1525 | if (rc != 0) |
@@ -1535,9 +1540,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1535 | rc = -EFAULT; | 1540 | rc = -EFAULT; |
1536 | } | 1541 | } |
1537 | 1542 | ||
1538 | if(buf_type == CIFS_SMALL_BUFFER) | 1543 | if (buf_type == CIFS_SMALL_BUFFER) |
1539 | cifs_small_buf_release(smb_read_data); | 1544 | cifs_small_buf_release(smb_read_data); |
1540 | else if(buf_type == CIFS_LARGE_BUFFER) | 1545 | else if (buf_type == CIFS_LARGE_BUFFER) |
1541 | cifs_buf_release(smb_read_data); | 1546 | cifs_buf_release(smb_read_data); |
1542 | smb_read_data = NULL; | 1547 | smb_read_data = NULL; |
1543 | } | 1548 | } |
@@ -1586,21 +1591,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1586 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1591 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1587 | cFYI(1, ("attempting read on write only file instance")); | 1592 | cFYI(1, ("attempting read on write only file instance")); |
1588 | 1593 | ||
1589 | for (total_read = 0, current_offset = read_data; | 1594 | for (total_read = 0, current_offset = read_data; |
1590 | read_size > total_read; | 1595 | read_size > total_read; |
1591 | total_read += bytes_read, current_offset += bytes_read) { | 1596 | total_read += bytes_read, current_offset += bytes_read) { |
1592 | current_read_size = min_t(const int, read_size - total_read, | 1597 | current_read_size = min_t(const int, read_size - total_read, |
1593 | cifs_sb->rsize); | 1598 | cifs_sb->rsize); |
1594 | /* For windows me and 9x we do not want to request more | 1599 | /* For windows me and 9x we do not want to request more |
1595 | than it negotiated since it will refuse the read then */ | 1600 | than it negotiated since it will refuse the read then */ |
1596 | if((pTcon->ses) && | 1601 | if ((pTcon->ses) && |
1597 | !(pTcon->ses->capabilities & CAP_LARGE_FILES)) { | 1602 | !(pTcon->ses->capabilities & CAP_LARGE_FILES)) { |
1598 | current_read_size = min_t(const int, current_read_size, | 1603 | current_read_size = min_t(const int, current_read_size, |
1599 | pTcon->ses->server->maxBuf - 128); | 1604 | pTcon->ses->server->maxBuf - 128); |
1600 | } | 1605 | } |
1601 | rc = -EAGAIN; | 1606 | rc = -EAGAIN; |
1602 | while (rc == -EAGAIN) { | 1607 | while (rc == -EAGAIN) { |
1603 | if ((open_file->invalidHandle) && | 1608 | if ((open_file->invalidHandle) && |
1604 | (!open_file->closePend)) { | 1609 | (!open_file->closePend)) { |
1605 | rc = cifs_reopen_file(file, TRUE); | 1610 | rc = cifs_reopen_file(file, TRUE); |
1606 | if (rc != 0) | 1611 | if (rc != 0) |
@@ -1646,7 +1651,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
1646 | } | 1651 | } |
1647 | 1652 | ||
1648 | 1653 | ||
1649 | static void cifs_copy_cache_pages(struct address_space *mapping, | 1654 | static void cifs_copy_cache_pages(struct address_space *mapping, |
1650 | struct list_head *pages, int bytes_read, char *data, | 1655 | struct list_head *pages, int bytes_read, char *data, |
1651 | struct pagevec *plru_pvec) | 1656 | struct pagevec *plru_pvec) |
1652 | { | 1657 | { |
@@ -1669,12 +1674,12 @@ static void cifs_copy_cache_pages(struct address_space *mapping, | |||
1669 | continue; | 1674 | continue; |
1670 | } | 1675 | } |
1671 | 1676 | ||
1672 | target = kmap_atomic(page,KM_USER0); | 1677 | target = kmap_atomic(page, KM_USER0); |
1673 | 1678 | ||
1674 | if (PAGE_CACHE_SIZE > bytes_read) { | 1679 | if (PAGE_CACHE_SIZE > bytes_read) { |
1675 | memcpy(target, data, bytes_read); | 1680 | memcpy(target, data, bytes_read); |
1676 | /* zero the tail end of this partial page */ | 1681 | /* zero the tail end of this partial page */ |
1677 | memset(target + bytes_read, 0, | 1682 | memset(target + bytes_read, 0, |
1678 | PAGE_CACHE_SIZE - bytes_read); | 1683 | PAGE_CACHE_SIZE - bytes_read); |
1679 | bytes_read = 0; | 1684 | bytes_read = 0; |
1680 | } else { | 1685 | } else { |
@@ -1703,7 +1708,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1703 | struct cifs_sb_info *cifs_sb; | 1708 | struct cifs_sb_info *cifs_sb; |
1704 | struct cifsTconInfo *pTcon; | 1709 | struct cifsTconInfo *pTcon; |
1705 | int bytes_read = 0; | 1710 | int bytes_read = 0; |
1706 | unsigned int read_size,i; | 1711 | unsigned int read_size, i; |
1707 | char *smb_read_data = NULL; | 1712 | char *smb_read_data = NULL; |
1708 | struct smb_com_read_rsp *pSMBr; | 1713 | struct smb_com_read_rsp *pSMBr; |
1709 | struct pagevec lru_pvec; | 1714 | struct pagevec lru_pvec; |
@@ -1721,8 +1726,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1721 | 1726 | ||
1722 | pagevec_init(&lru_pvec, 0); | 1727 | pagevec_init(&lru_pvec, 0); |
1723 | #ifdef CONFIG_CIFS_DEBUG2 | 1728 | #ifdef CONFIG_CIFS_DEBUG2 |
1724 | cFYI(1,("rpages: num pages %d", num_pages)); | 1729 | cFYI(1, ("rpages: num pages %d", num_pages)); |
1725 | #endif | 1730 | #endif |
1726 | for (i = 0; i < num_pages; ) { | 1731 | for (i = 0; i < num_pages; ) { |
1727 | unsigned contig_pages; | 1732 | unsigned contig_pages; |
1728 | struct page *tmp_page; | 1733 | struct page *tmp_page; |
@@ -1736,14 +1741,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1736 | 1741 | ||
1737 | /* count adjacent pages that we will read into */ | 1742 | /* count adjacent pages that we will read into */ |
1738 | contig_pages = 0; | 1743 | contig_pages = 0; |
1739 | expected_index = | 1744 | expected_index = |
1740 | list_entry(page_list->prev, struct page, lru)->index; | 1745 | list_entry(page_list->prev, struct page, lru)->index; |
1741 | list_for_each_entry_reverse(tmp_page,page_list,lru) { | 1746 | list_for_each_entry_reverse(tmp_page, page_list, lru) { |
1742 | if (tmp_page->index == expected_index) { | 1747 | if (tmp_page->index == expected_index) { |
1743 | contig_pages++; | 1748 | contig_pages++; |
1744 | expected_index++; | 1749 | expected_index++; |
1745 | } else | 1750 | } else |
1746 | break; | 1751 | break; |
1747 | } | 1752 | } |
1748 | if (contig_pages + i > num_pages) | 1753 | if (contig_pages + i > num_pages) |
1749 | contig_pages = num_pages - i; | 1754 | contig_pages = num_pages - i; |
@@ -1756,12 +1761,12 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1756 | read_size = min_t(const unsigned int, read_size, | 1761 | read_size = min_t(const unsigned int, read_size, |
1757 | cifs_sb->rsize & PAGE_CACHE_MASK); | 1762 | cifs_sb->rsize & PAGE_CACHE_MASK); |
1758 | #ifdef CONFIG_CIFS_DEBUG2 | 1763 | #ifdef CONFIG_CIFS_DEBUG2 |
1759 | cFYI(1,("rpages: read size 0x%x contiguous pages %d", | 1764 | cFYI(1, ("rpages: read size 0x%x contiguous pages %d", |
1760 | read_size, contig_pages)); | 1765 | read_size, contig_pages)); |
1761 | #endif | 1766 | #endif |
1762 | rc = -EAGAIN; | 1767 | rc = -EAGAIN; |
1763 | while (rc == -EAGAIN) { | 1768 | while (rc == -EAGAIN) { |
1764 | if ((open_file->invalidHandle) && | 1769 | if ((open_file->invalidHandle) && |
1765 | (!open_file->closePend)) { | 1770 | (!open_file->closePend)) { |
1766 | rc = cifs_reopen_file(file, TRUE); | 1771 | rc = cifs_reopen_file(file, TRUE); |
1767 | if (rc != 0) | 1772 | if (rc != 0) |
@@ -1774,11 +1779,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1774 | &bytes_read, &smb_read_data, | 1779 | &bytes_read, &smb_read_data, |
1775 | &buf_type); | 1780 | &buf_type); |
1776 | /* BB more RC checks ? */ | 1781 | /* BB more RC checks ? */ |
1777 | if (rc== -EAGAIN) { | 1782 | if (rc == -EAGAIN) { |
1778 | if (smb_read_data) { | 1783 | if (smb_read_data) { |
1779 | if(buf_type == CIFS_SMALL_BUFFER) | 1784 | if (buf_type == CIFS_SMALL_BUFFER) |
1780 | cifs_small_buf_release(smb_read_data); | 1785 | cifs_small_buf_release(smb_read_data); |
1781 | else if(buf_type == CIFS_LARGE_BUFFER) | 1786 | else if (buf_type == CIFS_LARGE_BUFFER) |
1782 | cifs_buf_release(smb_read_data); | 1787 | cifs_buf_release(smb_read_data); |
1783 | smb_read_data = NULL; | 1788 | smb_read_data = NULL; |
1784 | } | 1789 | } |
@@ -1799,10 +1804,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1799 | if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { | 1804 | if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { |
1800 | i++; /* account for partial page */ | 1805 | i++; /* account for partial page */ |
1801 | 1806 | ||
1802 | /* server copy of file can have smaller size | 1807 | /* server copy of file can have smaller size |
1803 | than client */ | 1808 | than client */ |
1804 | /* BB do we need to verify this common case ? | 1809 | /* BB do we need to verify this common case ? |
1805 | this case is ok - if we are at server EOF | 1810 | this case is ok - if we are at server EOF |
1806 | we will hit it on next read */ | 1811 | we will hit it on next read */ |
1807 | 1812 | ||
1808 | /* break; */ | 1813 | /* break; */ |
@@ -1811,14 +1816,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1811 | cFYI(1, ("No bytes read (%d) at offset %lld . " | 1816 | cFYI(1, ("No bytes read (%d) at offset %lld . " |
1812 | "Cleaning remaining pages from readahead list", | 1817 | "Cleaning remaining pages from readahead list", |
1813 | bytes_read, offset)); | 1818 | bytes_read, offset)); |
1814 | /* BB turn off caching and do new lookup on | 1819 | /* BB turn off caching and do new lookup on |
1815 | file size at server? */ | 1820 | file size at server? */ |
1816 | break; | 1821 | break; |
1817 | } | 1822 | } |
1818 | if (smb_read_data) { | 1823 | if (smb_read_data) { |
1819 | if(buf_type == CIFS_SMALL_BUFFER) | 1824 | if (buf_type == CIFS_SMALL_BUFFER) |
1820 | cifs_small_buf_release(smb_read_data); | 1825 | cifs_small_buf_release(smb_read_data); |
1821 | else if(buf_type == CIFS_LARGE_BUFFER) | 1826 | else if (buf_type == CIFS_LARGE_BUFFER) |
1822 | cifs_buf_release(smb_read_data); | 1827 | cifs_buf_release(smb_read_data); |
1823 | smb_read_data = NULL; | 1828 | smb_read_data = NULL; |
1824 | } | 1829 | } |
@@ -1829,12 +1834,12 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1829 | 1834 | ||
1830 | /* need to free smb_read_data buf before exit */ | 1835 | /* need to free smb_read_data buf before exit */ |
1831 | if (smb_read_data) { | 1836 | if (smb_read_data) { |
1832 | if(buf_type == CIFS_SMALL_BUFFER) | 1837 | if (buf_type == CIFS_SMALL_BUFFER) |
1833 | cifs_small_buf_release(smb_read_data); | 1838 | cifs_small_buf_release(smb_read_data); |
1834 | else if(buf_type == CIFS_LARGE_BUFFER) | 1839 | else if (buf_type == CIFS_LARGE_BUFFER) |
1835 | cifs_buf_release(smb_read_data); | 1840 | cifs_buf_release(smb_read_data); |
1836 | smb_read_data = NULL; | 1841 | smb_read_data = NULL; |
1837 | } | 1842 | } |
1838 | 1843 | ||
1839 | FreeXid(xid); | 1844 | FreeXid(xid); |
1840 | return rc; | 1845 | return rc; |
@@ -1849,26 +1854,26 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
1849 | page_cache_get(page); | 1854 | page_cache_get(page); |
1850 | read_data = kmap(page); | 1855 | read_data = kmap(page); |
1851 | /* for reads over a certain size could initiate async read ahead */ | 1856 | /* for reads over a certain size could initiate async read ahead */ |
1852 | 1857 | ||
1853 | rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset); | 1858 | rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset); |
1854 | 1859 | ||
1855 | if (rc < 0) | 1860 | if (rc < 0) |
1856 | goto io_error; | 1861 | goto io_error; |
1857 | else | 1862 | else |
1858 | cFYI(1, ("Bytes read %d",rc)); | 1863 | cFYI(1, ("Bytes read %d", rc)); |
1859 | 1864 | ||
1860 | file->f_path.dentry->d_inode->i_atime = | 1865 | file->f_path.dentry->d_inode->i_atime = |
1861 | current_fs_time(file->f_path.dentry->d_inode->i_sb); | 1866 | current_fs_time(file->f_path.dentry->d_inode->i_sb); |
1862 | 1867 | ||
1863 | if (PAGE_CACHE_SIZE > rc) | 1868 | if (PAGE_CACHE_SIZE > rc) |
1864 | memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); | 1869 | memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); |
1865 | 1870 | ||
1866 | flush_dcache_page(page); | 1871 | flush_dcache_page(page); |
1867 | SetPageUptodate(page); | 1872 | SetPageUptodate(page); |
1868 | rc = 0; | 1873 | rc = 0; |
1869 | 1874 | ||
1870 | io_error: | 1875 | io_error: |
1871 | kunmap(page); | 1876 | kunmap(page); |
1872 | page_cache_release(page); | 1877 | page_cache_release(page); |
1873 | return rc; | 1878 | return rc; |
1874 | } | 1879 | } |
@@ -1886,7 +1891,7 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
1886 | return -EBADF; | 1891 | return -EBADF; |
1887 | } | 1892 | } |
1888 | 1893 | ||
1889 | cFYI(1, ("readpage %p at offset %d 0x%x\n", | 1894 | cFYI(1, ("readpage %p at offset %d 0x%x\n", |
1890 | page, (int)offset, (int)offset)); | 1895 | page, (int)offset, (int)offset)); |
1891 | 1896 | ||
1892 | rc = cifs_readpage_worker(file, page, &offset); | 1897 | rc = cifs_readpage_worker(file, page, &offset); |
@@ -1900,7 +1905,7 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
1900 | /* We do not want to update the file size from server for inodes | 1905 | /* We do not want to update the file size from server for inodes |
1901 | open for write - to avoid races with writepage extending | 1906 | open for write - to avoid races with writepage extending |
1902 | the file - in the future we could consider allowing | 1907 | the file - in the future we could consider allowing |
1903 | refreshing the inode only on increases in the file size | 1908 | refreshing the inode only on increases in the file size |
1904 | but this is tricky to do without racing with writebehind | 1909 | but this is tricky to do without racing with writebehind |
1905 | page caching in the current Linux kernel design */ | 1910 | page caching in the current Linux kernel design */ |
1906 | int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) | 1911 | int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) |
@@ -1910,7 +1915,7 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) | |||
1910 | if (cifsInode) | 1915 | if (cifsInode) |
1911 | open_file = find_writable_file(cifsInode); | 1916 | open_file = find_writable_file(cifsInode); |
1912 | 1917 | ||
1913 | if(open_file) { | 1918 | if (open_file) { |
1914 | struct cifs_sb_info *cifs_sb; | 1919 | struct cifs_sb_info *cifs_sb; |
1915 | 1920 | ||
1916 | /* there is not actually a write pending so let | 1921 | /* there is not actually a write pending so let |
@@ -1920,12 +1925,12 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) | |||
1920 | 1925 | ||
1921 | cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); | 1926 | cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); |
1922 | if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { | 1927 | if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { |
1923 | /* since no page cache to corrupt on directio | 1928 | /* since no page cache to corrupt on directio |
1924 | we can change size safely */ | 1929 | we can change size safely */ |
1925 | return 1; | 1930 | return 1; |
1926 | } | 1931 | } |
1927 | 1932 | ||
1928 | if(i_size_read(&cifsInode->vfs_inode) < end_of_file) | 1933 | if (i_size_read(&cifsInode->vfs_inode) < end_of_file) |
1929 | return 1; | 1934 | return 1; |
1930 | 1935 | ||
1931 | return 0; | 1936 | return 0; |
@@ -1940,7 +1945,7 @@ static int cifs_prepare_write(struct file *file, struct page *page, | |||
1940 | loff_t i_size; | 1945 | loff_t i_size; |
1941 | loff_t offset; | 1946 | loff_t offset; |
1942 | 1947 | ||
1943 | cFYI(1, ("prepare write for page %p from %d to %d",page,from,to)); | 1948 | cFYI(1, ("prepare write for page %p from %d to %d", page, from, to)); |
1944 | if (PageUptodate(page)) | 1949 | if (PageUptodate(page)) |
1945 | return 0; | 1950 | return 0; |
1946 | 1951 | ||
@@ -1979,8 +1984,8 @@ static int cifs_prepare_write(struct file *file, struct page *page, | |||
1979 | this will be written out by commit_write so is fine */ | 1984 | this will be written out by commit_write so is fine */ |
1980 | } | 1985 | } |
1981 | 1986 | ||
1982 | /* we do not need to pass errors back | 1987 | /* we do not need to pass errors back |
1983 | e.g. if we do not have read access to the file | 1988 | e.g. if we do not have read access to the file |
1984 | because cifs_commit_write will do the right thing. -- shaggy */ | 1989 | because cifs_commit_write will do the right thing. -- shaggy */ |
1985 | 1990 | ||
1986 | return 0; | 1991 | return 0; |