Commit 93ce9358 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'davidh' (fixes from David Howells)

Merge misc fixes from David Howells:
 "A set of patches for watch_queue filter issues noted by Jann. I've
  added in a cleanup patch from Christophe Jaillet to convert to using
  formal bitmap specifiers for the note allocation bitmap.

  Also two filesystem fixes (afs and cachefiles)"

* emailed patches from David Howells <dhowells@redhat.com>:
  cachefiles: Fix volume coherency attribute
  afs: Fix potential thrashing in afs writeback
  watch_queue: Make comment about setting ->defunct more accurate
  watch_queue: Fix lack of barrier/sync/lock between post and read
  watch_queue: Free the alloc bitmap when the watch_queue is torn down
  watch_queue: Fix the alloc bitmap size to reflect notes allocated
  watch_queue: Use the bitmap API when applicable
  watch_queue: Fix to always request a pow-of-2 pipe ring size
  watch_queue: Fix to release page in ->release()
  watch_queue, pipe: Free watchqueue state after clearing pipe ring
  watch_queue: Fix filter limit check
parents 79b00034 413a4a6b
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -703,7 +703,7 @@ static int afs_writepages_region(struct address_space *mapping,
	struct folio *folio;
	struct page *head_page;
	ssize_t ret;
	int n;
	int n, skips = 0;

	_enter("%llx,%llx,", start, end);

@@ -754,8 +754,15 @@ static int afs_writepages_region(struct address_space *mapping,
#ifdef CONFIG_AFS_FSCACHE
				folio_wait_fscache(folio);
#endif
			} else {
				start += folio_size(folio);
			}
			folio_put(folio);
			if (wbc->sync_mode == WB_SYNC_NONE) {
				if (skips >= 5 || need_resched())
					break;
				skips++;
			}
			continue;
		}

+20 −3
Original line number Diff line number Diff line
@@ -28,6 +28,11 @@ struct cachefiles_xattr {
static const char cachefiles_xattr_cache[] =
	XATTR_USER_PREFIX "CacheFiles.cache";

struct cachefiles_vol_xattr {
	__be32	reserved;	/* Reserved, should be 0 */
	__u8	data[];		/* netfs volume coherency data */
} __packed;

/*
 * set the state xattr on a cache file
 */
@@ -185,6 +190,7 @@ void cachefiles_prepare_to_write(struct fscache_cookie *cookie)
 */
bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
{
	struct cachefiles_vol_xattr *buf;
	unsigned int len = volume->vcookie->coherency_len;
	const void *p = volume->vcookie->coherency;
	struct dentry *dentry = volume->dentry;
@@ -192,10 +198,17 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)

	_enter("%x,#%d", volume->vcookie->debug_id, len);

	len += sizeof(*buf);
	buf = kmalloc(len, GFP_KERNEL);
	if (!buf)
		return false;
	buf->reserved = cpu_to_be32(0);
	memcpy(buf->data, p, len);

	ret = cachefiles_inject_write_error();
	if (ret == 0)
		ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
				   p, len, 0);
				   buf, len, 0);
	if (ret < 0) {
		trace_cachefiles_vfs_error(NULL, d_inode(dentry), ret,
					   cachefiles_trace_setxattr_error);
@@ -209,6 +222,7 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
					       cachefiles_coherency_vol_set_ok);
	}

	kfree(buf);
	_leave(" = %d", ret);
	return ret == 0;
}
@@ -218,7 +232,7 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
 */
int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)
{
	struct cachefiles_xattr *buf;
	struct cachefiles_vol_xattr *buf;
	struct dentry *dentry = volume->dentry;
	unsigned int len = volume->vcookie->coherency_len;
	const void *p = volume->vcookie->coherency;
@@ -228,6 +242,7 @@ int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)

	_enter("");

	len += sizeof(*buf);
	buf = kmalloc(len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
@@ -245,7 +260,9 @@ int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)
					"Failed to read xattr with error %zd", xlen);
		}
		why = cachefiles_coherency_vol_check_xattr;
	} else if (memcmp(buf->data, p, len) != 0) {
	} else if (buf->reserved != cpu_to_be32(0)) {
		why = cachefiles_coherency_vol_check_resv;
	} else if (memcmp(buf->data, p, len - sizeof(*buf)) != 0) {
		why = cachefiles_coherency_vol_check_cmp;
	} else {
		why = cachefiles_coherency_vol_check_ok;
+7 −4
Original line number Diff line number Diff line
@@ -253,7 +253,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
	 */
	was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
	for (;;) {
		unsigned int head = pipe->head;
		/* Read ->head with a barrier vs post_one_notification() */
		unsigned int head = smp_load_acquire(&pipe->head);
		unsigned int tail = pipe->tail;
		unsigned int mask = pipe->ring_size - 1;

@@ -831,10 +832,8 @@ void free_pipe_info(struct pipe_inode_info *pipe)
	int i;

#ifdef CONFIG_WATCH_QUEUE
	if (pipe->watch_queue) {
	if (pipe->watch_queue)
		watch_queue_clear(pipe->watch_queue);
		put_watch_queue(pipe->watch_queue);
	}
#endif

	(void) account_pipe_buffers(pipe->user, pipe->nr_accounted, 0);
@@ -844,6 +843,10 @@ void free_pipe_info(struct pipe_inode_info *pipe)
		if (buf->ops)
			pipe_buf_release(pipe, buf);
	}
#ifdef CONFIG_WATCH_QUEUE
	if (pipe->watch_queue)
		put_watch_queue(pipe->watch_queue);
#endif
	if (pipe->tmp_page)
		__free_page(pipe->tmp_page);
	kfree(pipe->bufs);
+2 −1
Original line number Diff line number Diff line
@@ -28,7 +28,8 @@ struct watch_type_filter {
struct watch_filter {
	union {
		struct rcu_head	rcu;
		unsigned long	type_filter[2];	/* Bitmask of accepted types */
		/* Bitmask of accepted types */
		DECLARE_BITMAP(type_filter, WATCH_TYPE__NR);
	};
	u32			nr_filters;	/* Number of filters */
	struct watch_type_filter filters[];
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ enum cachefiles_coherency_trace {
	cachefiles_coherency_set_ok,
	cachefiles_coherency_vol_check_cmp,
	cachefiles_coherency_vol_check_ok,
	cachefiles_coherency_vol_check_resv,
	cachefiles_coherency_vol_check_xattr,
	cachefiles_coherency_vol_set_fail,
	cachefiles_coherency_vol_set_ok,
@@ -139,6 +140,7 @@ enum cachefiles_error_trace {
	EM(cachefiles_coherency_set_ok,		"SET ok  ")		\
	EM(cachefiles_coherency_vol_check_cmp,	"VOL BAD cmp ")		\
	EM(cachefiles_coherency_vol_check_ok,	"VOL OK      ")		\
	EM(cachefiles_coherency_vol_check_resv,	"VOL BAD resv")	\
	EM(cachefiles_coherency_vol_check_xattr,"VOL BAD xatt")		\
	EM(cachefiles_coherency_vol_set_fail,	"VOL SET fail")		\
	E_(cachefiles_coherency_vol_set_ok,	"VOL SET ok  ")
Loading