diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-03-07 03:34:50 +0100 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-03-25 18:51:55 +0100 |
commit | 315f24088048a51eed341c53be66ea477a3c7d16 (patch) | |
tree | b0947756198ee556f500e2b5dd001104fec003b8 /fs/ceph/super.h | |
parent | ceph: don't request vxattrs from MDS (diff) | |
download | linux-315f24088048a51eed341c53be66ea477a3c7d16.tar.xz linux-315f24088048a51eed341c53be66ea477a3c7d16.zip |
ceph: fix security xattr deadlock
When security is enabled, security module can call filesystem's
getxattr/setxattr callbacks during d_instantiate(). For cephfs,
d_instantiate() is usually called by MDS' dispatch thread, while
handling MDS reply. If the MDS reply does not include xattrs and
corresponding caps, getxattr/setxattr need to send a new request
to MDS and waits for the reply. This makes MDS' dispatch sleep,
nobody handles later MDS replies.
The fix is make sure lookup/atomic_open reply include xattrs and
corresponding caps. So getxattr can be handled by cached xattrs.
This requires some modification to both MDS and request message.
(Client tells MDS what caps it wants; MDS encodes proper caps in
the reply)
Smack security module may call setxattr during d_instantiate().
Unlike getxattr, we can't force MDS to issue CEPH_CAP_XATTR_EXCL
to us. So just make setxattr return error when called by MDS'
dispatch thread.
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/super.h')
-rw-r--r-- | fs/ceph/super.h | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 57ac43d64322..2d48138da58e 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -468,7 +468,7 @@ static inline struct inode *ceph_find_inode(struct super_block *sb, #define CEPH_I_POOL_PERM (1 << 4) /* pool rd/wr bits are valid */ #define CEPH_I_POOL_RD (1 << 5) /* can read from pool */ #define CEPH_I_POOL_WR (1 << 6) /* can write to pool */ - +#define CEPH_I_SEC_INITED (1 << 7) /* security initialized */ static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci, long long release_count, @@ -804,6 +804,20 @@ extern void __init ceph_xattr_init(void); extern void ceph_xattr_exit(void); extern const struct xattr_handler *ceph_xattr_handlers[]; +#ifdef CONFIG_SECURITY +extern bool ceph_security_xattr_deadlock(struct inode *in); +extern bool ceph_security_xattr_wanted(struct inode *in); +#else +static inline bool ceph_security_xattr_deadlock(struct inode *in) +{ + return false; +} +static inline bool ceph_security_xattr_wanted(struct inode *in) +{ + return false; +} +#endif + /* acl.c */ struct ceph_acls_info { void *default_acl; |