]>
git.proxmox.com Git - ceph.git/blob - ceph/src/os/filestore/chain_xattr.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef __CEPH_OSD_CHAIN_XATTR_H
5 #define __CEPH_OSD_CHAIN_XATTR_H
7 #include "include/compat.h"
10 #include "common/xattr.h"
11 #include "include/assert.h"
12 #include "include/buffer_fwd.h"
14 #if defined(__linux__)
15 #include <linux/limits.h>
16 #define CHAIN_XATTR_MAX_NAME_LEN ((XATTR_NAME_MAX + 1) / 2)
17 #elif defined(__APPLE__)
18 #include <sys/xattr.h>
19 #define CHAIN_XATTR_MAX_NAME_LEN ((XATTR_MAXNAMELEN + 1) / 2)
21 #define CHAIN_XATTR_MAX_NAME_LEN 128
24 #define CHAIN_XATTR_MAX_BLOCK_LEN 2048
27 * XFS will only inline xattrs < 255 bytes, so for xattrs that are
28 * likely to fit in the inode, stripe over short xattrs.
30 #define CHAIN_XATTR_SHORT_BLOCK_LEN 250
31 #define CHAIN_XATTR_SHORT_LEN_THRESHOLD 1000
33 // wrappers to hide annoying errno handling.
35 static inline int sys_fgetxattr(int fd
, const char *name
, void *val
, size_t size
)
37 int r
= ::ceph_os_fgetxattr(fd
, name
, val
, size
);
38 return (r
< 0 ? -errno
: r
);
40 static inline int sys_getxattr(const char *fn
, const char *name
, void *val
, size_t size
)
42 int r
= ::ceph_os_getxattr(fn
, name
, val
, size
);
43 return (r
< 0 ? -errno
: r
);
46 static inline int sys_setxattr(const char *fn
, const char *name
, const void *val
, size_t size
)
48 int r
= ::ceph_os_setxattr(fn
, name
, val
, size
);
49 return (r
< 0 ? -errno
: r
);
51 static inline int sys_fsetxattr(int fd
, const char *name
, const void *val
, size_t size
)
53 int r
= ::ceph_os_fsetxattr(fd
, name
, val
, size
);
54 return (r
< 0 ? -errno
: r
);
57 static inline int sys_listxattr(const char *fn
, char *names
, size_t len
)
59 int r
= ::ceph_os_listxattr(fn
, names
, len
);
60 return (r
< 0 ? -errno
: r
);
62 static inline int sys_flistxattr(int fd
, char *names
, size_t len
)
64 int r
= ::ceph_os_flistxattr(fd
, names
, len
);
65 return (r
< 0 ? -errno
: r
);
68 static inline int sys_removexattr(const char *fn
, const char *name
)
70 int r
= ::ceph_os_removexattr(fn
, name
);
71 return (r
< 0 ? -errno
: r
);
73 static inline int sys_fremovexattr(int fd
, const char *name
)
75 int r
= ::ceph_os_fremovexattr(fd
, name
);
76 return (r
< 0 ? -errno
: r
);
80 // wrappers to chain large values across multiple xattrs
82 int chain_getxattr(const char *fn
, const char *name
, void *val
, size_t size
);
83 int chain_getxattr_buf(const char *fn
, const char *name
, bufferptr
*bp
);
84 int chain_fgetxattr(int fd
, const char *name
, void *val
, size_t size
);
86 int get_xattr_block_size(size_t size
);
87 void get_raw_xattr_name(const char *name
, int i
, char *raw_name
, int raw_len
);
89 template <bool skip_chain_cleanup
=false, bool ensure_single_attr
=false>
91 const char *fn
, const char *name
, const void *val
, size_t size
)
94 char raw_name
[CHAIN_XATTR_MAX_NAME_LEN
* 2 + 16];
96 size_t max_chunk_size
=
97 ensure_single_attr
? size
: get_xattr_block_size(size
);
100 !skip_chain_cleanup
|| ensure_single_attr
,
101 "skip_chain_cleanup must imply ensure_single_attr");
104 size_t chunk_size
= (size
< max_chunk_size
? size
: max_chunk_size
);
105 get_raw_xattr_name(name
, i
, raw_name
, sizeof(raw_name
));
108 int r
= sys_setxattr(fn
, raw_name
, (char *)val
+ pos
, chunk_size
);
116 assert(size
== 0 || !ensure_single_attr
);
119 if (ret
>= 0 && !skip_chain_cleanup
) {
122 get_raw_xattr_name(name
, i
, raw_name
, sizeof(raw_name
));
123 r
= sys_removexattr(fn
, raw_name
);
124 if (r
< 0 && r
!= -ENODATA
)
127 } while (r
!= -ENODATA
);
133 template <bool skip_chain_cleanup
=false, bool ensure_single_attr
=false>
135 int fd
, const char *name
, const void *val
, size_t size
)
138 char raw_name
[CHAIN_XATTR_MAX_NAME_LEN
* 2 + 16];
140 size_t max_chunk_size
=
141 ensure_single_attr
? size
: get_xattr_block_size(size
);
144 !skip_chain_cleanup
|| ensure_single_attr
,
145 "skip_chain_cleanup must imply ensure_single_attr");
148 size_t chunk_size
= (size
< max_chunk_size
? size
: max_chunk_size
);
149 get_raw_xattr_name(name
, i
, raw_name
, sizeof(raw_name
));
152 int r
= sys_fsetxattr(fd
, raw_name
, (char *)val
+ pos
, chunk_size
);
160 assert(size
== 0 || !ensure_single_attr
);
163 if (ret
>= 0 && !skip_chain_cleanup
) {
166 get_raw_xattr_name(name
, i
, raw_name
, sizeof(raw_name
));
167 r
= sys_fremovexattr(fd
, raw_name
);
168 if (r
< 0 && r
!= -ENODATA
)
171 } while (r
!= -ENODATA
);
177 int chain_listxattr(const char *fn
, char *names
, size_t len
);
178 int chain_flistxattr(int fd
, char *names
, size_t len
);
179 int chain_removexattr(const char *fn
, const char *name
);
180 int chain_fremovexattr(int fd
, const char *name
);