25
25
#include "cache.h"
26
26
27
27
struct ceph_aux_inode {
28
+ u64 version ;
28
29
struct timespec mtime ;
29
30
loff_t size ;
30
31
};
@@ -69,15 +70,8 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
69
70
fsc -> fscache = fscache_acquire_cookie (ceph_cache_netfs .primary_index ,
70
71
& ceph_fscache_fsid_object_def ,
71
72
fsc , true);
72
-
73
- if (fsc -> fscache == NULL ) {
73
+ if (!fsc -> fscache )
74
74
pr_err ("Unable to resgister fsid: %p fscache cookie" , fsc );
75
- return 0 ;
76
- }
77
-
78
- fsc -> revalidate_wq = alloc_workqueue ("ceph-revalidate" , 0 , 1 );
79
- if (fsc -> revalidate_wq == NULL )
80
- return - ENOMEM ;
81
75
82
76
return 0 ;
83
77
}
@@ -105,6 +99,7 @@ static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,
105
99
const struct inode * inode = & ci -> vfs_inode ;
106
100
107
101
memset (& aux , 0 , sizeof (aux ));
102
+ aux .version = ci -> i_version ;
108
103
aux .mtime = inode -> i_mtime ;
109
104
aux .size = i_size_read (inode );
110
105
@@ -131,6 +126,7 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
131
126
return FSCACHE_CHECKAUX_OBSOLETE ;
132
127
133
128
memset (& aux , 0 , sizeof (aux ));
129
+ aux .version = ci -> i_version ;
134
130
aux .mtime = inode -> i_mtime ;
135
131
aux .size = i_size_read (inode );
136
132
@@ -181,32 +177,26 @@ static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
181
177
.now_uncached = ceph_fscache_inode_now_uncached ,
182
178
};
183
179
184
- void ceph_fscache_register_inode_cookie (struct ceph_fs_client * fsc ,
185
- struct ceph_inode_info * ci )
180
+ void ceph_fscache_register_inode_cookie (struct inode * inode )
186
181
{
187
- struct inode * inode = & ci -> vfs_inode ;
182
+ struct ceph_inode_info * ci = ceph_inode (inode );
183
+ struct ceph_fs_client * fsc = ceph_inode_to_client (inode );
188
184
189
185
/* No caching for filesystem */
190
186
if (fsc -> fscache == NULL )
191
187
return ;
192
188
193
189
/* Only cache for regular files that are read only */
194
- if (( ci -> vfs_inode . i_mode & S_IFREG ) == 0 )
190
+ if (! S_ISREG ( inode -> i_mode ) )
195
191
return ;
196
192
197
- /* Avoid multiple racing open requests */
198
- inode_lock (inode );
199
-
200
- if (ci -> fscache )
201
- goto done ;
202
-
203
- ci -> fscache = fscache_acquire_cookie (fsc -> fscache ,
204
- & ceph_fscache_inode_object_def ,
205
- ci , true);
206
- fscache_check_consistency (ci -> fscache );
207
- done :
193
+ inode_lock_nested (inode , I_MUTEX_CHILD );
194
+ if (!ci -> fscache ) {
195
+ ci -> fscache = fscache_acquire_cookie (fsc -> fscache ,
196
+ & ceph_fscache_inode_object_def ,
197
+ ci , false);
198
+ }
208
199
inode_unlock (inode );
209
-
210
200
}
211
201
212
202
void ceph_fscache_unregister_inode_cookie (struct ceph_inode_info * ci )
@@ -222,6 +212,34 @@ void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
222
212
fscache_relinquish_cookie (cookie , 0 );
223
213
}
224
214
215
+ static bool ceph_fscache_can_enable (void * data )
216
+ {
217
+ struct inode * inode = data ;
218
+ return !inode_is_open_for_write (inode );
219
+ }
220
+
221
+ void ceph_fscache_file_set_cookie (struct inode * inode , struct file * filp )
222
+ {
223
+ struct ceph_inode_info * ci = ceph_inode (inode );
224
+
225
+ if (!fscache_cookie_valid (ci -> fscache ))
226
+ return ;
227
+
228
+ if (inode_is_open_for_write (inode )) {
229
+ dout ("fscache_file_set_cookie %p %p disabling cache\n" ,
230
+ inode , filp );
231
+ fscache_disable_cookie (ci -> fscache , false);
232
+ fscache_uncache_all_inode_pages (ci -> fscache , inode );
233
+ } else {
234
+ fscache_enable_cookie (ci -> fscache , ceph_fscache_can_enable ,
235
+ inode );
236
+ if (fscache_cookie_enabled (ci -> fscache )) {
237
+ dout ("fscache_file_set_cookie %p %p enabing cache\n" ,
238
+ inode , filp );
239
+ }
240
+ }
241
+ }
242
+
225
243
static void ceph_vfs_readpage_complete (struct page * page , void * data , int error )
226
244
{
227
245
if (!error )
@@ -238,8 +256,7 @@ static void ceph_vfs_readpage_complete_unlock(struct page *page, void *data, int
238
256
239
257
static inline bool cache_valid (struct ceph_inode_info * ci )
240
258
{
241
- return ((ceph_caps_issued (ci ) & CEPH_CAP_FILE_CACHE ) &&
242
- (ci -> i_fscache_gen == ci -> i_rdcache_gen ));
259
+ return ci -> i_fscache_gen == ci -> i_rdcache_gen ;
243
260
}
244
261
245
262
@@ -332,69 +349,27 @@ void ceph_invalidate_fscache_page(struct inode* inode, struct page *page)
332
349
333
350
void ceph_fscache_unregister_fs (struct ceph_fs_client * fsc )
334
351
{
335
- if (fsc -> revalidate_wq )
336
- destroy_workqueue (fsc -> revalidate_wq );
337
-
338
352
fscache_relinquish_cookie (fsc -> fscache , 0 );
339
353
fsc -> fscache = NULL ;
340
354
}
341
355
342
- static void ceph_revalidate_work (struct work_struct * work )
343
- {
344
- int issued ;
345
- u32 orig_gen ;
346
- struct ceph_inode_info * ci = container_of (work , struct ceph_inode_info ,
347
- i_revalidate_work );
348
- struct inode * inode = & ci -> vfs_inode ;
349
-
350
- spin_lock (& ci -> i_ceph_lock );
351
- issued = __ceph_caps_issued (ci , NULL );
352
- orig_gen = ci -> i_rdcache_gen ;
353
- spin_unlock (& ci -> i_ceph_lock );
354
-
355
- if (!(issued & CEPH_CAP_FILE_CACHE )) {
356
- dout ("revalidate_work lost cache before validation %p\n" ,
357
- inode );
358
- goto out ;
359
- }
360
-
361
- if (!fscache_check_consistency (ci -> fscache ))
362
- fscache_invalidate (ci -> fscache );
363
-
364
- spin_lock (& ci -> i_ceph_lock );
365
- /* Update the new valid generation (backwards sanity check too) */
366
- if (orig_gen > ci -> i_fscache_gen ) {
367
- ci -> i_fscache_gen = orig_gen ;
368
- }
369
- spin_unlock (& ci -> i_ceph_lock );
370
-
371
- out :
372
- iput (& ci -> vfs_inode );
373
- }
374
-
375
- void ceph_queue_revalidate (struct inode * inode )
356
+ /*
357
+ * caller should hold CEPH_CAP_FILE_{RD,CACHE}
358
+ */
359
+ void ceph_fscache_revalidate_cookie (struct ceph_inode_info * ci )
376
360
{
377
- struct ceph_fs_client * fsc = ceph_sb_to_client (inode -> i_sb );
378
- struct ceph_inode_info * ci = ceph_inode (inode );
379
-
380
- if (fsc -> revalidate_wq == NULL || ci -> fscache == NULL )
361
+ if (cache_valid (ci ))
381
362
return ;
382
363
383
- ihold (inode );
384
-
385
- if (queue_work (ceph_sb_to_client (inode -> i_sb )-> revalidate_wq ,
386
- & ci -> i_revalidate_work )) {
387
- dout ("ceph_queue_revalidate %p\n" , inode );
388
- } else {
389
- dout ("ceph_queue_revalidate %p failed\n)" , inode );
390
- iput (inode );
364
+ /* resue i_truncate_mutex. There should be no pending
365
+ * truncate while the caller holds CEPH_CAP_FILE_RD */
366
+ mutex_lock (& ci -> i_truncate_mutex );
367
+ if (!cache_valid (ci )) {
368
+ if (fscache_check_consistency (ci -> fscache ))
369
+ fscache_invalidate (ci -> fscache );
370
+ spin_lock (& ci -> i_ceph_lock );
371
+ ci -> i_fscache_gen = ci -> i_rdcache_gen ;
372
+ spin_unlock (& ci -> i_ceph_lock );
391
373
}
392
- }
393
-
394
- void ceph_fscache_inode_init (struct ceph_inode_info * ci )
395
- {
396
- ci -> fscache = NULL ;
397
- /* The first load is verifed cookie open time */
398
- ci -> i_fscache_gen = 1 ;
399
- INIT_WORK (& ci -> i_revalidate_work , ceph_revalidate_work );
374
+ mutex_unlock (& ci -> i_truncate_mutex );
400
375
}
0 commit comments