Skip to content

Commit 7fd350f

Browse files
committed
Merge tag 'fscache-fixes-20220121' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull more fscache updates from David Howells: "A set of fixes and minor updates for the fscache rewrite: - Fix mishandling of volume collisions (the wait condition is inverted and so it was only waiting if the volume collision was already resolved). - Fix miscalculation of whether there's space available in cachefiles. - Make sure a default cache name is set on a cache if the user hasn't set one by the time they bind the cache. - Adjust the way the backing inode is presented in tracepoints, add a tracepoint for mkdir and trace directory lookup. - Add a tracepoint for failure to set the active file mark. - Add an explanation of the checks made on the backing filesystem. - Check that the backing filesystem supports tmpfile. - Document how the page-release cancellation of the read-skip optimisation works. And I've included a change for netfslib: - Make ops->init_rreq() optional" * tag 'fscache-fixes-20220121' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: netfs: Make ops->init_rreq() optional fscache: Add a comment explaining how page-release optimisation works cachefiles: Check that the backing filesystem supports tmpfiles cachefiles: Explain checks in a comment cachefiles: Trace active-mark failure cachefiles: Make some tracepoint adjustments cachefiles: set default tag name if it's unspecified cachefiles: Calculate the blockshift in terms of bytes, not pages fscache: Fix the volume collision wait condition
2 parents b68b10b + cef0223 commit 7fd350f

File tree

10 files changed

+113
-51
lines changed

10 files changed

+113
-51
lines changed

fs/cachefiles/cache.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,19 @@ int cachefiles_add_cache(struct cachefiles_cache *cache)
4949
goto error_unsupported;
5050
}
5151

52-
/* check parameters */
52+
/* Check features of the backing filesystem:
53+
* - Directories must support looking up and directory creation
54+
* - We create tmpfiles to handle invalidation
55+
* - We use xattrs to store metadata
56+
* - We need to be able to query the amount of space available
57+
* - We want to be able to sync the filesystem when stopping the cache
58+
* - We use DIO to/from pages, so the blocksize mustn't be too big.
59+
*/
5360
ret = -EOPNOTSUPP;
5461
if (d_is_negative(root) ||
5562
!d_backing_inode(root)->i_op->lookup ||
5663
!d_backing_inode(root)->i_op->mkdir ||
64+
!d_backing_inode(root)->i_op->tmpfile ||
5765
!(d_backing_inode(root)->i_opflags & IOP_XATTR) ||
5866
!root->d_sb->s_op->statfs ||
5967
!root->d_sb->s_op->sync_fs ||
@@ -84,9 +92,7 @@ int cachefiles_add_cache(struct cachefiles_cache *cache)
8492
goto error_unsupported;
8593

8694
cache->bsize = stats.f_bsize;
87-
cache->bshift = 0;
88-
if (stats.f_bsize < PAGE_SIZE)
89-
cache->bshift = PAGE_SHIFT - ilog2(stats.f_bsize);
95+
cache->bshift = ilog2(stats.f_bsize);
9096

9197
_debug("blksize %u (shift %u)",
9298
cache->bsize, cache->bshift);
@@ -106,7 +112,6 @@ int cachefiles_add_cache(struct cachefiles_cache *cache)
106112
(unsigned long long) cache->fcull,
107113
(unsigned long long) cache->fstop);
108114

109-
stats.f_blocks >>= cache->bshift;
110115
do_div(stats.f_blocks, 100);
111116
cache->bstop = stats.f_blocks * cache->bstop_percent;
112117
cache->bcull = stats.f_blocks * cache->bcull_percent;
@@ -209,7 +214,7 @@ int cachefiles_has_space(struct cachefiles_cache *cache,
209214
return ret;
210215
}
211216

212-
b_avail = stats.f_bavail >> cache->bshift;
217+
b_avail = stats.f_bavail;
213218
b_writing = atomic_long_read(&cache->b_writing);
214219
if (b_avail > b_writing)
215220
b_avail -= b_writing;

fs/cachefiles/daemon.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,17 @@ static int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args)
703703
return -EBUSY;
704704
}
705705

706+
/* Make sure we have copies of the tag string */
707+
if (!cache->tag) {
708+
/*
709+
* The tag string is released by the fops->release()
710+
* function, so we don't release it on error here
711+
*/
712+
cache->tag = kstrdup("CacheFiles", GFP_KERNEL);
713+
if (!cache->tag)
714+
return -ENOMEM;
715+
}
716+
706717
return cachefiles_add_cache(cache);
707718
}
708719

fs/cachefiles/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ struct cachefiles_cache {
8686
unsigned bcull_percent; /* when to start culling (% blocks) */
8787
unsigned bstop_percent; /* when to stop allocating (% blocks) */
8888
unsigned bsize; /* cache's block size */
89-
unsigned bshift; /* min(ilog2(PAGE_SIZE / bsize), 0) */
89+
unsigned bshift; /* ilog2(bsize) */
9090
uint64_t frun; /* when to stop culling */
9191
uint64_t fcull; /* when to start culling */
9292
uint64_t fstop; /* when to stop allocating */

fs/cachefiles/io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres,
264264
ki->term_func = term_func;
265265
ki->term_func_priv = term_func_priv;
266266
ki->was_async = true;
267-
ki->b_writing = (len + (1 << cache->bshift)) >> cache->bshift;
267+
ki->b_writing = (len + (1 << cache->bshift) - 1) >> cache->bshift;
268268

269269
if (ki->term_func)
270270
ki->iocb.ki_complete = cachefiles_write_complete;

fs/cachefiles/namei.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ static bool __cachefiles_mark_inode_in_use(struct cachefiles_object *object,
2525
trace_cachefiles_mark_active(object, inode);
2626
can_use = true;
2727
} else {
28-
pr_notice("cachefiles: Inode already in use: %pd\n", dentry);
28+
trace_cachefiles_mark_failed(object, inode);
29+
pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n",
30+
dentry, inode->i_ino);
2931
}
3032

3133
return can_use;
@@ -101,6 +103,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
101103
subdir = lookup_one_len(dirname, dir, strlen(dirname));
102104
else
103105
subdir = ERR_PTR(ret);
106+
trace_cachefiles_lookup(NULL, dir, subdir);
104107
if (IS_ERR(subdir)) {
105108
trace_cachefiles_vfs_error(NULL, d_backing_inode(dir),
106109
PTR_ERR(subdir),
@@ -135,6 +138,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
135138
cachefiles_trace_mkdir_error);
136139
goto mkdir_error;
137140
}
141+
trace_cachefiles_mkdir(dir, subdir);
138142

139143
if (unlikely(d_unhashed(subdir))) {
140144
cachefiles_put_directory(subdir);
@@ -233,7 +237,7 @@ static int cachefiles_unlink(struct cachefiles_cache *cache,
233237
};
234238
int ret;
235239

236-
trace_cachefiles_unlink(object, dentry, why);
240+
trace_cachefiles_unlink(object, d_inode(dentry)->i_ino, why);
237241
ret = security_path_unlink(&path, dentry);
238242
if (ret < 0) {
239243
cachefiles_io_error(cache, "Unlink security error");
@@ -386,7 +390,7 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
386390
.new_dir = d_inode(cache->graveyard),
387391
.new_dentry = grave,
388392
};
389-
trace_cachefiles_rename(object, rep, grave, why);
393+
trace_cachefiles_rename(object, d_inode(rep)->i_ino, why);
390394
ret = cachefiles_inject_read_error();
391395
if (ret == 0)
392396
ret = vfs_rename(&rd);
@@ -617,7 +621,7 @@ bool cachefiles_look_up_object(struct cachefiles_object *object)
617621
object->d_name_len);
618622
else
619623
dentry = ERR_PTR(ret);
620-
trace_cachefiles_lookup(object, dentry);
624+
trace_cachefiles_lookup(object, fan, dentry);
621625
if (IS_ERR(dentry)) {
622626
if (dentry == ERR_PTR(-ENOENT))
623627
goto new_file;

fs/ceph/addr.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,6 @@ static void ceph_netfs_issue_op(struct netfs_read_subrequest *subreq)
297297
dout("%s: result %d\n", __func__, err);
298298
}
299299

300-
static void ceph_init_rreq(struct netfs_read_request *rreq, struct file *file)
301-
{
302-
}
303-
304300
static void ceph_readahead_cleanup(struct address_space *mapping, void *priv)
305301
{
306302
struct inode *inode = mapping->host;
@@ -312,7 +308,6 @@ static void ceph_readahead_cleanup(struct address_space *mapping, void *priv)
312308
}
313309

314310
static const struct netfs_read_request_ops ceph_netfs_read_ops = {
315-
.init_rreq = ceph_init_rreq,
316311
.is_cache_enabled = ceph_is_cache_enabled,
317312
.begin_cache_operation = ceph_begin_cache_operation,
318313
.issue_op = ceph_netfs_issue_op,

fs/fscache/volume.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ static void fscache_wait_on_volume_collision(struct fscache_volume *candidate,
142142
unsigned int collidee_debug_id)
143143
{
144144
wait_var_event_timeout(&candidate->flags,
145-
fscache_is_acquire_pending(candidate), 20 * HZ);
145+
!fscache_is_acquire_pending(candidate), 20 * HZ);
146146
if (!fscache_is_acquire_pending(candidate)) {
147147
pr_notice("Potential volume collision new=%08x old=%08x",
148148
candidate->debug_id, collidee_debug_id);
149149
fscache_stat(&fscache_n_volumes_collision);
150-
wait_var_event(&candidate->flags, fscache_is_acquire_pending(candidate));
150+
wait_var_event(&candidate->flags, !fscache_is_acquire_pending(candidate));
151151
}
152152
}
153153

fs/netfs/read_helper.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ static struct netfs_read_request *netfs_alloc_read_request(
5555
INIT_WORK(&rreq->work, netfs_rreq_work);
5656
refcount_set(&rreq->usage, 1);
5757
__set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
58-
ops->init_rreq(rreq, file);
58+
if (ops->init_rreq)
59+
ops->init_rreq(rreq, file);
5960
netfs_stat(&netfs_n_rh_rreq);
6061
}
6162

include/linux/fscache.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,11 @@ static inline void fscache_clear_inode_writeback(struct fscache_cookie *cookie,
665665
static inline
666666
void fscache_note_page_release(struct fscache_cookie *cookie)
667667
{
668+
/* If we've written data to the cache (HAVE_DATA) and there wasn't any
669+
* data in the cache when we started (NO_DATA_TO_READ), it may no
670+
* longer be true that we can skip reading from the cache - so clear
671+
* the flag that causes reads to be skipped.
672+
*/
668673
if (cookie &&
669674
test_bit(FSCACHE_COOKIE_HAVE_DATA, &cookie->flags) &&
670675
test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags))

0 commit comments

Comments
 (0)