Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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:
[CIFS] statfs for cifs unix extensions no longer experimental
[CIFS] New POSIX locking code not setting rc properly to zero on successful
[CIFS] Support deep tree mounts (e.g. mounts to //server/share/path)

+76 -14
+6 -1
fs/cifs/CHANGES
··· 1 + Version 1.46 2 + ------------ 3 + Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. 4 + 1 5 Version 1.45 2 6 ------------ 3 7 Do not time out lockw calls when using posix extensions. Do not ··· 10 6 (lock cancel now works, and unlock of merged range works even 11 7 to Windows servers now). Fix oops on mount to lanman servers 12 8 (win9x, os/2 etc.) when null password. Do not send listxattr 13 - (SMB to query all EAs) if nouser_xattr specified. 9 + (SMB to query all EAs) if nouser_xattr specified. Fix SE Linux 10 + problem (instantiate inodes/dentries in right order for readdir). 14 11 15 12 Version 1.44 16 13 ------------
+2
fs/cifs/cifs_fs_sb.h
··· 40 40 mode_t mnt_file_mode; 41 41 mode_t mnt_dir_mode; 42 42 int mnt_cifs_flags; 43 + int prepathlen; 44 + char * prepath; 43 45 }; 44 46 #endif /* _CIFS_FS_SB_H */
-2
fs/cifs/cifsfs.c
··· 189 189 buf->f_files = 0; /* undefined */ 190 190 buf->f_ffree = 0; /* unlimited */ 191 191 192 - #ifdef CONFIG_CIFS_EXPERIMENTAL 193 192 /* BB we could add a second check for a QFS Unix capability bit */ 194 193 /* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */ 195 194 if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS & ··· 198 199 /* Only need to call the old QFSInfo if failed 199 200 on newer one */ 200 201 if(rc) 201 - #endif /* CIFS_EXPERIMENTAL */ 202 202 rc = CIFSSMBQFSInfo(xid, pTcon, buf); 203 203 204 204 /* Old Windows servers do not support level 103, retry with level
+1 -1
fs/cifs/cifsfs.h
··· 100 100 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 101 101 extern int cifs_ioctl (struct inode * inode, struct file * filep, 102 102 unsigned int command, unsigned long arg); 103 - #define CIFS_VERSION "1.45" 103 + #define CIFS_VERSION "1.46" 104 104 #endif /* _CIFSFS_H */
+2
fs/cifs/cifspdu.h
··· 1344 1344 #define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ 1345 1345 #define SMB_QUERY_POSIX_PERMISSION 0x207 1346 1346 #define SMB_QUERY_POSIX_LOCK 0x208 1347 + /* #define SMB_POSIX_OPEN 0x209 */ 1347 1348 #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee 1348 1349 #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 1349 1350 #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ ··· 1364 1363 #define SMB_SET_XATTR 0x205 1365 1364 #define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ 1366 1365 #define SMB_SET_POSIX_LOCK 0x208 1366 + #define SMB_POSIX_OPEN 0x209 1367 1367 #define SMB_SET_FILE_BASIC_INFO2 0x3ec 1368 1368 #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ 1369 1369 #define SMB_FILE_ALL_INFO2 0x3fa
+47
fs/cifs/connect.c
··· 89 89 unsigned int wsize; 90 90 unsigned int sockopt; 91 91 unsigned short int port; 92 + char * prepath; 92 93 }; 93 94 94 95 static int ipv4_connect(struct sockaddr_in *psin_server, ··· 994 993 printk(KERN_WARNING "CIFS: domain name too long\n"); 995 994 return 1; 996 995 } 996 + } else if (strnicmp(data, "prefixpath", 10) == 0) { 997 + if (!value || !*value) { 998 + printk(KERN_WARNING 999 + "CIFS: invalid path prefix\n"); 1000 + return 1; /* needs_arg; */ 1001 + } 1002 + if ((temp_len = strnlen(value, 1024)) < 1024) { 1003 + if(value[0] != '/') 1004 + temp_len++; /* missing leading slash */ 1005 + vol->prepath = kmalloc(temp_len+1,GFP_KERNEL); 1006 + if(vol->prepath == NULL) 1007 + return 1; 1008 + if(value[0] != '/') { 1009 + vol->prepath[0] = '/'; 1010 + strcpy(vol->prepath+1,value); 1011 + } else 1012 + strcpy(vol->prepath,value); 1013 + cFYI(1,("prefix path %s",vol->prepath)); 1014 + } else { 1015 + printk(KERN_WARNING "CIFS: prefix too long\n"); 1016 + return 1; 1017 + } 997 1018 } else if (strnicmp(data, "iocharset", 9) == 0) { 998 1019 if (!value || !*value) { 999 1020 printk(KERN_WARNING "CIFS: invalid iocharset specified\n"); ··· 1628 1605 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { 1629 1606 kfree(volume_info.UNC); 1630 1607 kfree(volume_info.password); 1608 + kfree(volume_info.prepath); 1631 1609 FreeXid(xid); 1632 1610 return -EINVAL; 1633 1611 } ··· 1643 1619 locations such as env variables and files on disk */ 1644 1620 kfree(volume_info.UNC); 1645 1621 kfree(volume_info.password); 1622 + kfree(volume_info.prepath); 1646 1623 FreeXid(xid); 1647 1624 return -EINVAL; 1648 1625 } ··· 1664 1639 /* we failed translating address */ 1665 1640 kfree(volume_info.UNC); 1666 1641 kfree(volume_info.password); 1642 + kfree(volume_info.prepath); 1667 1643 FreeXid(xid); 1668 1644 return -EINVAL; 1669 1645 } ··· 1677 1651 cERROR(1,("Connecting to DFS root not implemented yet")); 1678 1652 kfree(volume_info.UNC); 1679 1653 kfree(volume_info.password); 1654 + kfree(volume_info.prepath); 1680 1655 FreeXid(xid); 1681 1656 return -EINVAL; 1682 1657 } else /* which servers DFS root would we conect to */ { ··· 1685 1658 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); 1686 1659 kfree(volume_info.UNC); 1687 1660 kfree(volume_info.password); 1661 + kfree(volume_info.prepath); 1688 1662 FreeXid(xid); 1689 1663 return -EINVAL; 1690 1664 } ··· 1700 1672 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset)); 1701 1673 kfree(volume_info.UNC); 1702 1674 kfree(volume_info.password); 1675 + kfree(volume_info.prepath); 1703 1676 FreeXid(xid); 1704 1677 return -ELIBACC; 1705 1678 } ··· 1717 1688 else { 1718 1689 kfree(volume_info.UNC); 1719 1690 kfree(volume_info.password); 1691 + kfree(volume_info.prepath); 1720 1692 FreeXid(xid); 1721 1693 return -EINVAL; 1722 1694 } ··· 1740 1710 sock_release(csocket); 1741 1711 kfree(volume_info.UNC); 1742 1712 kfree(volume_info.password); 1713 + kfree(volume_info.prepath); 1743 1714 FreeXid(xid); 1744 1715 return rc; 1745 1716 } ··· 1751 1720 sock_release(csocket); 1752 1721 kfree(volume_info.UNC); 1753 1722 kfree(volume_info.password); 1723 + kfree(volume_info.prepath); 1754 1724 FreeXid(xid); 1755 1725 return rc; 1756 1726 } else { ··· 1776 1744 sock_release(csocket); 1777 1745 kfree(volume_info.UNC); 1778 1746 kfree(volume_info.password); 1747 + kfree(volume_info.prepath); 1779 1748 FreeXid(xid); 1780 1749 return rc; 1781 1750 } ··· 1864 1831 /* Windows ME may prefer this */ 1865 1832 cFYI(1,("readsize set to minimum 2048")); 1866 1833 } 1834 + /* calculate prepath */ 1835 + cifs_sb->prepath = volume_info.prepath; 1836 + if(cifs_sb->prepath) { 1837 + cifs_sb->prepathlen = strlen(cifs_sb->prepath); 1838 + cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); 1839 + volume_info.prepath = NULL; 1840 + } else 1841 + cifs_sb->prepathlen = 0; 1867 1842 cifs_sb->mnt_uid = volume_info.linux_uid; 1868 1843 cifs_sb->mnt_gid = volume_info.linux_gid; 1869 1844 cifs_sb->mnt_file_mode = volume_info.file_mode; ··· 2049 2008 the password ptr is put in the new session structure (in which case the 2050 2009 password will be freed at unmount time) */ 2051 2010 kfree(volume_info.UNC); 2011 + kfree(volume_info.prepath); 2052 2012 FreeXid(xid); 2053 2013 return rc; 2054 2014 } ··· 3237 3195 int xid; 3238 3196 struct cifsSesInfo *ses = NULL; 3239 3197 struct task_struct *cifsd_task; 3198 + char * tmp; 3240 3199 3241 3200 xid = GetXid(); 3242 3201 ··· 3271 3228 } 3272 3229 3273 3230 cifs_sb->tcon = NULL; 3231 + tmp = cifs_sb->prepath; 3232 + cifs_sb->prepathlen = 0; 3233 + cifs_sb->prepath = NULL; 3234 + kfree(tmp); 3274 3235 if (ses) 3275 3236 schedule_timeout_interruptible(msecs_to_jiffies(500)); 3276 3237 if (ses)
+15 -8
fs/cifs/dir.c
··· 46 46 build_path_from_dentry(struct dentry *direntry) 47 47 { 48 48 struct dentry *temp; 49 - int namelen = 0; 49 + int namelen; 50 + int pplen; 50 51 char *full_path; 51 52 char dirsep; 52 53 ··· 57 56 when the server crashed */ 58 57 59 58 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 59 + pplen = CIFS_SB(direntry->d_sb)->prepathlen; 60 60 cifs_bp_rename_retry: 61 + namelen = pplen; 61 62 for (temp = direntry; !IS_ROOT(temp);) { 62 63 namelen += (1 + temp->d_name.len); 63 64 temp = temp->d_parent; ··· 73 70 if(full_path == NULL) 74 71 return full_path; 75 72 full_path[namelen] = 0; /* trailing null */ 76 - 77 73 for (temp = direntry; !IS_ROOT(temp);) { 78 74 namelen -= 1 + temp->d_name.len; 79 75 if (namelen < 0) { ··· 81 79 full_path[namelen] = dirsep; 82 80 strncpy(full_path + namelen + 1, temp->d_name.name, 83 81 temp->d_name.len); 84 - cFYI(0, (" name: %s ", full_path + namelen)); 82 + cFYI(0, ("name: %s", full_path + namelen)); 85 83 } 86 84 temp = temp->d_parent; 87 85 if(temp == NULL) { ··· 90 88 return NULL; 91 89 } 92 90 } 93 - if (namelen != 0) { 91 + if (namelen != pplen) { 94 92 cERROR(1, 95 - ("We did not end path lookup where we expected namelen is %d", 93 + ("did not end path lookup where expected namelen is %d", 96 94 namelen)); 97 - /* presumably this is only possible if we were racing with a rename 95 + /* presumably this is only possible if racing with a rename 98 96 of one of the parent directories (we can not lock the dentries 99 97 above us to prevent this, but retrying should be harmless) */ 100 98 kfree(full_path); 101 - namelen = 0; 102 99 goto cifs_bp_rename_retry; 103 100 } 104 - 101 + /* DIR_SEP already set for byte 0 / vs \ but not for 102 + subsequent slashes in prepath which currently must 103 + be entered the right way - not sure if there is an alternative 104 + since the '\' is a valid posix character so we can not switch 105 + those safely to '/' if any are found in the middle of the prepath */ 106 + /* BB test paths to Windows with '/' in the midst of prepath */ 107 + strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen); 105 108 return full_path; 106 109 } 107 110
+2 -1
fs/cifs/file.c
··· 752 752 int stored_rc = 0; 753 753 struct cifsLockInfo *li, *tmp; 754 754 755 + rc = 0; 755 756 down(&fid->lock_sem); 756 757 list_for_each_entry_safe(li, tmp, &fid->llist, llist) { 757 758 if (pfLock->fl_start <= li->offset && ··· 767 766 kfree(li); 768 767 } 769 768 } 770 - up(&fid->lock_sem); 769 + up(&fid->lock_sem); 771 770 } 772 771 } 773 772
+1 -1
fs/cifs/xattr.c
··· 269 269 rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, 270 270 ea_value, buf_size, 271 271 ACL_TYPE_ACCESS); 272 - CIFSSMBClose(xid, pTcon, fid) 272 + CIFSSMBClose(xid, pTcon, fid); 273 273 } 274 274 } */ /* BB enable after fixing up return data */ 275 275