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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.