diff options
| -rw-r--r-- | fs/cifs/CHANGES | 5 | ||||
| -rw-r--r-- | fs/cifs/README | 25 | ||||
| -rw-r--r-- | fs/cifs/TODO | 6 | ||||
| -rw-r--r-- | fs/cifs/cifspdu.h | 11 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 53 | ||||
| -rw-r--r-- | fs/cifs/file.c | 9 |
6 files changed, 80 insertions, 29 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index a9b6bc5157b8..b4d388d2b524 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -8,7 +8,10 @@ when Unix Extensions were ignored). This allows users to override the | |||
| 8 | default uid and gid for files when they are certain that the uids or | 8 | default uid and gid for files when they are certain that the uids or |
| 9 | gids on the server do not match those of the client. Make "sec=none" | 9 | gids on the server do not match those of the client. Make "sec=none" |
| 10 | mount override username (so that null user connection is attempted) | 10 | mount override username (so that null user connection is attempted) |
| 11 | to match what documentation said. | 11 | to match what documentation said. Support for very large reads, over 127K, |
| 12 | available to some newer servers (such as Samba 3.0.26 and later but | ||
| 13 | note that it also requires setting CIFSMaxBufSize at module install | ||
| 14 | time to a larger value which may hurt performance in some cases). | ||
| 12 | 15 | ||
| 13 | Version 1.48 | 16 | Version 1.48 |
| 14 | ------------ | 17 | ------------ |
diff --git a/fs/cifs/README b/fs/cifs/README index 4d01697722cc..eb3efd5a6a81 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
| @@ -301,10 +301,21 @@ A partial list of the supported mount options follows: | |||
| 301 | during the local client kernel build will be used. | 301 | during the local client kernel build will be used. |
| 302 | If server does not support Unicode, this parameter is | 302 | If server does not support Unicode, this parameter is |
| 303 | unused. | 303 | unused. |
| 304 | rsize default read size (usually 16K) | 304 | rsize default read size (usually 16K). The client currently |
| 305 | wsize default write size (usually 16K, 32K is often better over GigE) | 305 | can not use rsize larger than CIFSMaxBufSize. CIFSMaxBufSize |
| 306 | maximum wsize currently allowed by CIFS is 57344 (14 4096 byte | 306 | defaults to 16K and may be changed (from 8K to the maximum |
| 307 | pages) | 307 | kmalloc size allowed by your kernel) at module install time |
| 308 | for cifs.ko. Setting CIFSMaxBufSize to a very large value | ||
| 309 | will cause cifs to use more memory and may reduce performance | ||
| 310 | in some cases. To use rsize greater than 127K (the original | ||
| 311 | cifs protocol maximum) also requires that the server support | ||
| 312 | a new Unix Capability flag (for very large read) which some | ||
| 313 | newer servers (e.g. Samba 3.0.26 or later) do. rsize can be | ||
| 314 | set from a minimum of 2048 to a maximum of 130048 (127K or | ||
| 315 | CIFSMaxBufSize, whichever is smaller) | ||
| 316 | wsize default write size (default 57344) | ||
| 317 | maximum wsize currently allowed by CIFS is 57344 (fourteen | ||
| 318 | 4096 byte pages) | ||
| 308 | rw mount the network share read-write (note that the | 319 | rw mount the network share read-write (note that the |
| 309 | server may still consider the share read-only) | 320 | server may still consider the share read-only) |
| 310 | ro mount network share read-only | 321 | ro mount network share read-only |
| @@ -582,10 +593,10 @@ the start of smb requests and responses can be enabled via: | |||
| 582 | 593 | ||
| 583 | echo 1 > /proc/fs/cifs/traceSMB | 594 | echo 1 > /proc/fs/cifs/traceSMB |
| 584 | 595 | ||
| 585 | Two other experimental features are under development and to test | 596 | Two other experimental features are under development. To test these |
| 586 | require enabling CONFIG_CIFS_EXPERIMENTAL | 597 | requires enabling CONFIG_CIFS_EXPERIMENTAL |
| 587 | 598 | ||
| 588 | More efficient write operations | 599 | ipv6 enablement |
| 589 | 600 | ||
| 590 | DNOTIFY fcntl: needed for support of directory change | 601 | DNOTIFY fcntl: needed for support of directory change |
| 591 | notification and perhaps later for file leases) | 602 | notification and perhaps later for file leases) |
diff --git a/fs/cifs/TODO b/fs/cifs/TODO index 78b620e332bd..d57dc2917d04 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO | |||
| @@ -106,6 +106,12 @@ but recognizes them | |||
| 106 | succeed but still return access denied (appears to be Windows | 106 | succeed but still return access denied (appears to be Windows |
| 107 | server not cifs client problem) and has not been reproduced recently. | 107 | server not cifs client problem) and has not been reproduced recently. |
| 108 | NTFS partitions do not have this problem. | 108 | NTFS partitions do not have this problem. |
| 109 | 4) Unix/POSIX capabilities are reset after reconnection, and affect | ||
| 110 | a few fields in the tree connection but we do do not know which | ||
| 111 | superblocks to apply these changes to. We should probably walk | ||
| 112 | the list of superblocks to set these. Also need to check the | ||
| 113 | flags on the second mount to the same share, and see if we | ||
| 114 | can do the same trick that NFS does to remount duplicate shares. | ||
| 109 | 115 | ||
| 110 | Misc testing to do | 116 | Misc testing to do |
| 111 | ================== | 117 | ================== |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index d619ca7d1416..802d27d98e2d 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
| @@ -712,6 +712,7 @@ typedef struct smb_com_findclose_req { | |||
| 712 | #define REQ_OPLOCK 0x00000002 | 712 | #define REQ_OPLOCK 0x00000002 |
| 713 | #define REQ_BATCHOPLOCK 0x00000004 | 713 | #define REQ_BATCHOPLOCK 0x00000004 |
| 714 | #define REQ_OPENDIRONLY 0x00000008 | 714 | #define REQ_OPENDIRONLY 0x00000008 |
| 715 | #define REQ_EXTENDED_INFO 0x00000010 | ||
| 715 | 716 | ||
| 716 | typedef struct smb_com_open_req { /* also handles create */ | 717 | typedef struct smb_com_open_req { /* also handles create */ |
| 717 | struct smb_hdr hdr; /* wct = 24 */ | 718 | struct smb_hdr hdr; /* wct = 24 */ |
| @@ -1885,15 +1886,19 @@ typedef struct { | |||
| 1885 | #define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */ | 1886 | #define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */ |
| 1886 | #define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based | 1887 | #define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based |
| 1887 | calls including posix open | 1888 | calls including posix open |
| 1888 | and posix unlink */ | 1889 | and posix unlink */ |
| 1890 | #define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up | ||
| 1891 | to 0xFFFF00 */ | ||
| 1892 | #define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080 | ||
| 1893 | |||
| 1889 | #ifdef CONFIG_CIFS_POSIX | 1894 | #ifdef CONFIG_CIFS_POSIX |
| 1890 | /* Can not set pathnames cap yet until we send new posix create SMB since | 1895 | /* Can not set pathnames cap yet until we send new posix create SMB since |
| 1891 | otherwise server can treat such handles opened with older ntcreatex | 1896 | otherwise server can treat such handles opened with older ntcreatex |
| 1892 | (by a new client which knows how to send posix path ops) | 1897 | (by a new client which knows how to send posix path ops) |
| 1893 | as non-posix handles (can affect write behavior with byte range locks. | 1898 | as non-posix handles (can affect write behavior with byte range locks. |
| 1894 | We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ | 1899 | We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ |
| 1895 | /* #define CIFS_UNIX_CAP_MASK 0x0000003b */ | 1900 | /* #define CIFS_UNIX_CAP_MASK 0x000000fb */ |
| 1896 | #define CIFS_UNIX_CAP_MASK 0x0000001b | 1901 | #define CIFS_UNIX_CAP_MASK 0x000000db |
| 1897 | #else | 1902 | #else |
| 1898 | #define CIFS_UNIX_CAP_MASK 0x00000013 | 1903 | #define CIFS_UNIX_CAP_MASK 0x00000013 |
| 1899 | #endif /* CONFIG_CIFS_POSIX */ | 1904 | #endif /* CONFIG_CIFS_POSIX */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f4e92661b223..4a2af78083fb 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/connect.c | 2 | * fs/cifs/connect.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) International Business Machines Corp., 2002,2006 | 4 | * Copyright (C) International Business Machines Corp., 2002,2007 |
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 6 | * | 6 | * |
| 7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
| @@ -1650,19 +1650,19 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon, | |||
| 1650 | } | 1650 | } |
| 1651 | 1651 | ||
| 1652 | cap &= CIFS_UNIX_CAP_MASK; | 1652 | cap &= CIFS_UNIX_CAP_MASK; |
| 1653 | if(vol_info && vol_info->no_psx_acl) | 1653 | if (vol_info && vol_info->no_psx_acl) |
| 1654 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; | 1654 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
| 1655 | else if(CIFS_UNIX_POSIX_ACL_CAP & cap) { | 1655 | else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { |
| 1656 | cFYI(1,("negotiated posix acl support")); | 1656 | cFYI(1,("negotiated posix acl support")); |
| 1657 | if(sb) | 1657 | if(sb) |
| 1658 | sb->s_flags |= MS_POSIXACL; | 1658 | sb->s_flags |= MS_POSIXACL; |
| 1659 | } | 1659 | } |
| 1660 | 1660 | ||
| 1661 | if(vol_info && vol_info->posix_paths == 0) | 1661 | if (vol_info && vol_info->posix_paths == 0) |
| 1662 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; | 1662 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; |
| 1663 | else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { | 1663 | else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { |
| 1664 | cFYI(1,("negotiate posix pathnames")); | 1664 | cFYI(1,("negotiate posix pathnames")); |
| 1665 | if(sb) | 1665 | if (sb) |
| 1666 | CIFS_SB(sb)->mnt_cifs_flags |= | 1666 | CIFS_SB(sb)->mnt_cifs_flags |= |
| 1667 | CIFS_MOUNT_POSIX_PATHS; | 1667 | CIFS_MOUNT_POSIX_PATHS; |
| 1668 | } | 1668 | } |
| @@ -1670,21 +1670,35 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon, | |||
| 1670 | /* We might be setting the path sep back to a different | 1670 | /* We might be setting the path sep back to a different |
| 1671 | form if we are reconnecting and the server switched its | 1671 | form if we are reconnecting and the server switched its |
| 1672 | posix path capability for this share */ | 1672 | posix path capability for this share */ |
| 1673 | if(sb && (CIFS_SB(sb)->prepathlen > 0)) | 1673 | if (sb && (CIFS_SB(sb)->prepathlen > 0)) |
| 1674 | CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb)); | 1674 | CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb)); |
| 1675 | |||
| 1676 | if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { | ||
| 1677 | if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { | ||
| 1678 | CIFS_SB(sb)->rsize = 127 * 1024; | ||
| 1679 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 1680 | cFYI(1,("larger reads not supported by srv")); | ||
| 1681 | #endif | ||
| 1682 | } | ||
| 1683 | } | ||
| 1684 | |||
| 1675 | 1685 | ||
| 1676 | cFYI(1,("Negotiate caps 0x%x",(int)cap)); | 1686 | cFYI(1,("Negotiate caps 0x%x",(int)cap)); |
| 1677 | #ifdef CONFIG_CIFS_DEBUG2 | 1687 | #ifdef CONFIG_CIFS_DEBUG2 |
| 1678 | if(cap & CIFS_UNIX_FCNTL_CAP) | 1688 | if (cap & CIFS_UNIX_FCNTL_CAP) |
| 1679 | cFYI(1,("FCNTL cap")); | 1689 | cFYI(1,("FCNTL cap")); |
| 1680 | if(cap & CIFS_UNIX_EXTATTR_CAP) | 1690 | if (cap & CIFS_UNIX_EXTATTR_CAP) |
| 1681 | cFYI(1,("EXTATTR cap")); | 1691 | cFYI(1,("EXTATTR cap")); |
| 1682 | if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) | 1692 | if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) |
| 1683 | cFYI(1,("POSIX path cap")); | 1693 | cFYI(1,("POSIX path cap")); |
| 1684 | if(cap & CIFS_UNIX_XATTR_CAP) | 1694 | if (cap & CIFS_UNIX_XATTR_CAP) |
| 1685 | cFYI(1,("XATTR cap")); | 1695 | cFYI(1,("XATTR cap")); |
| 1686 | if(cap & CIFS_UNIX_POSIX_ACL_CAP) | 1696 | if (cap & CIFS_UNIX_POSIX_ACL_CAP) |
| 1687 | cFYI(1,("POSIX ACL cap")); | 1697 | cFYI(1,("POSIX ACL cap")); |
| 1698 | if (cap & CIFS_UNIX_LARGE_READ_CAP) | ||
| 1699 | cFYI(1,("very large read cap")); | ||
| 1700 | if (cap & CIFS_UNIX_LARGE_WRITE_CAP) | ||
| 1701 | cFYI(1,("very large write cap")); | ||
| 1688 | #endif /* CIFS_DEBUG2 */ | 1702 | #endif /* CIFS_DEBUG2 */ |
| 1689 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { | 1703 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { |
| 1690 | cFYI(1,("setting capabilities failed")); | 1704 | cFYI(1,("setting capabilities failed")); |
| @@ -1935,13 +1949,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1935 | cERROR(1,("rsize %d too large, using MaxBufSize", | 1949 | cERROR(1,("rsize %d too large, using MaxBufSize", |
| 1936 | volume_info.rsize)); | 1950 | volume_info.rsize)); |
| 1937 | cifs_sb->rsize = CIFSMaxBufSize; | 1951 | cifs_sb->rsize = CIFSMaxBufSize; |
| 1938 | } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) | 1952 | } else if ((volume_info.rsize) && |
| 1953 | (volume_info.rsize <= CIFSMaxBufSize)) | ||
| 1939 | cifs_sb->rsize = volume_info.rsize; | 1954 | cifs_sb->rsize = volume_info.rsize; |
| 1940 | else /* default */ | 1955 | else /* default */ |
| 1941 | cifs_sb->rsize = CIFSMaxBufSize; | 1956 | cifs_sb->rsize = CIFSMaxBufSize; |
| 1942 | 1957 | ||
| 1943 | if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { | 1958 | if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { |
| 1944 | cERROR(1,("wsize %d too large using 4096 instead", | 1959 | cERROR(1,("wsize %d too large, using 4096 instead", |
| 1945 | volume_info.wsize)); | 1960 | volume_info.wsize)); |
| 1946 | cifs_sb->wsize = 4096; | 1961 | cifs_sb->wsize = 4096; |
| 1947 | } else if (volume_info.wsize) | 1962 | } else if (volume_info.wsize) |
| @@ -1960,7 +1975,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1960 | if (cifs_sb->rsize < 2048) { | 1975 | if (cifs_sb->rsize < 2048) { |
| 1961 | cifs_sb->rsize = 2048; | 1976 | cifs_sb->rsize = 2048; |
| 1962 | /* Windows ME may prefer this */ | 1977 | /* Windows ME may prefer this */ |
| 1963 | cFYI(1,("readsize set to minimum 2048")); | 1978 | cFYI(1,("readsize set to minimum: 2048")); |
| 1964 | } | 1979 | } |
| 1965 | /* calculate prepath */ | 1980 | /* calculate prepath */ |
| 1966 | cifs_sb->prepath = volume_info.prepath; | 1981 | cifs_sb->prepath = volume_info.prepath; |
| @@ -2116,7 +2131,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2116 | /* tell server which Unix caps we support */ | 2131 | /* tell server which Unix caps we support */ |
| 2117 | if (tcon->ses->capabilities & CAP_UNIX) | 2132 | if (tcon->ses->capabilities & CAP_UNIX) |
| 2118 | reset_cifs_unix_caps(xid, tcon, sb, &volume_info); | 2133 | reset_cifs_unix_caps(xid, tcon, sb, &volume_info); |
| 2119 | 2134 | else if(cifs_sb->rsize > (1024 * 127)) { | |
| 2135 | cifs_sb->rsize = 1024 * 127; | ||
| 2136 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 2137 | cFYI(1,("no very large read support, rsize 127K")); | ||
| 2138 | #endif | ||
| 2139 | |||
| 2140 | } | ||
| 2120 | if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) | 2141 | if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) |
| 2121 | cifs_sb->wsize = min(cifs_sb->wsize, | 2142 | cifs_sb->wsize = min(cifs_sb->wsize, |
| 2122 | (tcon->ses->server->maxBuf - | 2143 | (tcon->ses->server->maxBuf - |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 94d5b49049df..5f1b707188f8 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -1720,7 +1720,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1720 | pTcon = cifs_sb->tcon; | 1720 | pTcon = cifs_sb->tcon; |
| 1721 | 1721 | ||
| 1722 | pagevec_init(&lru_pvec, 0); | 1722 | pagevec_init(&lru_pvec, 0); |
| 1723 | 1723 | #ifdef CONFIG_CIFS_DEBUG2 | |
| 1724 | cFYI(1,("rpages: num pages %d", num_pages)); | ||
| 1725 | #endif | ||
| 1724 | for (i = 0; i < num_pages; ) { | 1726 | for (i = 0; i < num_pages; ) { |
| 1725 | unsigned contig_pages; | 1727 | unsigned contig_pages; |
| 1726 | struct page *tmp_page; | 1728 | struct page *tmp_page; |
| @@ -1753,7 +1755,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1753 | /* Read size needs to be in multiples of one page */ | 1755 | /* Read size needs to be in multiples of one page */ |
| 1754 | read_size = min_t(const unsigned int, read_size, | 1756 | read_size = min_t(const unsigned int, read_size, |
| 1755 | cifs_sb->rsize & PAGE_CACHE_MASK); | 1757 | cifs_sb->rsize & PAGE_CACHE_MASK); |
| 1756 | 1758 | #ifdef CONFIG_CIFS_DEBUG2 | |
| 1759 | cFYI(1,("rpages: read size 0x%x contiguous pages %d", | ||
| 1760 | read_size, contig_pages)); | ||
| 1761 | #endif | ||
| 1757 | rc = -EAGAIN; | 1762 | rc = -EAGAIN; |
| 1758 | while (rc == -EAGAIN) { | 1763 | while (rc == -EAGAIN) { |
| 1759 | if ((open_file->invalidHandle) && | 1764 | if ((open_file->invalidHandle) && |
