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) && |