Skip to content

Commit 18d0406

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: enable fscache usage even for files opened as rw
So far, the fscache implementation we had supports only a small set of use cases. Particularly for files opened with O_RDONLY. This commit enables it even for rw based file opens. It also enables the reuse of cached data in case of mount option (cache=singleclient) where it is guaranteed that this is the only client (and server) which operates on the files. There's also a single line change in fscache.c to get around a bug seen in fscache. Signed-off-by: Shyam Prasad N <[email protected]> Acked-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 3d2b50e commit 18d0406

File tree

6 files changed

+76
-11
lines changed

6 files changed

+76
-11
lines changed

fs/cifs/cifsfs.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,6 @@ cifs_evict_inode(struct inode *inode)
399399
{
400400
truncate_inode_pages_final(&inode->i_data);
401401
clear_inode(inode);
402-
cifs_fscache_release_inode_cookie(inode);
403402
}
404403

405404
static void

fs/cifs/cifssmb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,7 @@ cifs_writev_complete(struct work_struct *work)
21012101
else if (wdata->result < 0)
21022102
SetPageError(page);
21032103
end_page_writeback(page);
2104+
cifs_readpage_to_fscache(inode, page);
21042105
put_page(page);
21052106
}
21062107
if (wdata->result != -EAGAIN)

fs/cifs/file.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ static void cifsFileInfo_put_final(struct cifsFileInfo *cifs_file)
377377
struct cifsLockInfo *li, *tmp;
378378
struct super_block *sb = inode->i_sb;
379379

380+
cifs_fscache_release_inode_cookie(inode);
381+
380382
/*
381383
* Delete any outstanding lock records. We'll lose them when the file
382384
* is closed anyway.
@@ -882,8 +884,10 @@ int cifs_close(struct inode *inode, struct file *file)
882884
if ((cinode->oplock == CIFS_CACHE_RHW_FLG) &&
883885
cinode->lease_granted &&
884886
dclose) {
885-
if (test_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags))
887+
if (test_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags)) {
886888
inode->i_ctime = inode->i_mtime = current_time(inode);
889+
cifs_fscache_update_inode_cookie(inode);
890+
}
887891
spin_lock(&cinode->deferred_lock);
888892
cifs_add_deferred_close(cfile, dclose);
889893
if (cfile->deferred_close_scheduled &&
@@ -4170,6 +4174,10 @@ static vm_fault_t
41704174
cifs_page_mkwrite(struct vm_fault *vmf)
41714175
{
41724176
struct page *page = vmf->page;
4177+
struct file *file = vmf->vma->vm_file;
4178+
struct inode *inode = file_inode(file);
4179+
4180+
cifs_fscache_wait_on_page_write(inode, page);
41734181

41744182
lock_page(page);
41754183
return VM_FAULT_LOCKED;
@@ -4235,13 +4243,16 @@ cifs_readv_complete(struct work_struct *work)
42354243
(rdata->result == -EAGAIN && got_bytes)) {
42364244
flush_dcache_page(page);
42374245
SetPageUptodate(page);
4238-
}
4246+
} else
4247+
SetPageError(page);
42394248

42404249
unlock_page(page);
42414250

42424251
if (rdata->result == 0 ||
42434252
(rdata->result == -EAGAIN && got_bytes))
42444253
cifs_readpage_to_fscache(rdata->mapping->host, page);
4254+
else
4255+
cifs_fscache_uncache_page(rdata->mapping->host, page);
42454256

42464257
got_bytes -= min_t(unsigned int, PAGE_SIZE, got_bytes);
42474258

fs/cifs/fscache.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,29 +176,34 @@ void cifs_fscache_release_inode_cookie(struct inode *inode)
176176
auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec;
177177

178178
cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
179+
/* fscache_relinquish_cookie does not seem to update auxdata */
180+
fscache_update_cookie(cifsi->fscache, &auxdata);
179181
fscache_relinquish_cookie(cifsi->fscache, &auxdata, false);
180182
cifsi->fscache = NULL;
181183
}
182184
}
183185

184-
static void cifs_fscache_disable_inode_cookie(struct inode *inode)
186+
void cifs_fscache_update_inode_cookie(struct inode *inode)
185187
{
188+
struct cifs_fscache_inode_auxdata auxdata;
186189
struct cifsInodeInfo *cifsi = CIFS_I(inode);
187190

188191
if (cifsi->fscache) {
192+
memset(&auxdata, 0, sizeof(auxdata));
193+
auxdata.eof = cifsi->server_eof;
194+
auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec;
195+
auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec;
196+
auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec;
197+
auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec;
198+
189199
cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache);
190-
fscache_uncache_all_inode_pages(cifsi->fscache, inode);
191-
fscache_relinquish_cookie(cifsi->fscache, NULL, true);
192-
cifsi->fscache = NULL;
200+
fscache_update_cookie(cifsi->fscache, &auxdata);
193201
}
194202
}
195203

196204
void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
197205
{
198-
if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
199-
cifs_fscache_disable_inode_cookie(inode);
200-
else
201-
cifs_fscache_enable_inode_cookie(inode);
206+
cifs_fscache_enable_inode_cookie(inode);
202207
}
203208

204209
void cifs_fscache_reset_inode_cookie(struct inode *inode)
@@ -310,6 +315,8 @@ void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
310315
struct cifsInodeInfo *cifsi = CIFS_I(inode);
311316
int ret;
312317

318+
WARN_ON(!cifsi->fscache);
319+
313320
cifs_dbg(FYI, "%s: (fsc: %p, p: %p, i: %p)\n",
314321
__func__, cifsi->fscache, page, inode);
315322
ret = fscache_write_page(cifsi->fscache, page,
@@ -334,3 +341,21 @@ void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
334341
fscache_wait_on_page_write(cookie, page);
335342
fscache_uncache_page(cookie, page);
336343
}
344+
345+
void __cifs_fscache_wait_on_page_write(struct inode *inode, struct page *page)
346+
{
347+
struct cifsInodeInfo *cifsi = CIFS_I(inode);
348+
struct fscache_cookie *cookie = cifsi->fscache;
349+
350+
cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", __func__, page, cookie);
351+
fscache_wait_on_page_write(cookie, page);
352+
}
353+
354+
void __cifs_fscache_uncache_page(struct inode *inode, struct page *page)
355+
{
356+
struct cifsInodeInfo *cifsi = CIFS_I(inode);
357+
struct fscache_cookie *cookie = cifsi->fscache;
358+
359+
cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", __func__, page, cookie);
360+
fscache_uncache_page(cookie, page);
361+
}

fs/cifs/fscache.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,13 @@ extern void cifs_fscache_get_super_cookie(struct cifs_tcon *);
5555
extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
5656

5757
extern void cifs_fscache_release_inode_cookie(struct inode *);
58+
extern void cifs_fscache_update_inode_cookie(struct inode *inode);
5859
extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
5960
extern void cifs_fscache_reset_inode_cookie(struct inode *);
6061

6162
extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
63+
extern void __cifs_fscache_wait_on_page_write(struct inode *inode, struct page *page);
64+
extern void __cifs_fscache_uncache_page(struct inode *inode, struct page *page);
6265
extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
6366
extern int __cifs_readpage_from_fscache(struct inode *, struct page *);
6467
extern int __cifs_readpages_from_fscache(struct inode *,
@@ -76,6 +79,20 @@ static inline void cifs_fscache_invalidate_page(struct page *page,
7679
__cifs_fscache_invalidate_page(page, inode);
7780
}
7881

82+
static inline void cifs_fscache_wait_on_page_write(struct inode *inode,
83+
struct page *page)
84+
{
85+
if (PageFsCache(page))
86+
__cifs_fscache_wait_on_page_write(inode, page);
87+
}
88+
89+
static inline void cifs_fscache_uncache_page(struct inode *inode,
90+
struct page *page)
91+
{
92+
if (PageFsCache(page))
93+
__cifs_fscache_uncache_page(inode, page);
94+
}
95+
7996
static inline int cifs_readpage_from_fscache(struct inode *inode,
8097
struct page *page)
8198
{
@@ -123,6 +140,7 @@ static inline void
123140
cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {}
124141

125142
static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
143+
static inline void cifs_fscache_update_inode_cookie(struct inode *inode) {}
126144
static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
127145
struct file *filp) {}
128146
static inline void cifs_fscache_reset_inode_cookie(struct inode *inode) {}
@@ -133,6 +151,11 @@ static inline int cifs_fscache_release_page(struct page *page, gfp_t gfp)
133151

134152
static inline void cifs_fscache_invalidate_page(struct page *page,
135153
struct inode *inode) {}
154+
static inline void cifs_fscache_wait_on_page_write(struct inode *inode,
155+
struct page *page) {}
156+
static inline void cifs_fscache_uncache_page(struct inode *inode,
157+
struct page *page) {}
158+
136159
static inline int
137160
cifs_readpage_from_fscache(struct inode *inode, struct page *page)
138161
{

fs/cifs/inode.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,6 +2297,7 @@ cifs_revalidate_mapping(struct inode *inode)
22972297
{
22982298
int rc;
22992299
unsigned long *flags = &CIFS_I(inode)->flags;
2300+
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
23002301

23012302
/* swapfiles are not supposed to be shared */
23022303
if (IS_SWAPFILE(inode))
@@ -2308,11 +2309,16 @@ cifs_revalidate_mapping(struct inode *inode)
23082309
return rc;
23092310

23102311
if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) {
2312+
/* for cache=singleclient, do not invalidate */
2313+
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)
2314+
goto skip_invalidate;
2315+
23112316
rc = cifs_invalidate_mapping(inode);
23122317
if (rc)
23132318
set_bit(CIFS_INO_INVALID_MAPPING, flags);
23142319
}
23152320

2321+
skip_invalidate:
23162322
clear_bit_unlock(CIFS_INO_LOCK, flags);
23172323
smp_mb__after_atomic();
23182324
wake_up_bit(flags, CIFS_INO_LOCK);

0 commit comments

Comments
 (0)