aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 15:00:58 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 15:00:58 -0400
commit2843483d2eb02ad104edbe8b2429fb6a39d25063 (patch)
tree7a63d1fa408ab50277666b2d73d2553ea4cfc7a7 /fs/cifs/inode.c
parent26790656d7dc34206f78eeca0f4be5caede788ce (diff)
parenta761ac579b89bc1f00212a42401398108deba65c (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.c52
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
578static const struct inode_operations cifs_ipc_inode_ops = {
579 .lookup = cifs_lookup,
580};
581
578/* gets root inode */ 582/* gets root inode */
579void cifs_read_inode(struct inode *inode) 583void 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 998mkdir_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
1384do_expand: 1416do_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,