diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/file.c | 6 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 5 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 3 | ||||
-rw-r--r-- | fs/file.c | 14 | ||||
-rw-r--r-- | fs/namei.c | 5 | ||||
-rw-r--r-- | fs/nfs/dir.c | 7 |
6 files changed, 25 insertions, 15 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index edb25b4bbb95..70b6f4c3a0c1 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1794,7 +1794,6 @@ static int cifs_writepages(struct address_space *mapping, | |||
1794 | struct TCP_Server_Info *server; | 1794 | struct TCP_Server_Info *server; |
1795 | struct page *page; | 1795 | struct page *page; |
1796 | int rc = 0; | 1796 | int rc = 0; |
1797 | loff_t isize = i_size_read(mapping->host); | ||
1798 | 1797 | ||
1799 | /* | 1798 | /* |
1800 | * If wsize is smaller than the page cache size, default to writing | 1799 | * If wsize is smaller than the page cache size, default to writing |
@@ -1899,7 +1898,7 @@ retry: | |||
1899 | */ | 1898 | */ |
1900 | set_page_writeback(page); | 1899 | set_page_writeback(page); |
1901 | 1900 | ||
1902 | if (page_offset(page) >= isize) { | 1901 | if (page_offset(page) >= i_size_read(mapping->host)) { |
1903 | done = true; | 1902 | done = true; |
1904 | unlock_page(page); | 1903 | unlock_page(page); |
1905 | end_page_writeback(page); | 1904 | end_page_writeback(page); |
@@ -1932,7 +1931,8 @@ retry: | |||
1932 | wdata->offset = page_offset(wdata->pages[0]); | 1931 | wdata->offset = page_offset(wdata->pages[0]); |
1933 | wdata->pagesz = PAGE_CACHE_SIZE; | 1932 | wdata->pagesz = PAGE_CACHE_SIZE; |
1934 | wdata->tailsz = | 1933 | wdata->tailsz = |
1935 | min(isize - page_offset(wdata->pages[nr_pages - 1]), | 1934 | min(i_size_read(mapping->host) - |
1935 | page_offset(wdata->pages[nr_pages - 1]), | ||
1936 | (loff_t)PAGE_CACHE_SIZE); | 1936 | (loff_t)PAGE_CACHE_SIZE); |
1937 | wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + | 1937 | wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + |
1938 | wdata->tailsz; | 1938 | wdata->tailsz; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index f9b5d3d6cf33..1c576e871366 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -86,14 +86,17 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, | |||
86 | 86 | ||
87 | dentry = d_lookup(parent, name); | 87 | dentry = d_lookup(parent, name); |
88 | if (dentry) { | 88 | if (dentry) { |
89 | int err; | ||
89 | inode = dentry->d_inode; | 90 | inode = dentry->d_inode; |
90 | /* update inode in place if i_ino didn't change */ | 91 | /* update inode in place if i_ino didn't change */ |
91 | if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { | 92 | if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { |
92 | cifs_fattr_to_inode(inode, fattr); | 93 | cifs_fattr_to_inode(inode, fattr); |
93 | return dentry; | 94 | return dentry; |
94 | } | 95 | } |
95 | d_drop(dentry); | 96 | err = d_invalidate(dentry); |
96 | dput(dentry); | 97 | dput(dentry); |
98 | if (err) | ||
99 | return NULL; | ||
97 | } | 100 | } |
98 | 101 | ||
99 | dentry = d_alloc(parent, name); | 102 | dentry = d_alloc(parent, name); |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 56cc4be87807..34cea2798333 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -766,7 +766,6 @@ smb_set_file_info(struct inode *inode, const char *full_path, | |||
766 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 766 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
767 | struct tcon_link *tlink = NULL; | 767 | struct tcon_link *tlink = NULL; |
768 | struct cifs_tcon *tcon; | 768 | struct cifs_tcon *tcon; |
769 | FILE_BASIC_INFO info_buf; | ||
770 | 769 | ||
771 | /* if the file is already open for write, just use that fileid */ | 770 | /* if the file is already open for write, just use that fileid */ |
772 | open_file = find_writable_file(cinode, true); | 771 | open_file = find_writable_file(cinode, true); |
@@ -817,7 +816,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, | |||
817 | netpid = current->tgid; | 816 | netpid = current->tgid; |
818 | 817 | ||
819 | set_via_filehandle: | 818 | set_via_filehandle: |
820 | rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid); | 819 | rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid); |
821 | if (!rc) | 820 | if (!rc) |
822 | cinode->cifsAttrs = le32_to_cpu(buf->Attributes); | 821 | cinode->cifsAttrs = le32_to_cpu(buf->Attributes); |
823 | 822 | ||
@@ -994,16 +994,18 @@ int iterate_fd(struct files_struct *files, unsigned n, | |||
994 | const void *p) | 994 | const void *p) |
995 | { | 995 | { |
996 | struct fdtable *fdt; | 996 | struct fdtable *fdt; |
997 | struct file *file; | ||
998 | int res = 0; | 997 | int res = 0; |
999 | if (!files) | 998 | if (!files) |
1000 | return 0; | 999 | return 0; |
1001 | spin_lock(&files->file_lock); | 1000 | spin_lock(&files->file_lock); |
1002 | fdt = files_fdtable(files); | 1001 | for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { |
1003 | while (!res && n < fdt->max_fds) { | 1002 | struct file *file; |
1004 | file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); | 1003 | file = rcu_dereference_check_fdtable(files, fdt->fd[n]); |
1005 | if (file) | 1004 | if (!file) |
1006 | res = f(p, file, n); | 1005 | continue; |
1006 | res = f(p, file, n); | ||
1007 | if (res) | ||
1008 | break; | ||
1007 | } | 1009 | } |
1008 | spin_unlock(&files->file_lock); | 1010 | spin_unlock(&files->file_lock); |
1009 | return res; | 1011 | return res; |
diff --git a/fs/namei.c b/fs/namei.c index 937f9d50c84b..5f4cdf3ad913 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2131,6 +2131,11 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) | |||
2131 | if (!len) | 2131 | if (!len) |
2132 | return ERR_PTR(-EACCES); | 2132 | return ERR_PTR(-EACCES); |
2133 | 2133 | ||
2134 | if (unlikely(name[0] == '.')) { | ||
2135 | if (len < 2 || (len == 2 && name[1] == '.')) | ||
2136 | return ERR_PTR(-EACCES); | ||
2137 | } | ||
2138 | |||
2134 | while (len--) { | 2139 | while (len--) { |
2135 | c = *(const unsigned char *)name++; | 2140 | c = *(const unsigned char *)name++; |
2136 | if (c == '/' || c == '\0') | 2141 | if (c == '/' || c == '\0') |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ce8cb926526b..b9e66b7e0c14 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -450,7 +450,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
450 | nfs_refresh_inode(dentry->d_inode, entry->fattr); | 450 | nfs_refresh_inode(dentry->d_inode, entry->fattr); |
451 | goto out; | 451 | goto out; |
452 | } else { | 452 | } else { |
453 | d_drop(dentry); | 453 | if (d_invalidate(dentry) != 0) |
454 | goto out; | ||
454 | dput(dentry); | 455 | dput(dentry); |
455 | } | 456 | } |
456 | } | 457 | } |
@@ -1100,6 +1101,8 @@ out_set_verifier: | |||
1100 | out_zap_parent: | 1101 | out_zap_parent: |
1101 | nfs_zap_caches(dir); | 1102 | nfs_zap_caches(dir); |
1102 | out_bad: | 1103 | out_bad: |
1104 | nfs_free_fattr(fattr); | ||
1105 | nfs_free_fhandle(fhandle); | ||
1103 | nfs_mark_for_revalidate(dir); | 1106 | nfs_mark_for_revalidate(dir); |
1104 | if (inode && S_ISDIR(inode->i_mode)) { | 1107 | if (inode && S_ISDIR(inode->i_mode)) { |
1105 | /* Purge readdir caches. */ | 1108 | /* Purge readdir caches. */ |
@@ -1112,8 +1115,6 @@ out_zap_parent: | |||
1112 | shrink_dcache_parent(dentry); | 1115 | shrink_dcache_parent(dentry); |
1113 | } | 1116 | } |
1114 | d_drop(dentry); | 1117 | d_drop(dentry); |
1115 | nfs_free_fattr(fattr); | ||
1116 | nfs_free_fhandle(fhandle); | ||
1117 | dput(parent); | 1118 | dput(parent); |
1118 | dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", | 1119 | dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", |
1119 | __func__, dentry->d_parent->d_name.name, | 1120 | __func__, dentry->d_parent->d_name.name, |