Skip to content

Commit a3021a5

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull Ceph fixes from Sage Weil: "We have a few follow-up fixes for the libceph refactor from Ilya, and then some cephfs + fscache fixes from Zheng. The first two FS-Cache patches are acked by David Howells and deemed trivial enough to go through our tree. The rest fix some issues with the ceph fscache handling (disable cache for inodes opened for write, and simplify the revalidation logic accordingly, dropping the now-unnecessary work queue)" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: ceph: use i_version to check validity of fscache ceph: improve fscache revalidation ceph: disable fscache when inode is opened for write ceph: avoid unnecessary fscache invalidation/revlidation ceph: call __fscache_uncache_page() if readpages fails FS-Cache: make check_consistency callback return int FS-Cache: wake write waiter after invalidating writes libceph: use %s instead of %pE in dout()s libceph: put request only if it's done in handle_reply() libceph: change ceph_osdmap_flag() to take osdc
2 parents eb10a7b + f6973c0 commit a3021a5

File tree

13 files changed

+138
-178
lines changed

13 files changed

+138
-178
lines changed

fs/cachefiles/interface.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache)
380380
* check if the backing cache is updated to FS-Cache
381381
* - called by FS-Cache when evaluates if need to invalidate the cache
382382
*/
383-
static bool cachefiles_check_consistency(struct fscache_operation *op)
383+
static int cachefiles_check_consistency(struct fscache_operation *op)
384384
{
385385
struct cachefiles_object *object;
386386
struct cachefiles_cache *cache;

fs/ceph/addr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,10 @@ static void finish_read(struct ceph_osd_request *req)
276276
for (i = 0; i < num_pages; i++) {
277277
struct page *page = osd_data->pages[i];
278278

279-
if (rc < 0 && rc != -ENOENT)
279+
if (rc < 0 && rc != -ENOENT) {
280+
ceph_fscache_readpage_cancel(inode, page);
280281
goto unlock;
282+
}
281283
if (bytes < (int)PAGE_SIZE) {
282284
/* zero (remainder of) page */
283285
int s = bytes < 0 ? 0 : bytes;
@@ -535,8 +537,6 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
535537
CONGESTION_ON_THRESH(fsc->mount_options->congestion_kb))
536538
set_bdi_congested(&fsc->backing_dev_info, BLK_RW_ASYNC);
537539

538-
ceph_readpage_to_fscache(inode, page);
539-
540540
set_page_writeback(page);
541541
err = ceph_osdc_writepages(osdc, ceph_vino(inode),
542542
&ci->i_layout, snapc,

fs/ceph/cache.c

Lines changed: 58 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "cache.h"
2626

2727
struct ceph_aux_inode {
28+
u64 version;
2829
struct timespec mtime;
2930
loff_t size;
3031
};
@@ -69,15 +70,8 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
6970
fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index,
7071
&ceph_fscache_fsid_object_def,
7172
fsc, true);
72-
73-
if (fsc->fscache == NULL) {
73+
if (!fsc->fscache)
7474
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;
8175

8276
return 0;
8377
}
@@ -105,6 +99,7 @@ static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,
10599
const struct inode* inode = &ci->vfs_inode;
106100

107101
memset(&aux, 0, sizeof(aux));
102+
aux.version = ci->i_version;
108103
aux.mtime = inode->i_mtime;
109104
aux.size = i_size_read(inode);
110105

@@ -131,6 +126,7 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
131126
return FSCACHE_CHECKAUX_OBSOLETE;
132127

133128
memset(&aux, 0, sizeof(aux));
129+
aux.version = ci->i_version;
134130
aux.mtime = inode->i_mtime;
135131
aux.size = i_size_read(inode);
136132

@@ -181,32 +177,26 @@ static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
181177
.now_uncached = ceph_fscache_inode_now_uncached,
182178
};
183179

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)
186181
{
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);
188184

189185
/* No caching for filesystem */
190186
if (fsc->fscache == NULL)
191187
return;
192188

193189
/* 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))
195191
return;
196192

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+
}
208199
inode_unlock(inode);
209-
210200
}
211201

212202
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)
222212
fscache_relinquish_cookie(cookie, 0);
223213
}
224214

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+
225243
static void ceph_vfs_readpage_complete(struct page *page, void *data, int error)
226244
{
227245
if (!error)
@@ -238,8 +256,7 @@ static void ceph_vfs_readpage_complete_unlock(struct page *page, void *data, int
238256

239257
static inline bool cache_valid(struct ceph_inode_info *ci)
240258
{
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;
243260
}
244261

245262

@@ -332,69 +349,27 @@ void ceph_invalidate_fscache_page(struct inode* inode, struct page *page)
332349

333350
void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc)
334351
{
335-
if (fsc->revalidate_wq)
336-
destroy_workqueue(fsc->revalidate_wq);
337-
338352
fscache_relinquish_cookie(fsc->fscache, 0);
339353
fsc->fscache = NULL;
340354
}
341355

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)
376360
{
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))
381362
return;
382363

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);
391373
}
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);
400375
}

fs/ceph/cache.h

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ void ceph_fscache_unregister(void);
3434
int ceph_fscache_register_fs(struct ceph_fs_client* fsc);
3535
void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc);
3636

37-
void ceph_fscache_inode_init(struct ceph_inode_info *ci);
38-
void ceph_fscache_register_inode_cookie(struct ceph_fs_client* fsc,
39-
struct ceph_inode_info* ci);
37+
void ceph_fscache_register_inode_cookie(struct inode *inode);
4038
void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci);
39+
void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp);
40+
void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci);
4141

4242
int ceph_readpage_from_fscache(struct inode *inode, struct page *page);
4343
int ceph_readpages_from_fscache(struct inode *inode,
@@ -46,12 +46,11 @@ int ceph_readpages_from_fscache(struct inode *inode,
4646
unsigned *nr_pages);
4747
void ceph_readpage_to_fscache(struct inode *inode, struct page *page);
4848
void ceph_invalidate_fscache_page(struct inode* inode, struct page *page);
49-
void ceph_queue_revalidate(struct inode *inode);
5049

51-
static inline void ceph_fscache_update_objectsize(struct inode *inode)
50+
static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
5251
{
53-
struct ceph_inode_info *ci = ceph_inode(inode);
54-
fscache_attr_changed(ci->fscache);
52+
ci->fscache = NULL;
53+
ci->i_fscache_gen = 0;
5554
}
5655

5756
static inline void ceph_fscache_invalidate(struct inode *inode)
@@ -88,6 +87,11 @@ static inline void ceph_fscache_readpages_cancel(struct inode *inode,
8887
return fscache_readpages_cancel(ci->fscache, pages);
8988
}
9089

90+
static inline void ceph_disable_fscache_readpage(struct ceph_inode_info *ci)
91+
{
92+
ci->i_fscache_gen = ci->i_rdcache_gen - 1;
93+
}
94+
9195
#else
9296

9397
static inline int ceph_fscache_register(void)
@@ -112,8 +116,20 @@ static inline void ceph_fscache_inode_init(struct ceph_inode_info *ci)
112116
{
113117
}
114118

115-
static inline void ceph_fscache_register_inode_cookie(struct ceph_fs_client* parent_fsc,
116-
struct ceph_inode_info* ci)
119+
static inline void ceph_fscache_register_inode_cookie(struct inode *inode)
120+
{
121+
}
122+
123+
static inline void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
124+
{
125+
}
126+
127+
static inline void ceph_fscache_file_set_cookie(struct inode *inode,
128+
struct file *filp)
129+
{
130+
}
131+
132+
static inline void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci)
117133
{
118134
}
119135

@@ -141,10 +157,6 @@ static inline void ceph_readpage_to_fscache(struct inode *inode,
141157
{
142158
}
143159

144-
static inline void ceph_fscache_update_objectsize(struct inode *inode)
145-
{
146-
}
147-
148160
static inline void ceph_fscache_invalidate(struct inode *inode)
149161
{
150162
}
@@ -154,10 +166,6 @@ static inline void ceph_invalidate_fscache_page(struct inode *inode,
154166
{
155167
}
156168

157-
static inline void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
158-
{
159-
}
160-
161169
static inline int ceph_release_fscache_page(struct page *page, gfp_t gfp)
162170
{
163171
return 1;
@@ -173,7 +181,7 @@ static inline void ceph_fscache_readpages_cancel(struct inode *inode,
173181
{
174182
}
175183

176-
static inline void ceph_queue_revalidate(struct inode *inode)
184+
static inline void ceph_disable_fscache_readpage(struct ceph_inode_info *ci)
177185
{
178186
}
179187

0 commit comments

Comments
 (0)