From a9e9b7bc15a32ec5b0679704e70f3ffeecfaadd8 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Fri, 13 Sep 2013 14:11:56 +0100 Subject: [PATCH 1/3] cifs: Do not take a reference to the page in cifs_readpage_worker() We do not need to take a reference to the pagecache in cifs_readpage_worker() since the calling function will have already taken one before passing the pointer to the page as an argument to the function. Signed-off-by: Sachin Prabhu Reviewed-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/file.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index d044b35ce228..5f99ee551662 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3379,6 +3379,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, return rc; } +/* + * cifs_readpage_worker must be called with the page pinned + */ static int cifs_readpage_worker(struct file *file, struct page *page, loff_t *poffset) { @@ -3390,7 +3393,6 @@ static int cifs_readpage_worker(struct file *file, struct page *page, if (rc == 0) goto read_complete; - page_cache_get(page); read_data = kmap(page); /* for reads over a certain size could initiate async read ahead */ @@ -3417,7 +3419,6 @@ static int cifs_readpage_worker(struct file *file, struct page *page, io_error: kunmap(page); - page_cache_release(page); read_complete: return rc; From 466bd31bbda9e1dd2ace1d72c8de5045bf6f3bf6 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Fri, 13 Sep 2013 14:11:57 +0100 Subject: [PATCH 2/3] cifs: Avoid calling unlock_page() twice in cifs_readpage() when using fscache When reading a single page with cifs_readpage(), we make a call to fscache_read_or_alloc_page() which once done, asynchronously calls the completion function cifs_readpage_from_fscache_complete(). This completion function unlocks the page once it has been populated from cache. The module then attempts to unlock the page a second time in cifs_readpage() which leads to warning messages. In case of a successful call to fscache_read_or_alloc_page() we should skip the second unlock_page() since this will be called by the cifs_readpage_from_fscache_complete() once the page has been populated by fscache. With the modifications to cifs_readpage_worker(), we will need to re-grab the page lock in cifs_write_begin(). The problem was first noticed when testing new fscache patches for cifs. https://bugzilla.redhat.com/show_bug.cgi?id=1005737 Signed-off-by: Sachin Prabhu Reviewed-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/file.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5f99ee551662..eb955b525e55 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3419,6 +3419,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, io_error: kunmap(page); + unlock_page(page); read_complete: return rc; @@ -3443,8 +3444,6 @@ static int cifs_readpage(struct file *file, struct page *page) rc = cifs_readpage_worker(file, page, &offset); - unlock_page(page); - free_xid(xid); return rc; } @@ -3498,6 +3497,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { + int oncethru = 0; pgoff_t index = pos >> PAGE_CACHE_SHIFT; loff_t offset = pos & (PAGE_CACHE_SIZE - 1); loff_t page_start = pos & PAGE_MASK; @@ -3507,6 +3507,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, cifs_dbg(FYI, "write_begin from %lld len %d\n", (long long)pos, len); +start: page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { rc = -ENOMEM; @@ -3548,13 +3549,16 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, } } - if ((file->f_flags & O_ACCMODE) != O_WRONLY) { + if ((file->f_flags & O_ACCMODE) != O_WRONLY && !oncethru) { /* * might as well read a page, it is fast enough. If we get * an error, we don't need to return it. cifs_write_end will * do a sync write instead since PG_uptodate isn't set. */ cifs_readpage_worker(file, page, &page_start); + page_cache_release(page); + oncethru = 1; + goto start; } else { /* we could try using another file handle if there is one - but how would we lock it to prevent close of that handle From 81b66220a9ebea7dd1547388279ee1898d7fe0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= Date: Tue, 10 Sep 2013 10:28:38 +0200 Subject: [PATCH 3/3] cifs: update cifs.txt and remove some outdated infos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acked-by: Jeff Layton Signed-off-by: Björn JACKE Signed-off-by: Steve French --- Documentation/filesystems/cifs/cifs.txt | 42 +++++++------------------ 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/Documentation/filesystems/cifs/cifs.txt b/Documentation/filesystems/cifs/cifs.txt index 49cc923a93e3..2fac91ac96cf 100644 --- a/Documentation/filesystems/cifs/cifs.txt +++ b/Documentation/filesystems/cifs/cifs.txt @@ -1,18 +1,14 @@ This is the client VFS module for the Common Internet File System (CIFS) protocol which is the successor to the Server Message Block (SMB) protocol, the native file sharing mechanism for most early - PC operating systems. CIFS is fully supported by current network - file servers such as Windows 2000, Windows 2003 (including - Windows XP) as well by Samba (which provides excellent CIFS + PC operating systems. New and improved versions of CIFS are now + called SMB2 and SMB3. These dialects are also supported by the + CIFS VFS module. CIFS is fully supported by network + file servers such as Windows 2000, 2003, 2008 and 2012 + as well by Samba (which provides excellent CIFS server support for Linux and many other operating systems), so this network filesystem client can mount to a wide variety of - servers. The smbfs module should be used instead of this cifs module - for mounting to older SMB servers such as OS/2. The smbfs and cifs - modules can coexist and do not conflict. The CIFS VFS filesystem - module is designed to work well with servers that implement the - newer versions (dialects) of the SMB/CIFS protocol such as Samba, - the program written by Andrew Tridgell that turns any Unix host - into a SMB/CIFS file server. + servers. The intent of this module is to provide the most advanced network file system function for CIFS compliant servers, including better @@ -24,28 +20,12 @@ alternative to NFSv4 for fileserving in some Linux to Linux environments, not just in Linux to Windows environments. - This filesystem has an optional mount utility (mount.cifs) that can - be obtained from the project page and installed in the path in the same - directory with the other mount helpers (such as mount.smbfs). - Mounting using the cifs filesystem without installing the mount helper - requires specifying the server's ip address. + This filesystem has an mount utility (mount.cifs) that can be obtained from - For Linux 2.4: - mount //anything/here /mnt_target -o - user=username,pass=password,unc=//ip_address_of_server/sharename + https://ftp.samba.org/pub/linux-cifs/cifs-utils/ - For Linux 2.5: - mount //ip_address_of_server/sharename /mnt_target -o user=username, pass=password + It must be installed in the directory with the other mount helpers. + For more information on the module see the project wiki page at - For more information on the module see the project page at - - http://us1.samba.org/samba/Linux_CIFS_client.html - - For more information on CIFS see: - - http://www.snia.org/tech_activities/CIFS - - or the Samba site: - - http://www.samba.org + https://wiki.samba.org/index.php/LinuxCIFS_utils