diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 15:00:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 15:00:58 -0400 |
commit | 2843483d2eb02ad104edbe8b2429fb6a39d25063 (patch) | |
tree | 7a63d1fa408ab50277666b2d73d2553ea4cfc7a7 /fs/cifs/inode.c | |
parent | 26790656d7dc34206f78eeca0f4be5caede788ce (diff) | |
parent | a761ac579b89bc1f00212a42401398108deba65c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (51 commits)
[CIFS] log better errors on failed mounts
[CIFS] Return better error when server requires signing but client forbids
[CIFS] fix typo
[CIFS] acl support part 4
[CIFS] Fix minor problems noticed by scan
[CIFS] fix bad handling of EAGAIN error on kernel_recvmsg in cifs_demultiplex_thread
[CIFS] build break
[CIFS] endian fixes
[CIFS] endian fixes in new acl code
[CIFS] Fix some endianness problems in new acl code
[CIFS] missing #endif from a previous patch
[CIFS] formatting fixes
[CIFS] Break up unicode_sessetup string functions
[CIFS] parse server_GUID in SPNEGO negProt response
[CIFS]
[CIFS] Fix endian conversion problem in posix mkdir
[CIFS] fix build break when lanman not enabled
[CIFS] remove two sparse warnings
[CIFS] remove compile warnings when debug disabled
[CIFS] CIFS ACL support part 3
...
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 279f3c5e0ce3..5e8b388be3b6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
115 | inode->i_mode = le64_to_cpu(findData.Permissions); | 115 | inode->i_mode = le64_to_cpu(findData.Permissions); |
116 | /* since we set the inode type below we need to mask off | 116 | /* since we set the inode type below we need to mask off |
117 | to avoid strange results if bits set above */ | 117 | to avoid strange results if bits set above */ |
118 | inode->i_mode &= ~S_IFMT; | 118 | inode->i_mode &= ~S_IFMT; |
119 | if (type == UNIX_FILE) { | 119 | if (type == UNIX_FILE) { |
120 | inode->i_mode |= S_IFREG; | 120 | inode->i_mode |= S_IFREG; |
121 | } else if (type == UNIX_SYMLINK) { | 121 | } else if (type == UNIX_SYMLINK) { |
@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode, | |||
575 | return rc; | 575 | return rc; |
576 | } | 576 | } |
577 | 577 | ||
578 | static const struct inode_operations cifs_ipc_inode_ops = { | ||
579 | .lookup = cifs_lookup, | ||
580 | }; | ||
581 | |||
578 | /* gets root inode */ | 582 | /* gets root inode */ |
579 | void cifs_read_inode(struct inode *inode) | 583 | void cifs_read_inode(struct inode *inode) |
580 | { | 584 | { |
581 | int xid; | 585 | int xid, rc; |
582 | struct cifs_sb_info *cifs_sb; | 586 | struct cifs_sb_info *cifs_sb; |
583 | 587 | ||
584 | cifs_sb = CIFS_SB(inode->i_sb); | 588 | cifs_sb = CIFS_SB(inode->i_sb); |
585 | xid = GetXid(); | 589 | xid = GetXid(); |
586 | 590 | ||
587 | if (cifs_sb->tcon->unix_ext) | 591 | if (cifs_sb->tcon->unix_ext) |
588 | cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); | 592 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); |
589 | else | 593 | else |
590 | cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); | 594 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); |
595 | if (rc && cifs_sb->tcon->ipc) { | ||
596 | cFYI(1, ("ipc connection - fake read inode")); | ||
597 | inode->i_mode |= S_IFDIR; | ||
598 | inode->i_nlink = 2; | ||
599 | inode->i_op = &cifs_ipc_inode_ops; | ||
600 | inode->i_fop = &simple_dir_operations; | ||
601 | inode->i_uid = cifs_sb->mnt_uid; | ||
602 | inode->i_gid = cifs_sb->mnt_gid; | ||
603 | } | ||
604 | |||
591 | /* can not call macro FreeXid here since in a void func */ | 605 | /* can not call macro FreeXid here since in a void func */ |
592 | _FreeXid(xid); | 606 | _FreeXid(xid); |
593 | } | 607 | } |
@@ -919,18 +933,25 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
919 | goto mkdir_out; | 933 | goto mkdir_out; |
920 | } | 934 | } |
921 | 935 | ||
936 | mode &= ~current->fs->umask; | ||
922 | rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, | 937 | rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, |
923 | mode, NULL /* netfid */, pInfo, &oplock, | 938 | mode, NULL /* netfid */, pInfo, &oplock, |
924 | full_path, cifs_sb->local_nls, | 939 | full_path, cifs_sb->local_nls, |
925 | cifs_sb->mnt_cifs_flags & | 940 | cifs_sb->mnt_cifs_flags & |
926 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 941 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
927 | if (rc) { | 942 | if (rc == -EOPNOTSUPP) { |
943 | kfree(pInfo); | ||
944 | goto mkdir_retry_old; | ||
945 | } else if (rc) { | ||
928 | cFYI(1, ("posix mkdir returned 0x%x", rc)); | 946 | cFYI(1, ("posix mkdir returned 0x%x", rc)); |
929 | d_drop(direntry); | 947 | d_drop(direntry); |
930 | } else { | 948 | } else { |
931 | int obj_type; | 949 | int obj_type; |
932 | if (pInfo->Type == -1) /* no return info - go query */ | 950 | if (pInfo->Type == cpu_to_le32(-1)) { |
951 | /* no return info, go query for it */ | ||
952 | kfree(pInfo); | ||
933 | goto mkdir_get_info; | 953 | goto mkdir_get_info; |
954 | } | ||
934 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need | 955 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need |
935 | to set uid/gid */ | 956 | to set uid/gid */ |
936 | inc_nlink(inode); | 957 | inc_nlink(inode); |
@@ -940,8 +961,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
940 | direntry->d_op = &cifs_dentry_ops; | 961 | direntry->d_op = &cifs_dentry_ops; |
941 | 962 | ||
942 | newinode = new_inode(inode->i_sb); | 963 | newinode = new_inode(inode->i_sb); |
943 | if (newinode == NULL) | 964 | if (newinode == NULL) { |
965 | kfree(pInfo); | ||
944 | goto mkdir_get_info; | 966 | goto mkdir_get_info; |
967 | } | ||
945 | /* Is an i_ino of zero legal? */ | 968 | /* Is an i_ino of zero legal? */ |
946 | /* Are there sanity checks we can use to ensure that | 969 | /* Are there sanity checks we can use to ensure that |
947 | the server is really filling in that field? */ | 970 | the server is really filling in that field? */ |
@@ -972,7 +995,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
972 | kfree(pInfo); | 995 | kfree(pInfo); |
973 | goto mkdir_out; | 996 | goto mkdir_out; |
974 | } | 997 | } |
975 | 998 | mkdir_retry_old: | |
976 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ | 999 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ |
977 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, | 1000 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, |
978 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 1001 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -1377,8 +1400,17 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset) | |||
1377 | } | 1400 | } |
1378 | i_size_write(inode, offset); | 1401 | i_size_write(inode, offset); |
1379 | spin_unlock(&inode->i_lock); | 1402 | spin_unlock(&inode->i_lock); |
1403 | /* | ||
1404 | * unmap_mapping_range is called twice, first simply for efficiency | ||
1405 | * so that truncate_inode_pages does fewer single-page unmaps. However | ||
1406 | * after this first call, and before truncate_inode_pages finishes, | ||
1407 | * it is possible for private pages to be COWed, which remain after | ||
1408 | * truncate_inode_pages finishes, hence the second unmap_mapping_range | ||
1409 | * call must be made for correctness. | ||
1410 | */ | ||
1380 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | 1411 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); |
1381 | truncate_inode_pages(mapping, offset); | 1412 | truncate_inode_pages(mapping, offset); |
1413 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
1382 | goto out_truncate; | 1414 | goto out_truncate; |
1383 | 1415 | ||
1384 | do_expand: | 1416 | do_expand: |
@@ -1469,7 +1501,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1469 | atomic_dec(&open_file->wrtPending); | 1501 | atomic_dec(&open_file->wrtPending); |
1470 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); | 1502 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); |
1471 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | 1503 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
1472 | int bytes_written; | 1504 | unsigned int bytes_written; |
1473 | rc = CIFSSMBWrite(xid, pTcon, | 1505 | rc = CIFSSMBWrite(xid, pTcon, |
1474 | nfid, 0, attrs->ia_size, | 1506 | nfid, 0, attrs->ia_size, |
1475 | &bytes_written, NULL, NULL, | 1507 | &bytes_written, NULL, NULL, |
@@ -1502,7 +1534,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1502 | cifs_sb->mnt_cifs_flags & | 1534 | cifs_sb->mnt_cifs_flags & |
1503 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1535 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1504 | if (rc == 0) { | 1536 | if (rc == 0) { |
1505 | int bytes_written; | 1537 | unsigned int bytes_written; |
1506 | rc = CIFSSMBWrite(xid, pTcon, | 1538 | rc = CIFSSMBWrite(xid, pTcon, |
1507 | netfid, 0, | 1539 | netfid, 0, |
1508 | attrs->ia_size, | 1540 | attrs->ia_size, |