aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c129
1 files changed, 35 insertions, 94 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 2d3275bedb5..b570530f97b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -48,7 +48,7 @@ static inline struct cifsFileInfo *cifs_init_private(
48 private_data->netfid = netfid; 48 private_data->netfid = netfid;
49 private_data->pid = current->tgid; 49 private_data->pid = current->tgid;
50 init_MUTEX(&private_data->fh_sem); 50 init_MUTEX(&private_data->fh_sem);
51 init_MUTEX(&private_data->lock_sem); 51 mutex_init(&private_data->lock_mutex);
52 INIT_LIST_HEAD(&private_data->llist); 52 INIT_LIST_HEAD(&private_data->llist);
53 private_data->pfile = file; /* needed for writepage */ 53 private_data->pfile = file; /* needed for writepage */
54 private_data->pInode = inode; 54 private_data->pInode = inode;
@@ -338,8 +338,7 @@ static int cifs_relock_file(struct cifsFileInfo *cifsFile)
338 return rc; 338 return rc;
339} 339}
340 340
341static int cifs_reopen_file(struct inode *inode, struct file *file, 341static int cifs_reopen_file(struct file *file, int can_flush)
342 int can_flush)
343{ 342{
344 int rc = -EACCES; 343 int rc = -EACCES;
345 int xid, oplock; 344 int xid, oplock;
@@ -347,13 +346,12 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
347 struct cifsTconInfo *pTcon; 346 struct cifsTconInfo *pTcon;
348 struct cifsFileInfo *pCifsFile; 347 struct cifsFileInfo *pCifsFile;
349 struct cifsInodeInfo *pCifsInode; 348 struct cifsInodeInfo *pCifsInode;
349 struct inode * inode;
350 char *full_path = NULL; 350 char *full_path = NULL;
351 int desiredAccess; 351 int desiredAccess;
352 int disposition = FILE_OPEN; 352 int disposition = FILE_OPEN;
353 __u16 netfid; 353 __u16 netfid;
354 354
355 if (inode == NULL)
356 return -EBADF;
357 if (file->private_data) { 355 if (file->private_data) {
358 pCifsFile = (struct cifsFileInfo *)file->private_data; 356 pCifsFile = (struct cifsFileInfo *)file->private_data;
359 } else 357 } else
@@ -368,25 +366,37 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
368 } 366 }
369 367
370 if (file->f_path.dentry == NULL) { 368 if (file->f_path.dentry == NULL) {
371 up(&pCifsFile->fh_sem); 369 cERROR(1, ("no valid name if dentry freed"));
372 cFYI(1, ("failed file reopen, no valid name if dentry freed")); 370 dump_stack();
373 FreeXid(xid); 371 rc = -EBADF;
374 return -EBADF; 372 goto reopen_error_exit;
375 } 373 }
374
375 inode = file->f_path.dentry->d_inode;
376 if(inode == NULL) {
377 cERROR(1, ("inode not valid"));
378 dump_stack();
379 rc = -EBADF;
380 goto reopen_error_exit;
381 }
382
376 cifs_sb = CIFS_SB(inode->i_sb); 383 cifs_sb = CIFS_SB(inode->i_sb);
377 pTcon = cifs_sb->tcon; 384 pTcon = cifs_sb->tcon;
385
378/* can not grab rename sem here because various ops, including 386/* can not grab rename sem here because various ops, including
379 those that already have the rename sem can end up causing writepage 387 those that already have the rename sem can end up causing writepage
380 to get called and if the server was down that means we end up here, 388 to get called and if the server was down that means we end up here,
381 and we can never tell if the caller already has the rename_sem */ 389 and we can never tell if the caller already has the rename_sem */
382 full_path = build_path_from_dentry(file->f_path.dentry); 390 full_path = build_path_from_dentry(file->f_path.dentry);
383 if (full_path == NULL) { 391 if (full_path == NULL) {
392 rc = -ENOMEM;
393reopen_error_exit:
384 up(&pCifsFile->fh_sem); 394 up(&pCifsFile->fh_sem);
385 FreeXid(xid); 395 FreeXid(xid);
386 return -ENOMEM; 396 return rc;
387 } 397 }
388 398
389 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", 399 cFYI(1, ("inode = 0x%p file flags 0x%x for %s",
390 inode, file->f_flags,full_path)); 400 inode, file->f_flags,full_path));
391 desiredAccess = cifs_convert_flags(file->f_flags); 401 desiredAccess = cifs_convert_flags(file->f_flags);
392 402
@@ -401,13 +411,6 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
401 and server version of file size can be stale. If we knew for sure 411 and server version of file size can be stale. If we knew for sure
402 that inode was not dirty locally we could do this */ 412 that inode was not dirty locally we could do this */
403 413
404/* buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
405 if (buf == 0) {
406 up(&pCifsFile->fh_sem);
407 kfree(full_path);
408 FreeXid(xid);
409 return -ENOMEM;
410 } */
411 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, 414 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
412 CREATE_NOT_DIR, &netfid, &oplock, NULL, 415 CREATE_NOT_DIR, &netfid, &oplock, NULL,
413 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 416 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -508,12 +511,12 @@ int cifs_close(struct inode *inode, struct file *file)
508 511
509 /* Delete any outstanding lock records. 512 /* Delete any outstanding lock records.
510 We'll lose them when the file is closed anyway. */ 513 We'll lose them when the file is closed anyway. */
511 down(&pSMBFile->lock_sem); 514 mutex_lock(&pSMBFile->lock_mutex);
512 list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) { 515 list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) {
513 list_del(&li->llist); 516 list_del(&li->llist);
514 kfree(li); 517 kfree(li);
515 } 518 }
516 up(&pSMBFile->lock_sem); 519 mutex_unlock(&pSMBFile->lock_mutex);
517 520
518 write_lock(&GlobalSMBSeslock); 521 write_lock(&GlobalSMBSeslock);
519 list_del(&pSMBFile->flist); 522 list_del(&pSMBFile->flist);
@@ -598,9 +601,9 @@ static int store_file_lock(struct cifsFileInfo *fid, __u64 len,
598 li->offset = offset; 601 li->offset = offset;
599 li->length = len; 602 li->length = len;
600 li->type = lockType; 603 li->type = lockType;
601 down(&fid->lock_sem); 604 mutex_lock(&fid->lock_mutex);
602 list_add(&li->llist, &fid->llist); 605 list_add(&li->llist, &fid->llist);
603 up(&fid->lock_sem); 606 mutex_unlock(&fid->lock_mutex);
604 return 0; 607 return 0;
605} 608}
606 609
@@ -757,7 +760,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
757 struct cifsLockInfo *li, *tmp; 760 struct cifsLockInfo *li, *tmp;
758 761
759 rc = 0; 762 rc = 0;
760 down(&fid->lock_sem); 763 mutex_lock(&fid->lock_mutex);
761 list_for_each_entry_safe(li, tmp, &fid->llist, llist) { 764 list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
762 if (pfLock->fl_start <= li->offset && 765 if (pfLock->fl_start <= li->offset &&
763 length >= li->length) { 766 length >= li->length) {
@@ -771,7 +774,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
771 kfree(li); 774 kfree(li);
772 } 775 }
773 } 776 }
774 up(&fid->lock_sem); 777 mutex_unlock(&fid->lock_mutex);
775 } 778 }
776 } 779 }
777 780
@@ -792,12 +795,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
792 int xid, long_op; 795 int xid, long_op;
793 struct cifsFileInfo *open_file; 796 struct cifsFileInfo *open_file;
794 797
795 if (file->f_path.dentry == NULL)
796 return -EBADF;
797
798 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 798 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
799 if (cifs_sb == NULL)
800 return -EBADF;
801 799
802 pTcon = cifs_sb->tcon; 800 pTcon = cifs_sb->tcon;
803 801
@@ -807,14 +805,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
807 805
808 if (file->private_data == NULL) 806 if (file->private_data == NULL)
809 return -EBADF; 807 return -EBADF;
810 else 808 open_file = (struct cifsFileInfo *) file->private_data;
811 open_file = (struct cifsFileInfo *) file->private_data;
812 809
813 xid = GetXid(); 810 xid = GetXid();
814 if (file->f_path.dentry->d_inode == NULL) {
815 FreeXid(xid);
816 return -EBADF;
817 }
818 811
819 if (*poffset > file->f_path.dentry->d_inode->i_size) 812 if (*poffset > file->f_path.dentry->d_inode->i_size)
820 long_op = 2; /* writes past end of file can take a long time */ 813 long_op = 2; /* writes past end of file can take a long time */
@@ -841,17 +834,11 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
841 return -EBADF; 834 return -EBADF;
842 } 835 }
843 if (open_file->invalidHandle) { 836 if (open_file->invalidHandle) {
844 if ((file->f_path.dentry == NULL) ||
845 (file->f_path.dentry->d_inode == NULL)) {
846 FreeXid(xid);
847 return total_written;
848 }
849 /* we could deadlock if we called 837 /* we could deadlock if we called
850 filemap_fdatawait from here so tell 838 filemap_fdatawait from here so tell
851 reopen_file not to flush data to server 839 reopen_file not to flush data to server
852 now */ 840 now */
853 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 841 rc = cifs_reopen_file(file, FALSE);
854 file, FALSE);
855 if (rc != 0) 842 if (rc != 0)
856 break; 843 break;
857 } 844 }
@@ -908,12 +895,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
908 int xid, long_op; 895 int xid, long_op;
909 struct cifsFileInfo *open_file; 896 struct cifsFileInfo *open_file;
910 897
911 if (file->f_path.dentry == NULL)
912 return -EBADF;
913
914 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 898 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
915 if (cifs_sb == NULL)
916 return -EBADF;
917 899
918 pTcon = cifs_sb->tcon; 900 pTcon = cifs_sb->tcon;
919 901
@@ -922,14 +904,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
922 904
923 if (file->private_data == NULL) 905 if (file->private_data == NULL)
924 return -EBADF; 906 return -EBADF;
925 else 907 open_file = (struct cifsFileInfo *)file->private_data;
926 open_file = (struct cifsFileInfo *)file->private_data;
927 908
928 xid = GetXid(); 909 xid = GetXid();
929 if (file->f_path.dentry->d_inode == NULL) {
930 FreeXid(xid);
931 return -EBADF;
932 }
933 910
934 if (*poffset > file->f_path.dentry->d_inode->i_size) 911 if (*poffset > file->f_path.dentry->d_inode->i_size)
935 long_op = 2; /* writes past end of file can take a long time */ 912 long_op = 2; /* writes past end of file can take a long time */
@@ -957,17 +934,11 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
957 return -EBADF; 934 return -EBADF;
958 } 935 }
959 if (open_file->invalidHandle) { 936 if (open_file->invalidHandle) {
960 if ((file->f_path.dentry == NULL) ||
961 (file->f_path.dentry->d_inode == NULL)) {
962 FreeXid(xid);
963 return total_written;
964 }
965 /* we could deadlock if we called 937 /* we could deadlock if we called
966 filemap_fdatawait from here so tell 938 filemap_fdatawait from here so tell
967 reopen_file not to flush data to 939 reopen_file not to flush data to
968 server now */ 940 server now */
969 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 941 rc = cifs_reopen_file(file, FALSE);
970 file, FALSE);
971 if (rc != 0) 942 if (rc != 0)
972 break; 943 break;
973 } 944 }
@@ -1056,8 +1027,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1056 read_unlock(&GlobalSMBSeslock); 1027 read_unlock(&GlobalSMBSeslock);
1057 if((open_file->invalidHandle) && 1028 if((open_file->invalidHandle) &&
1058 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { 1029 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
1059 rc = cifs_reopen_file(&cifs_inode->vfs_inode, 1030 rc = cifs_reopen_file(open_file->pfile, FALSE);
1060 open_file->pfile, FALSE);
1061 /* if it fails, try another handle - might be */ 1031 /* if it fails, try another handle - might be */
1062 /* dangerous to hold up writepages with retry */ 1032 /* dangerous to hold up writepages with retry */
1063 if(rc) { 1033 if(rc) {
@@ -1404,32 +1374,6 @@ static int cifs_commit_write(struct file *file, struct page *page,
1404 spin_lock(&inode->i_lock); 1374 spin_lock(&inode->i_lock);
1405 if (position > inode->i_size) { 1375 if (position > inode->i_size) {
1406 i_size_write(inode, position); 1376 i_size_write(inode, position);
1407 /* if (file->private_data == NULL) {
1408 rc = -EBADF;
1409 } else {
1410 open_file = (struct cifsFileInfo *)file->private_data;
1411 cifs_sb = CIFS_SB(inode->i_sb);
1412 rc = -EAGAIN;
1413 while (rc == -EAGAIN) {
1414 if ((open_file->invalidHandle) &&
1415 (!open_file->closePend)) {
1416 rc = cifs_reopen_file(
1417 file->f_path.dentry->d_inode, file);
1418 if (rc != 0)
1419 break;
1420 }
1421 if (!open_file->closePend) {
1422 rc = CIFSSMBSetFileSize(xid,
1423 cifs_sb->tcon, position,
1424 open_file->netfid,
1425 open_file->pid, FALSE);
1426 } else {
1427 rc = -EBADF;
1428 break;
1429 }
1430 }
1431 cFYI(1, (" SetEOF (commit write) rc = %d", rc));
1432 } */
1433 } 1377 }
1434 spin_unlock(&inode->i_lock); 1378 spin_unlock(&inode->i_lock);
1435 if (!PageUptodate(page)) { 1379 if (!PageUptodate(page)) {
@@ -1573,8 +1517,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1573 int buf_type = CIFS_NO_BUFFER; 1517 int buf_type = CIFS_NO_BUFFER;
1574 if ((open_file->invalidHandle) && 1518 if ((open_file->invalidHandle) &&
1575 (!open_file->closePend)) { 1519 (!open_file->closePend)) {
1576 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 1520 rc = cifs_reopen_file(file, TRUE);
1577 file, TRUE);
1578 if (rc != 0) 1521 if (rc != 0)
1579 break; 1522 break;
1580 } 1523 }
@@ -1660,8 +1603,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1660 while (rc == -EAGAIN) { 1603 while (rc == -EAGAIN) {
1661 if ((open_file->invalidHandle) && 1604 if ((open_file->invalidHandle) &&
1662 (!open_file->closePend)) { 1605 (!open_file->closePend)) {
1663 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 1606 rc = cifs_reopen_file(file, TRUE);
1664 file, TRUE);
1665 if (rc != 0) 1607 if (rc != 0)
1666 break; 1608 break;
1667 } 1609 }
@@ -1817,8 +1759,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1817 while (rc == -EAGAIN) { 1759 while (rc == -EAGAIN) {
1818 if ((open_file->invalidHandle) && 1760 if ((open_file->invalidHandle) &&
1819 (!open_file->closePend)) { 1761 (!open_file->closePend)) {
1820 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 1762 rc = cifs_reopen_file(file, TRUE);
1821 file, TRUE);
1822 if (rc != 0) 1763 if (rc != 0)
1823 break; 1764 break;
1824 } 1765 }