From: David Howells <dhowells@redhat.com>
To: Trond Myklebust <trondmy@hammerspace.com>,
Anna Schumaker <anna.schumaker@netapp.com>,
Steve French <sfrench@samba.org>,
Dominique Martinet <asmadeus@codewreck.org>
Cc: dhowells@redhat.com, Jeff Layton <jlayton@redhat.com>,
Matthew Wilcox <willy@infradead.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
linux-cachefs@redhat.com, linux-afs@lists.infradead.org,
linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org,
ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 53/76] fscache: Implement "will_modify" parameter on fscache_use_cookie()
Date: Fri, 20 Nov 2020 15:13:55 +0000 [thread overview]
Message-ID: <160588523556.3465195.5875233390723322661.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <160588455242.3465195.3214733858273019178.stgit@warthog.procyon.org.uk>
Implement the "will_modify" parameter passed to fscache_use_cookie().
Setting this to true will henceforth cause the affected object to be marked
as dirty on disk, subject to conflict resolution in the event that power
failure or a crash occurs or the filesystem operates in disconnected mode.
The dirty flag is removed when the fscache_object is discarded from memory.
A cache hook is provided to prepare for writing - and this can be used to
mark the object on disk.
Signed-off-by: David Howells <dhowells@redhat.com>
---
fs/cachefiles/interface.c | 68 +++++++++++++++++++++++++++++++++++++++++
fs/cachefiles/internal.h | 2 +
fs/cachefiles/xattr.c | 27 ++++++++++++++++
fs/fscache/cookie.c | 15 ++++++++-
fs/fscache/internal.h | 1 +
fs/fscache/obj.c | 28 ++++++++++++++---
include/linux/fscache-cache.h | 4 ++
7 files changed, 137 insertions(+), 8 deletions(-)
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 4da10640611c..56ae8d956174 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -208,14 +208,81 @@ static void cachefiles_update_object(struct fscache_object *_object)
_leave("");
}
+/*
+ * Shorten the backing object to discard any dirty data and free up
+ * any unused granules.
+ */
+static bool cachefiles_shorten_object(struct cachefiles_object *object, loff_t new_size)
+{
+ struct cachefiles_cache *cache;
+ struct inode *inode;
+ struct path path;
+ loff_t i_size;
+ int ret;
+
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+ path.mnt = cache->mnt;
+ path.dentry = object->dentry;
+
+ inode = d_inode(object->dentry);
+ trace_cachefiles_trunc(object, inode, i_size_read(inode), new_size);
+ ret = vfs_truncate(&path, new_size);
+ if (ret < 0) {
+ cachefiles_io_error_obj(object, "Trunc-to-size failed %d", ret);
+ cachefiles_remove_object_xattr(cache, object->dentry);
+ return false;
+ }
+
+ new_size = round_up(new_size, CACHEFILES_DIO_BLOCK_SIZE);
+ i_size = i_size_read(inode);
+ if (i_size < new_size) {
+ trace_cachefiles_trunc(object, inode, i_size, new_size);
+ ret = vfs_truncate(&path, new_size);
+ if (ret < 0) {
+ cachefiles_io_error_obj(object, "Trunc-to-dio-size failed %d", ret);
+ cachefiles_remove_object_xattr(cache, object->dentry);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
+ * Trim excess stored data off of an object.
+ */
+static bool cachefiles_trim_object(struct cachefiles_object *object)
+{
+ loff_t object_size;
+
+ _enter("{OBJ%x}", object->fscache.debug_id);
+
+ object_size = object->fscache.cookie->object_size;
+ if (i_size_read(d_inode(object->dentry)) <= object_size)
+ return true;
+
+ return cachefiles_shorten_object(object, object_size);
+}
+
/*
* Commit changes to the object as we drop it.
*/
static bool cachefiles_commit_object(struct cachefiles_object *object,
struct cachefiles_cache *cache)
{
+ bool update = false;
+
if (object->content_map_changed)
cachefiles_save_content_map(object);
+ if (test_and_clear_bit(FSCACHE_OBJECT_LOCAL_WRITE, &object->fscache.flags))
+ update = true;
+ if (test_and_clear_bit(FSCACHE_OBJECT_NEEDS_UPDATE, &object->fscache.flags))
+ update = true;
+ if (update) {
+ if (cachefiles_trim_object(object))
+ cachefiles_set_object_xattr(object);
+ }
if (test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags))
return cachefiles_commit_tmpfile(cache, object);
@@ -591,5 +658,6 @@ const struct fscache_cache_ops cachefiles_cache_ops = {
.get_object_usage = cachefiles_get_object_usage,
.sync_cache = cachefiles_sync_cache,
.begin_operation = cachefiles_begin_operation,
+ .prepare_to_write = cachefiles_prepare_to_write,
.display_object = cachefiles_display_object,
};
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index af68564598d5..e2d06c0860a2 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -258,7 +258,7 @@ extern int cachefiles_set_object_xattr(struct cachefiles_object *object);
extern int cachefiles_check_auxdata(struct cachefiles_object *object);
extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
struct dentry *dentry);
-
+extern int cachefiles_prepare_to_write(struct fscache_object *object);
/*
* error handling
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index 991ecda1f140..2f8623a7b864 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -124,6 +124,8 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
buf->zero_point = cpu_to_be64(object->fscache.cookie->zero_point);
buf->type = object->fscache.cookie->type;
buf->content = object->content_info;
+ if (test_bit(FSCACHE_OBJECT_LOCAL_WRITE, &object->fscache.flags))
+ buf->content = CACHEFILES_CONTENT_DIRTY;
if (len > 0)
memcpy(buf->data, fscache_get_aux(object->fscache.cookie), len);
@@ -184,6 +186,10 @@ int cachefiles_check_auxdata(struct cachefiles_object *object)
why = cachefiles_coherency_check_aux;
} else if (be64_to_cpu(buf->object_size) != object->fscache.cookie->object_size) {
why = cachefiles_coherency_check_objsize;
+ } else if (buf->content == CACHEFILES_CONTENT_DIRTY) {
+ // TODO: Begin conflict resolution
+ pr_warn("Dirty object in cache\n");
+ why = cachefiles_coherency_check_dirty;
} else {
object->fscache.cookie->zero_point = be64_to_cpu(buf->zero_point);
object->content_info = buf->content;
@@ -219,3 +225,24 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
_leave(" = %d", ret);
return ret;
}
+
+/*
+ * Stick a marker on the cache object to indicate that it's dirty.
+ */
+int cachefiles_prepare_to_write(struct fscache_object *_object)
+{
+ int ret;
+ const struct cred *saved_cred;
+ struct cachefiles_object *object =
+ container_of(_object, struct cachefiles_object, fscache);
+ struct cachefiles_cache *cache =
+ container_of(_object->cache, struct cachefiles_cache, cache);
+
+ _enter("c=%08x", object->fscache.cookie->debug_id);
+
+ cachefiles_begin_secure(cache, &saved_cred);
+ ret = cachefiles_set_object_xattr(object);
+ cachefiles_end_secure(cache, saved_cred);
+
+ return ret;
+}
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index d20028535a86..bfea035af06d 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -363,6 +363,8 @@ EXPORT_SYMBOL(__fscache_acquire_cookie);
void __fscache_use_cookie(struct fscache_cookie *cookie, bool will_modify)
{
enum fscache_cookie_stage stage;
+ struct fscache_object *object;
+ bool write_set;
_enter("c=%08x", cookie->debug_id);
@@ -398,8 +400,17 @@ void __fscache_use_cookie(struct fscache_cookie *cookie, bool will_modify)
case FSCACHE_COOKIE_STAGE_NO_DATA_YET:
case FSCACHE_COOKIE_STAGE_ACTIVE:
case FSCACHE_COOKIE_STAGE_INVALIDATING:
- // TODO: Handle will_modify
- spin_unlock(&cookie->lock);
+ if (will_modify) {
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+ write_set = test_and_set_bit(FSCACHE_OBJECT_LOCAL_WRITE,
+ &object->flags);
+ spin_unlock(&cookie->lock);
+ if (!write_set)
+ fscache_dispatch(cookie, object, 0, fscache_prepare_to_write);
+ } else {
+ spin_unlock(&cookie->lock);
+ }
break;
case FSCACHE_COOKIE_STAGE_FAILED:
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index 73568e84fe3d..3c408da2c837 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -152,6 +152,7 @@ extern void fscache_lookup_object(struct fscache_cookie *, struct fscache_object
extern void fscache_invalidate_object(struct fscache_cookie *, struct fscache_object *, int);
extern void fscache_drop_object(struct fscache_cookie *, struct fscache_object *, bool);
extern void fscache_relinquish_objects(struct fscache_cookie *, struct fscache_object *, int);
+extern void fscache_prepare_to_write(struct fscache_cookie *, struct fscache_object *, int);
/*
* object-list.c
diff --git a/fs/fscache/obj.c b/fs/fscache/obj.c
index 60c70c0e474d..a36de6af2182 100644
--- a/fs/fscache/obj.c
+++ b/fs/fscache/obj.c
@@ -117,7 +117,8 @@ static bool fscache_wrangle_object(struct fscache_cookie *cookie,
* Create an object chain, making sure that the index chain is fully created.
*/
static struct fscache_object *fscache_lookup_object_chain(struct fscache_cookie *cookie,
- struct fscache_cache *cache)
+ struct fscache_cache *cache,
+ bool will_modify)
{
struct fscache_object *object = NULL, *parent, *xobject;
@@ -131,7 +132,7 @@ static struct fscache_object *fscache_lookup_object_chain(struct fscache_cookie
spin_unlock(&cookie->lock);
/* Recurse to look up/create the parent index. */
- parent = fscache_lookup_object_chain(cookie->parent, cache);
+ parent = fscache_lookup_object_chain(cookie->parent, cache, false);
if (!parent)
goto error;
@@ -146,6 +147,9 @@ static struct fscache_object *fscache_lookup_object_chain(struct fscache_cookie
if (!object)
goto error;
+ if (will_modify)
+ __set_bit(FSCACHE_OBJECT_LOCAL_WRITE, &object->flags);
+
xobject = fscache_attach_object(cookie, object);
if (xobject != object) {
fscache_do_put_object(object, fscache_obj_put_alloc_dup);
@@ -207,7 +211,8 @@ static struct fscache_object *fscache_lookup_object_chain(struct fscache_cookie
* - this must make sure the index chain is instantiated and instantiate the
* object representation too
*/
-static void fscache_lookup_object_locked(struct fscache_cookie *cookie)
+static void fscache_lookup_object_locked(struct fscache_cookie *cookie,
+ bool will_modify)
{
struct fscache_object *object;
struct fscache_cache *cache;
@@ -225,12 +230,16 @@ static void fscache_lookup_object_locked(struct fscache_cookie *cookie)
_debug("cache %s", cache->tag->name);
- object = fscache_lookup_object_chain(cookie, cache);
+ object = fscache_lookup_object_chain(cookie, cache, will_modify);
if (!object) {
_leave(" [fail]");
return;
}
+ if (will_modify &&
+ test_and_set_bit(FSCACHE_OBJECT_LOCAL_WRITE, &object->flags))
+ fscache_prepare_to_write(cookie, object, 0);
+
fscache_do_put_object(object, fscache_obj_put);
_leave(" [done]");
}
@@ -239,7 +248,7 @@ void fscache_lookup_object(struct fscache_cookie *cookie,
struct fscache_object *object, int param)
{
down_read(&fscache_addremove_sem);
- fscache_lookup_object_locked(cookie);
+ fscache_lookup_object_locked(cookie, param);
up_read(&fscache_addremove_sem);
__fscache_unuse_cookie(cookie, NULL, NULL);
}
@@ -354,3 +363,12 @@ void fscache_relinquish_objects(struct fscache_cookie *cookie,
fscache_drop_cookie(cookie);
}
+
+/*
+ * Prepare a cache object to be written to.
+ */
+void fscache_prepare_to_write(struct fscache_cookie *cookie,
+ struct fscache_object *object, int param)
+{
+ object->cache->ops->prepare_to_write(object);
+}
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index a0bb526735b5..eb303deb39c1 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -142,6 +142,9 @@ struct fscache_cache_ops {
/* Begin an operation on a cache object */
void (*begin_operation)(struct fscache_op_resources *opr);
+ /* Prepare to write to a live cache object */
+ int (*prepare_to_write)(struct fscache_object *object);
+
/* Display object info in /proc/fs/fscache/objects */
int (*display_object)(struct seq_file *m, struct fscache_object *object);
};
@@ -170,6 +173,7 @@ struct fscache_object {
spinlock_t lock; /* state and operations lock */
unsigned long flags;
+#define FSCACHE_OBJECT_LOCAL_WRITE 1 /* T if the object is being modified locally */
#define FSCACHE_OBJECT_NEEDS_INVAL 8 /* T if object needs invalidation */
#define FSCACHE_OBJECT_NEEDS_UPDATE 9 /* T if object attrs need writing to disk */
next prev parent reply other threads:[~2020-11-20 15:15 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-20 15:02 [RFC PATCH 00/76] fscache: Modernisation David Howells
2020-11-20 15:02 ` [RFC PATCH 01/76] nfs, cifs, ceph, 9p: Disable use of fscache prior to its rewrite David Howells
2020-11-20 15:02 ` [RFC PATCH 02/76] afs: Disable use of the fscache I/O routines David Howells
2020-11-20 15:03 ` [RFC PATCH 03/76] fscache: Add a cookie debug ID and use that in traces David Howells
2020-11-20 15:03 ` [RFC PATCH 04/76] fscache: Procfile to display cookies David Howells
2020-11-20 15:03 ` [RFC PATCH 05/76] fscache: Remove the old I/O API David Howells
2020-11-20 15:03 ` [RFC PATCH 06/76] fscache: Remove the netfs data from the cookie David Howells
2020-11-20 15:04 ` [RFC PATCH 07/76] fscache: Remove struct fscache_cookie_def David Howells
2020-11-20 15:04 ` [RFC PATCH 08/76] fscache: Remove store_limit* from struct fscache_object David Howells
2020-11-20 15:04 ` [RFC PATCH 09/76] fscache: Remove fscache_check_consistency() David Howells
2020-11-20 15:04 ` [RFC PATCH 10/76] fscache: Remove fscache_attr_changed() David Howells
2020-11-20 15:04 ` [RFC PATCH 11/76] fscache: Remove obsolete stats David Howells
2020-11-20 15:05 ` [RFC PATCH 12/76] fscache: Remove old I/O tracepoints David Howells
2020-11-20 15:05 ` [RFC PATCH 13/76] fscache: Temporarily disable fscache_invalidate() David Howells
2020-11-20 15:05 ` [RFC PATCH 14/76] fscache: Remove the I/O operation manager David Howells
2020-11-20 15:05 ` [RFC PATCH 15/76] fscache: Change %p in format strings to something else David Howells
2020-11-20 15:06 ` [RFC PATCH 16/76] cachefiles: " David Howells
2020-11-20 15:06 ` [RFC PATCH 17/76] iov_iter: Add ITER_XARRAY David Howells
2020-11-20 15:06 ` [RFC PATCH 18/76] vm: Add wait/unlock functions for PG_fscache David Howells
2020-11-20 15:06 ` [RFC PATCH 19/76] mm: Implement readahead_control pageset expansion David Howells
2020-11-20 15:06 ` [RFC PATCH 20/76] mm: Stop generic_file_buffered_read() from grabbing a superfluous page David Howells
2020-11-20 15:07 ` [RFC PATCH 21/76] vfs: Export rw_verify_area() for use by cachefiles David Howells
2020-11-20 15:07 ` [RFC PATCH 22/76] vfs: Provide S_CACHE_FILE inode flag David Howells
2020-11-20 15:07 ` [RFC PATCH 23/76] cachefiles: Remove tree of active files and use " David Howells
2020-11-20 15:07 ` [RFC PATCH 24/76] fscache: Provide a simple thread pool for running ops asynchronously David Howells
2020-11-20 15:08 ` [RFC PATCH 26/76] fscache: Rewrite the I/O API based on iov_iter David Howells
2020-11-20 15:08 ` [RFC PATCH 27/76] fscache: Keep track of size of a file last set independently on the server David Howells
2020-11-20 15:08 ` [RFC PATCH 28/76] fscache, cachefiles: Fix disabled histogram warnings David Howells
2020-11-20 15:08 ` [RFC PATCH 29/76] fscache: Recast assertion in terms of cookie not being an index David Howells
2020-11-20 15:08 ` [RFC PATCH 30/76] vfs, fscache: Force ->write_inode() to occur if cookie pinned for writeback David Howells
2020-11-20 15:09 ` [RFC PATCH 31/76] fscache: Allow ->put_super() to be used to wait for cache operations David Howells
2020-11-20 15:09 ` [RFC PATCH 32/76] netfs: Make a netfs helper module David Howells
2020-11-20 15:09 ` [RFC PATCH 33/76] netfs: Provide readahead and readpage netfs helpers David Howells
2020-11-20 15:09 ` [RFC PATCH 34/76] netfs: Use the cache David Howells
2020-11-20 15:10 ` [RFC PATCH 35/76] fscache: read-helper: Add tracepoints David Howells
2020-11-20 15:10 ` [RFC PATCH 36/76] cachefiles: Remove some redundant checks on unsigned values David Howells
2020-11-20 15:10 ` [RFC PATCH 37/76] cachefiles: trace: Log coherency checks David Howells
2020-11-20 15:10 ` [RFC PATCH 38/76] cachefiles: Split cachefiles_drop_object() up a bit David Howells
2020-11-20 15:11 ` [RFC PATCH 39/76] cachefiles: Implement new fscache I/O backend API David Howells
2020-11-20 15:11 ` [RFC PATCH 40/76] cachefiles: Merge object->backer into object->dentry David Howells
2020-11-20 15:11 ` [RFC PATCH 41/76] cachefiles: Implement a content-present indicator and bitmap David Howells
2020-11-20 15:11 ` [RFC PATCH 42/76] cachefiles: Shape requests from the fscache read helper David Howells
2020-11-20 15:11 ` [RFC PATCH 43/76] cachefiles: Round the cachefile size up to DIO block size David Howells
2020-11-20 15:12 ` [RFC PATCH 44/76] cachefiles: Implement read and write parts of new I/O API David Howells
2020-11-20 15:12 ` [RFC PATCH 45/76] cachefiles: Add I/O tracepoints David Howells
2020-11-20 15:12 ` [RFC PATCH 46/76] fscache: Display cache-specific data in /proc/fs/fscache/objects David Howells
2020-11-20 15:12 ` [RFC PATCH 47/76] fscache: Remove more obsolete stats David Howells
2020-11-20 15:12 ` [RFC PATCH 48/76] fscache: Always create /proc/fs/fscache/stats if configured David Howells
2020-11-20 15:13 ` [RFC PATCH 49/76] netfs: Stats David Howells
2020-11-20 15:13 ` [RFC PATCH 50/76] fscache: New stats David Howells
2020-11-20 15:13 ` [RFC PATCH 51/76] fscache, cachefiles: Rewrite invalidation David Howells
2020-11-20 15:13 ` [RFC PATCH 52/76] fscache: disable cookie when doing an invalidation for DIO write David Howells
2020-11-20 15:13 ` David Howells [this message]
2020-11-20 15:14 ` [RFC PATCH 54/76] fscache: Provide resize operation David Howells
2020-11-20 15:14 ` [RFC PATCH 55/76] fscache: Remove the update operation David Howells
2020-11-20 15:14 ` [RFC PATCH 56/76] afs: Pass page into dirty region helpers to provide THP size David Howells
2020-11-20 15:14 ` [RFC PATCH 57/76] afs: Print the operation debug_id when logging an unexpected data version David Howells
2020-11-20 15:14 ` [RFC PATCH 58/76] afs: Move key to afs_read struct David Howells
2020-11-20 15:15 ` [RFC PATCH 59/76] afs: Don't truncate iter during data fetch David Howells
2020-11-20 15:15 ` [RFC PATCH 60/76] afs: Log remote unmarshalling errors David Howells
2020-11-20 15:15 ` [RFC PATCH 61/76] afs: Set up the iov_iter before calling afs_extract_data() David Howells
2020-11-20 15:15 ` [RFC PATCH 62/76] afs: Use ITER_XARRAY for writing David Howells
2020-11-20 15:16 ` [RFC PATCH 63/76] afs: Wait on PG_fscache before modifying/releasing a page David Howells
2020-11-20 15:16 ` [RFC PATCH 64/76] afs: Extract writeback extension into its own function David Howells
2020-11-20 15:16 ` [RFC PATCH 65/76] afs: Prepare for use of THPs David Howells
2020-11-20 15:16 ` [RFC PATCH 66/76] afs: Use the fs operation ops to handle FetchData completion David Howells
2020-11-20 15:17 ` [RFC PATCH 67/76] afs: Use new fscache read helper API David Howells
2020-11-20 15:17 ` [RFC PATCH 68/76] netfs: Add write_begin helper David Howells
2020-11-20 15:17 ` [RFC PATCH 69/76] fscache: Add support for writing to the cache David Howells
2020-11-20 15:17 ` [RFC PATCH 70/76] afs: Use the fscache_write_begin() helper David Howells
2020-11-20 15:18 ` [RFC PATCH 71/76] afs: Copy local writes to the cache when writing to the server David Howells
2020-11-20 15:18 ` [RFC PATCH 72/76] afs: Invoke fscache_resize_cookie() when handling ATTR_SIZE for setattr David Howells
2020-11-20 15:18 ` [RFC PATCH 73/76] afs: Add O_DIRECT read support David Howells
2020-11-20 15:18 ` [RFC PATCH 74/76] afs: Skip truncation on the server of data we haven't written yet David Howells
2020-11-20 15:19 ` [RFC PATCH 75/76] afs: Make afs_write_begin() return the THP subpage David Howells
2020-11-20 15:19 ` [RFC PATCH 76/76] afs: Fix speculative status fetch going out of order wrt to modifications David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=160588523556.3465195.5875233390723322661.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=anna.schumaker@netapp.com \
--cc=asmadeus@codewreck.org \
--cc=ceph-devel@vger.kernel.org \
--cc=jlayton@redhat.com \
--cc=linux-afs@lists.infradead.org \
--cc=linux-cachefs@redhat.com \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=sfrench@samba.org \
--cc=trondmy@hammerspace.com \
--cc=v9fs-developer@lists.sourceforge.net \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).