From: Max Kellermann <max.kellermann@ionos.com>
To: idryomov@gmail.com, amarkuze@redhat.com,
ceph-devel@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Max Kellermann <max.kellermann@ionos.com>
Subject: [PATCH 10/12] fs/ceph/super.h: add helper ceph_in_snap()
Date: Fri, 12 Jun 2026 18:52:02 +0200 [thread overview]
Message-ID: <20260612165204.86137-11-max.kellermann@ionos.com> (raw)
In-Reply-To: <20260612165204.86137-1-max.kellermann@ionos.com>
Some code simplification.
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
---
fs/ceph/acl.c | 2 +-
fs/ceph/addr.c | 2 +-
fs/ceph/dir.c | 20 ++++++++++----------
fs/ceph/export.c | 8 ++++----
fs/ceph/file.c | 14 +++++++-------
fs/ceph/inode.c | 14 +++++++-------
fs/ceph/mds_client.c | 10 +++++-----
fs/ceph/quota.c | 4 ++--
fs/ceph/super.h | 8 ++++++++
fs/ceph/xattr.c | 4 ++--
10 files changed, 47 insertions(+), 39 deletions(-)
diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c
index 85d3dd48b167..dbc64ab60308 100644
--- a/fs/ceph/acl.c
+++ b/fs/ceph/acl.c
@@ -99,7 +99,7 @@ int ceph_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
struct timespec64 old_ctime = inode_get_ctime(inode);
umode_t new_mode = inode->i_mode, old_mode = inode->i_mode;
- if (ceph_snap(inode) != CEPH_NOSNAP) {
+ if (ceph_in_snap(inode)) {
ret = -EROFS;
goto out;
}
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index a11b5c633358..b114ef483937 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -2567,7 +2567,7 @@ int ceph_pool_perm_check(struct inode *inode, int need)
if (!S_ISREG(inode->i_mode))
return 0;
- if (ci->i_vino.snap != CEPH_NOSNAP) {
+ if (ceph_in_snap(inode)) {
/*
* Pool permission check needs to write to the first object.
* But for snapshot, head of the first object may have already
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 27ce9e55e947..c297cc57f88c 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -727,7 +727,7 @@ struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req,
struct ceph_client *cl = ceph_inode_to_client(parent);
/* .snap dir? */
- if (ceph_snap(parent) == CEPH_NOSNAP &&
+ if (!ceph_in_snap(parent) &&
strcmp(dentry->d_name.name, fsc->mount_options->snapdir_name) == 0) {
struct dentry *res;
struct inode *inode = ceph_get_snapdir(parent);
@@ -919,7 +919,7 @@ static int ceph_mknod(struct mnt_idmap *idmap, struct inode *dir,
struct ceph_acl_sec_ctx as_ctx = {};
int err;
- if (ceph_snap(dir) != CEPH_NOSNAP)
+ if (ceph_in_snap(dir))
return -EROFS;
err = ceph_wait_on_conflict_unlink(dentry);
@@ -1031,7 +1031,7 @@ static int ceph_symlink(struct mnt_idmap *idmap, struct inode *dir,
umode_t mode = S_IFLNK | 0777;
int err;
- if (ceph_snap(dir) != CEPH_NOSNAP)
+ if (ceph_in_snap(dir))
return -EROFS;
err = ceph_wait_on_conflict_unlink(dentry);
@@ -1115,7 +1115,7 @@ static struct dentry *ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
op = CEPH_MDS_OP_MKSNAP;
doutc(cl, "mksnap %llx.%llx/'%pd' dentry %p\n",
ceph_vinop(dir), dentry, dentry);
- } else if (ceph_snap(dir) == CEPH_NOSNAP) {
+ } else if (!ceph_in_snap(dir)) {
doutc(cl, "mkdir %llx.%llx/'%pd' dentry %p mode 0%ho\n",
ceph_vinop(dir), dentry, dentry, mode);
op = CEPH_MDS_OP_MKDIR;
@@ -1202,7 +1202,7 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
if (err)
return err;
- if (ceph_snap(dir) != CEPH_NOSNAP)
+ if (ceph_in_snap(dir))
return -EROFS;
err = fscrypt_prepare_link(old_dentry, dir, dentry);
@@ -1354,7 +1354,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
doutc(cl, "rmsnap %llx.%llx/'%pd' dn\n", ceph_vinop(dir),
dentry);
op = CEPH_MDS_OP_RMSNAP;
- } else if (ceph_snap(dir) == CEPH_NOSNAP) {
+ } else if (!ceph_in_snap(dir)) {
doutc(cl, "unlink/rmdir %llx.%llx/'%pd' inode %llx.%llx\n",
ceph_vinop(dir), dentry, ceph_vinop(inode));
op = d_is_dir(dentry) ?
@@ -1483,7 +1483,7 @@ static int ceph_rename(struct mnt_idmap *idmap, struct inode *old_dir,
if (ceph_snap(old_dir) != ceph_snap(new_dir))
return -EXDEV;
- if (ceph_snap(old_dir) != CEPH_NOSNAP) {
+ if (ceph_in_snap(old_dir)) {
if (old_dir == new_dir && ceph_snap(old_dir) == CEPH_SNAPDIR)
op = CEPH_MDS_OP_RENAMESNAP;
else
@@ -1981,7 +1981,7 @@ static int ceph_d_revalidate(struct inode *dir, const struct qstr *name,
mdsc = ceph_sb_to_fs_client(dir->i_sb)->mdsc;
/* always trust cached snapped dentries, snapdir dentry */
- if (ceph_snap(dir) != CEPH_NOSNAP) {
+ if (ceph_in_snap(dir)) {
doutc(cl, "%p '%pd' inode %p is SNAPPED\n", dentry,
dentry, inode);
valid = 1;
@@ -2065,7 +2065,7 @@ static int ceph_d_delete(const struct dentry *dentry)
/* won't release caps */
if (d_really_is_negative(dentry))
return 0;
- if (ceph_snap(d_inode(dentry)) != CEPH_NOSNAP)
+ if (ceph_in_snap(d_inode(dentry)))
return 0;
/* valid lease? */
di = ceph_dentry(dentry);
@@ -2120,7 +2120,7 @@ static void ceph_d_prune(struct dentry *dentry)
/* we hold d_lock, so d_parent is stable */
dir_ci = ceph_inode(d_inode(dentry->d_parent));
- if (dir_ci->i_vino.snap == CEPH_SNAPDIR)
+ if (ceph_in_snap(&dir_ci->netfs.inode))
return;
/* who calls d_delete() should also disable dcache readdir */
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index b2f2af104679..d132db40ba00 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -99,7 +99,7 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len,
static const int connected_handle_length = CEPH_FH_WITH_PARENT_SIZE;
int type;
- if (ceph_snap(inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(inode))
return ceph_encode_snapfh(inode, rawfh, max_len, parent_inode);
if (parent_inode && (*max_len < connected_handle_length)) {
@@ -372,7 +372,7 @@ static struct dentry *ceph_get_parent(struct dentry *child)
struct ceph_client *cl = ceph_inode_to_client(inode);
struct dentry *dn;
- if (ceph_snap(inode) != CEPH_NOSNAP) {
+ if (ceph_in_snap(inode)) {
struct inode* dir;
bool unlinked = false;
/* do not support non-directory */
@@ -456,7 +456,7 @@ static int __get_snap_name(struct dentry *parent, char *name,
if (ceph_ino(inode) != ceph_ino(dir))
goto out;
if (ceph_snap(inode) == CEPH_SNAPDIR) {
- if (ceph_snap(dir) == CEPH_NOSNAP) {
+ if (!ceph_in_snap(dir)) {
/*
* .get_name() from struct export_operations
* assumes that its 'name' parameter is pointing
@@ -555,7 +555,7 @@ static int ceph_get_name(struct dentry *parent, char *name,
struct ceph_mds_reply_info_parsed *rinfo;
int err;
- if (ceph_snap(inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(inode))
return __get_snap_name(parent, name, child);
mdsc = ceph_inode_to_fs_client(inode)->mdsc;
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index d54d71669176..00e62991a416 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -437,7 +437,7 @@ int ceph_open(struct inode *inode, struct file *file)
}
/* snapped files are read-only */
- if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE))
+ if (ceph_in_snap(inode) && (file->f_mode & FMODE_WRITE))
return -EROFS;
/* trivially open snapdir */
@@ -469,7 +469,7 @@ int ceph_open(struct inode *inode, struct file *file)
ceph_check_caps(ci, 0);
return ceph_init_file(inode, file, fmode);
- } else if (!do_sync && ceph_snap(inode) != CEPH_NOSNAP &&
+ } else if (!do_sync && ceph_in_snap(inode) &&
(ci->i_snap_caps & wanted) == wanted) {
__ceph_touch_fmode(ci, mdsc, fmode);
spin_unlock(&ci->i_ceph_lock);
@@ -1534,7 +1534,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
bool should_dirty = !write && user_backed_iter(iter);
bool sparse = ceph_test_mount_opt(fsc, SPARSEREAD);
- if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP)
+ if (write && ceph_in_snap(file_inode(file)))
return -EROFS;
doutc(cl, "sync_direct_%s on file %p %lld~%u snapc %p seq %lld\n",
@@ -1770,7 +1770,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
struct timespec64 mtime = current_time(inode);
size_t count = iov_iter_count(from);
- if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
+ if (ceph_in_snap(file_inode(file)))
return -EROFS;
doutc(cl, "on file %p %lld~%u snapc %p seq %lld\n", file, pos,
@@ -2405,7 +2405,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (ceph_inode_is_shutdown(inode))
return -ESTALE;
- if (ceph_snap(inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(inode))
return -EROFS;
prealloc_cf = ceph_alloc_cap_flush();
@@ -2757,7 +2757,7 @@ static long ceph_fallocate(struct file *file, int mode,
inode_lock(inode);
- if (ceph_snap(inode) != CEPH_NOSNAP) {
+ if (ceph_in_snap(inode)) {
ret = -EROFS;
goto unlock;
}
@@ -3046,7 +3046,7 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
return -EXDEV;
}
}
- if (ceph_snap(dst_inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(dst_inode))
return -EROFS;
/*
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index c0d88cf1f6e3..dcdbc24d1e21 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -765,7 +765,7 @@ void ceph_evict_inode(struct inode *inode)
* caps in i_snap_caps.
*/
if (ci->i_snap_realm) {
- if (ceph_snap(inode) == CEPH_NOSNAP) {
+ if (!ceph_in_snap(inode)) {
doutc(cl, " dropping residual ref to snap realm %p\n",
ci->i_snap_realm);
ceph_change_snap_realm(inode, NULL);
@@ -1065,7 +1065,7 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
info_caps = le32_to_cpu(info->cap.caps);
/* prealloc new cap struct */
- if (info_caps && ceph_snap(inode) == CEPH_NOSNAP) {
+ if (info_caps && !ceph_in_snap(inode)) {
new_cap = ceph_get_cap(mdsc, caps_reservation);
if (!new_cap)
return -ENOMEM;
@@ -1087,7 +1087,7 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
pool_ns = ceph_find_or_create_string(iinfo->pool_ns_data,
iinfo->pool_ns_len);
- if (ceph_snap(inode) != CEPH_NOSNAP && !ci->i_snapid_map)
+ if (ceph_in_snap(inode) && !ci->i_snapid_map)
ci->i_snapid_map = ceph_get_snapid_map(mdsc, ceph_snap(inode));
spin_lock(&ci->i_ceph_lock);
@@ -1332,7 +1332,7 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
/* were we issued a capability? */
if (info_caps) {
- if (ceph_snap(inode) == CEPH_NOSNAP) {
+ if (!ceph_in_snap(inode)) {
ceph_add_cap(inode, session,
le64_to_cpu(info->cap.cap_id),
info_caps,
@@ -1432,7 +1432,7 @@ static void __update_dentry_lease(struct inode *dir, struct dentry *dentry,
doutc(cl, "%p duration %lu ms ttl %lu\n", dentry, duration, ttl);
/* only track leases on regular dentries */
- if (ceph_snap(dir) != CEPH_NOSNAP)
+ if (ceph_in_snap(dir))
return;
if (mask & CEPH_LEASE_PRIMARY_LINK)
@@ -2929,7 +2929,7 @@ int ceph_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode);
int err;
- if (ceph_snap(inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(inode))
return -EROFS;
if (ceph_inode_is_shutdown(inode))
@@ -3184,7 +3184,7 @@ int ceph_getattr(struct mnt_idmap *idmap, const struct path *path,
valid_mask |= STATX_CHANGE_COOKIE;
}
- if (ceph_snap(inode) == CEPH_NOSNAP)
+ if (!ceph_in_snap(inode))
stat->dev = sb->s_dev;
else
stat->dev = ci->i_snapid_map ? ci->i_snapid_map->dev : 0;
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index ed17e0023705..1534a91342a7 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1308,7 +1308,7 @@ static struct inode *get_nonsnap_parent(struct dentry *dentry)
while (dentry && !IS_ROOT(dentry)) {
inode = d_inode_rcu(dentry);
- if (!inode || ceph_snap(inode) == CEPH_NOSNAP)
+ if (!inode || !ceph_in_snap(inode))
break;
dentry = dentry->d_parent;
}
@@ -1382,7 +1382,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
inode = d_inode(req->r_dentry);
if (inode)
ihold(inode);
- } else if (ceph_snap(dir) != CEPH_NOSNAP) {
+ } else if (ceph_in_snap(dir)) {
/* direct snapped/virtual snapdir requests
* based on parent dir inode */
inode = get_nonsnap_parent(parent);
@@ -2782,7 +2782,7 @@ char *ceph_mdsc_build_path(struct ceph_mds_client *mdsc, struct dentry *dentry,
spin_unlock(&cur->d_lock);
parent = dget_parent(cur);
} else if (for_wire && inode && dentry != cur &&
- ceph_snap(inode) == CEPH_NOSNAP) {
+ !ceph_in_snap(inode)) {
spin_unlock(&cur->d_lock);
pos++; /* get rid of any prepended '/' */
break;
@@ -2891,7 +2891,7 @@ static int build_dentry_path(struct ceph_mds_client *mdsc, struct dentry *dentry
rcu_read_lock();
if (!dir)
dir = d_inode_rcu(dentry->d_parent);
- if (dir && parent_locked && ceph_snap(dir) == CEPH_NOSNAP &&
+ if (dir && parent_locked && !ceph_in_snap(dir) &&
!IS_ENCRYPTED(dir)) {
path_info->vino.ino = ceph_ino(dir);
path_info->vino.snap = ceph_snap(dir);
@@ -2917,7 +2917,7 @@ static int build_inode_path(struct inode *inode, struct ceph_path_info *path_inf
struct dentry *dentry;
char *path;
- if (ceph_snap(inode) == CEPH_NOSNAP) {
+ if (!ceph_in_snap(inode)) {
path_info->vino.ino = ceph_ino(inode);
path_info->vino.snap = ceph_snap(inode);
path_info->pathlen = 0;
diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c
index 053d5bf0c9f0..08641d578a0b 100644
--- a/fs/ceph/quota.c
+++ b/fs/ceph/quota.c
@@ -223,7 +223,7 @@ static int get_quota_realm(struct ceph_mds_client *mdsc, struct inode *inode,
if (realmp)
*realmp = NULL;
- if (ceph_snap(inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(inode))
return 0;
restart:
@@ -341,7 +341,7 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
u64 max, rvalue;
bool exceeded = false;
- if (ceph_snap(inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(inode))
return false;
down_read(&mdsc->snap_rwsem);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index b1d38fa6647f..abdbffbdf0e6 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -601,6 +601,14 @@ static inline u64 ceph_snap(const struct inode *inode)
return ceph_inode(inode)->i_vino.snap;
}
+/**
+ * Is this inode in a ".snap" directory?
+ */
+static inline bool ceph_in_snap(const struct inode *inode)
+{
+ return ceph_snap(inode) != CEPH_NOSNAP;
+}
+
/**
* ceph_present_ino - format an inode number for presentation to userland
* @sb: superblock where the inode lives
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 9808eb10625d..c5e9ef656b5f 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -270,7 +270,7 @@ static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci)
bool ret = false;
spin_lock(&ci->i_ceph_lock);
if ((ci->i_max_files || ci->i_max_bytes) &&
- ci->i_vino.snap == CEPH_NOSNAP &&
+ !ceph_in_snap(&ci->netfs.inode) &&
ci->i_snap_realm &&
ci->i_snap_realm->ino == ci->i_vino.ino)
ret = true;
@@ -1193,7 +1193,7 @@ int __ceph_setxattr(struct inode *inode, const char *name,
bool check_realm = false;
bool lock_snap_rwsem = false;
- if (ceph_snap(inode) != CEPH_NOSNAP)
+ if (ceph_in_snap(inode))
return -EROFS;
vxattr = ceph_match_vxattr(inode, name);
--
2.47.3
next prev parent reply other threads:[~2026-06-12 16:52 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-12 16:51 [PATCH 00/12] fs/ceph: optimize struct layouts Max Kellermann
2026-06-12 16:51 ` [PATCH 01/12] fs/ceph/super: remove unused field `i_cap_migration_resv` Max Kellermann
2026-06-12 16:51 ` [PATCH 02/12] fs/ceph/super: make field `i_truncate_pagecache_size` optional Max Kellermann
2026-06-12 16:51 ` [PATCH 03/12] include/ceph/ceph_fs.h: convert `pool_id` to u32 Max Kellermann
2026-06-12 16:51 ` [PATCH 04/12] fs/ceph/super.h: convert ceph_inode_xattr fields to `bool` Max Kellermann
2026-06-12 16:51 ` [PATCH 05/12] fs/ceph/super.h: convert ceph_cap_snap.writing " Max Kellermann
2026-06-12 16:51 ` [PATCH 06/12] fs/ceph: consistently use `u32` for `time_warp_seq` Max Kellermann
2026-06-12 16:51 ` [PATCH 07/12] fs/ceph/super: reorder fields to eliminate padding holes Max Kellermann
2026-06-12 16:52 ` [PATCH 08/12] fs/ceph: remove i_truncate_mutex, use i_fragtree_mutex for both Max Kellermann
2026-06-12 16:52 ` [PATCH 09/12] fs/ceph/super.h: add `const` to helpers Max Kellermann
2026-06-12 16:52 ` Max Kellermann [this message]
2026-06-12 16:52 ` [PATCH 11/12] fs/ceph: use ceph_vino() etc. instead of accessing i_vino directly Max Kellermann
2026-06-12 16:52 ` [PATCH 12/12] fs/ceph: remove redundant inode number from ceph_inode_info Max Kellermann
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=20260612165204.86137-11-max.kellermann@ionos.com \
--to=max.kellermann@ionos.com \
--cc=amarkuze@redhat.com \
--cc=ceph-devel@vger.kernel.org \
--cc=idryomov@gmail.com \
--cc=linux-kernel@vger.kernel.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