mirror of
https://github.com/ceph/ceph
synced 2025-03-25 11:48:05 +00:00
Merge pull request #11647 from ceph/wip-jlayton-cephfs
libcephfs client API overhaul and update Reviewed-by: John Spray <john.spray@redhat.com>
This commit is contained in:
commit
f80c7a8f20
26
ceph.spec.in
26
ceph.spec.in
@ -218,7 +218,7 @@ Group: System Environment/Base
|
||||
Requires: ceph-common = %{epoch}:%{version}-%{release}
|
||||
Requires: librbd1 = %{epoch}:%{version}-%{release}
|
||||
Requires: librados2 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||
Requires: librgw2 = %{epoch}:%{version}-%{release}
|
||||
%if 0%{with selinux}
|
||||
Requires: ceph-selinux = %{epoch}:%{version}-%{release}
|
||||
@ -247,7 +247,7 @@ Summary: Ceph Common
|
||||
Group: System Environment/Base
|
||||
Requires: librbd1 = %{epoch}:%{version}-%{release}
|
||||
Requires: librados2 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||
Requires: python-rados = %{epoch}:%{version}-%{release}
|
||||
Requires: python-rbd = %{epoch}:%{version}-%{release}
|
||||
Requires: python-cephfs = %{epoch}:%{version}-%{release}
|
||||
@ -517,7 +517,7 @@ Requires: python%{python3_pkgversion}-rados = %{epoch}:%{version}-%{release}
|
||||
This package contains Python 3 libraries for interacting with Cephs RADOS
|
||||
block device.
|
||||
|
||||
%package -n libcephfs1
|
||||
%package -n libcephfs2
|
||||
Summary: Ceph distributed file system client library
|
||||
Group: System Environment/Libraries
|
||||
License: LGPL-2.0
|
||||
@ -525,7 +525,7 @@ License: LGPL-2.0
|
||||
Obsoletes: ceph-libs < %{epoch}:%{version}-%{release}
|
||||
Obsoletes: ceph-libcephfs
|
||||
%endif
|
||||
%description -n libcephfs1
|
||||
%description -n libcephfs2
|
||||
Ceph is a distributed network file system designed to provide excellent
|
||||
performance, reliability, and scalability. This is a shared library
|
||||
allowing applications to access a Ceph distributed file system via a
|
||||
@ -535,11 +535,11 @@ POSIX-like interface.
|
||||
Summary: Ceph distributed file system headers
|
||||
Group: Development/Libraries
|
||||
License: LGPL-2.0
|
||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||
Requires: librados-devel = %{epoch}:%{version}-%{release}
|
||||
Obsoletes: ceph-devel < %{epoch}:%{version}-%{release}
|
||||
Provides: libcephfs1-devel = %{epoch}:%{version}-%{release}
|
||||
Obsoletes: libcephfs1-devel < %{epoch}:%{version}-%{release}
|
||||
Provides: libcephfs2-devel = %{epoch}:%{version}-%{release}
|
||||
Obsoletes: libcephfs2-devel < %{epoch}:%{version}-%{release}
|
||||
%description -n libcephfs-devel
|
||||
This package contains libraries and headers needed to develop programs
|
||||
that use Cephs distributed file system.
|
||||
@ -548,7 +548,7 @@ that use Cephs distributed file system.
|
||||
Summary: Python 2 libraries for Ceph distributed file system
|
||||
Group: System Environment/Libraries
|
||||
License: LGPL-2.0
|
||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||
Requires: python-rados = %{epoch}:%{version}-%{release}
|
||||
Obsoletes: python-ceph < %{epoch}:%{version}-%{release}
|
||||
%description -n python-cephfs
|
||||
@ -559,7 +559,7 @@ file system.
|
||||
Summary: Python 3 libraries for Ceph distributed file system
|
||||
Group: System Environment/Libraries
|
||||
License: LGPL-2.0
|
||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||
Requires: python%{python3_pkgversion}-rados = %{epoch}:%{version}-%{release}
|
||||
%description -n python%{python3_pkgversion}-cephfs
|
||||
This package contains Python 3 libraries for interacting with Cephs distributed
|
||||
@ -593,7 +593,7 @@ Summary: Java Native Interface library for CephFS Java bindings
|
||||
Group: System Environment/Libraries
|
||||
License: LGPL-2.0
|
||||
Requires: java
|
||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
||||
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||
%description -n libcephfs_jni1
|
||||
This package contains the Java Native Interface library for CephFS Java
|
||||
bindings.
|
||||
@ -1428,13 +1428,13 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
|
||||
%{python3_sitearch}/rbd.cpython*.so
|
||||
%{python3_sitearch}/rbd-*.egg-info
|
||||
|
||||
%files -n libcephfs1
|
||||
%files -n libcephfs2
|
||||
%defattr(-,root,root,-)
|
||||
%{_libdir}/libcephfs.so.*
|
||||
|
||||
%post -n libcephfs1 -p /sbin/ldconfig
|
||||
%post -n libcephfs2 -p /sbin/ldconfig
|
||||
|
||||
%postun -n libcephfs1 -p /sbin/ldconfig
|
||||
%postun -n libcephfs2 -p /sbin/ldconfig
|
||||
|
||||
%files -n libcephfs-devel
|
||||
%defattr(-,root,root,-)
|
||||
|
4
debian/.gitignore
vendored
4
debian/.gitignore
vendored
@ -21,9 +21,9 @@
|
||||
/*.debhelper
|
||||
/ceph
|
||||
/files
|
||||
/libcephfs1-dbg
|
||||
/libcephfs2-dbg
|
||||
/libcephfs-dev
|
||||
/libcephfs1
|
||||
/libcephfs2
|
||||
/librados2-dbg
|
||||
/librados-dev
|
||||
/librados2
|
||||
|
24
debian/control
vendored
24
debian/control
vendored
@ -120,7 +120,7 @@ Depends: ceph-base (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Recommends: ceph-fuse (= ${binary:Version}),
|
||||
libcephfs1 (= ${binary:Version})
|
||||
libcephfs2 (= ${binary:Version})
|
||||
Replaces: ceph (<< 0.93-417)
|
||||
Breaks: ceph (<< 0.93-417)
|
||||
Description: metadata server for the ceph distributed file system
|
||||
@ -516,7 +516,7 @@ Description: RADOS block device client library (development files)
|
||||
This package contains development files needed for building applications that
|
||||
link against librbd1.
|
||||
|
||||
Package: libcephfs1
|
||||
Package: libcephfs2
|
||||
Conflicts: libceph, libceph1, libcephfs
|
||||
Replaces: libceph, libceph1, libcephfs
|
||||
Architecture: linux-any
|
||||
@ -529,28 +529,28 @@ Description: Ceph distributed file system client library
|
||||
shared library allowing applications to access a Ceph distributed
|
||||
file system via a POSIX-like interface.
|
||||
|
||||
Package: libcephfs1-dbg
|
||||
Package: libcephfs2-dbg
|
||||
Architecture: linux-any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: libcephfs1 (= ${binary:Version}), ${misc:Depends}
|
||||
Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}
|
||||
Conflicts: libceph1-dbg
|
||||
Replaces: libceph1-dbg
|
||||
Description: debugging symbols for libcephfs1
|
||||
Description: debugging symbols for libcephfs2
|
||||
Ceph is a massively scalable, open-source, distributed
|
||||
storage system that runs on commodity hardware and delivers object,
|
||||
block and file system storage. This is a
|
||||
shared library allowing applications to access a Ceph distributed
|
||||
file system via a POSIX-like interface.
|
||||
.
|
||||
This package contains debugging symbols for libcephfs1.
|
||||
This package contains debugging symbols for libcephfs2.
|
||||
|
||||
Package: libcephfs-dev
|
||||
Architecture: linux-any
|
||||
Section: libdevel
|
||||
Depends: libcephfs1 (= ${binary:Version}), ${misc:Depends}
|
||||
Conflicts: libceph-dev, libceph1-dev, libcephfs1-dev
|
||||
Replaces: libceph-dev, libceph1-dev, libcephfs1-dev
|
||||
Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}
|
||||
Conflicts: libceph-dev, libceph1-dev, libcephfs2-dev
|
||||
Replaces: libceph-dev, libceph1-dev, libcephfs2-dev
|
||||
Description: Ceph distributed file system client library (development files)
|
||||
Ceph is a massively scalable, open-source, distributed
|
||||
storage system that runs on commodity hardware and delivers object,
|
||||
@ -726,7 +726,7 @@ Description: Python 3 libraries for the Ceph librbd library
|
||||
Package: python-cephfs
|
||||
Architecture: linux-any
|
||||
Section: python
|
||||
Depends: libcephfs1 (= ${binary:Version}),
|
||||
Depends: libcephfs2 (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
${python:Depends}
|
||||
@ -743,7 +743,7 @@ Description: Python 2 libraries for the Ceph libcephfs library
|
||||
Package: python3-cephfs
|
||||
Architecture: linux-any
|
||||
Section: python
|
||||
Depends: libcephfs1 (= ${binary:Version}),
|
||||
Depends: libcephfs2 (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
${python3:Depends}
|
||||
@ -776,6 +776,6 @@ Description: Java libraries for the Ceph File System
|
||||
Package: libcephfs-jni
|
||||
Architecture: linux-any
|
||||
Section: java
|
||||
Depends: libcephfs1 (= ${binary:Version}), ${java:Depends},
|
||||
Depends: libcephfs2 (= ${binary:Version}), ${java:Depends},
|
||||
${misc:Depends}, ${shlibs:Depends}
|
||||
Description: Java Native Interface library for CephFS Java bindings
|
||||
|
2
debian/rules
vendored
2
debian/rules
vendored
@ -130,7 +130,7 @@ override_dh_strip:
|
||||
dh_strip -plibrados2 --dbg-package=librados2-dbg
|
||||
dh_strip -plibradosstriper1 --dbg-package=libradosstriper1-dbg
|
||||
dh_strip -plibrbd1 --dbg-package=librbd1-dbg
|
||||
dh_strip -plibcephfs1 --dbg-package=libcephfs1-dbg
|
||||
dh_strip -plibcephfs2 --dbg-package=libcephfs2-dbg
|
||||
dh_strip -plibrgw2 --dbg-package=librgw2-dbg
|
||||
dh_strip -pradosgw --dbg-package=radosgw-dbg
|
||||
dh_strip -pceph-test --dbg-package=ceph-test-dbg
|
||||
|
@ -19,8 +19,8 @@ sudo apt-get -y purge librados-dev
|
||||
sudo apt-get -y purge librbd1
|
||||
sudo apt-get -y purge librbd1-dbg
|
||||
sudo apt-get -y purge librbd-dev
|
||||
sudo apt-get -y purge libcephfs1
|
||||
sudo apt-get -y purge libcephfs1-dbg
|
||||
sudo apt-get -y purge libcephfs2
|
||||
sudo apt-get -y purge libcephfs2-dbg
|
||||
sudo apt-get -y purge libcephfs-dev
|
||||
sudo apt-get -y purge radosgw
|
||||
sudo apt-get -y purge radosgw-dbg
|
||||
|
@ -806,8 +806,8 @@ if(WITH_LIBCEPHFS)
|
||||
endforeach()
|
||||
set_target_properties(cephfs PROPERTIES
|
||||
OUTPUT_NAME cephfs
|
||||
VERSION 1.0.0
|
||||
SOVERSION 1
|
||||
VERSION 2.0.0
|
||||
SOVERSION 2
|
||||
LINK_FLAGS ${CEPHFS_LINK_FLAGS})
|
||||
endif(ENABLE_SHARED)
|
||||
install(TARGETS cephfs DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
@ -6568,10 +6568,12 @@ force_request:
|
||||
CEPH_CAP_FILE_WR;
|
||||
}
|
||||
if (mask & CEPH_SETATTR_SIZE) {
|
||||
if ((unsigned long)stx->stx_size < mdsmap->get_max_filesize())
|
||||
if ((unsigned long)stx->stx_size < mdsmap->get_max_filesize()) {
|
||||
req->head.args.setattr.size = stx->stx_size;
|
||||
else { //too big!
|
||||
ldout(cct,10) << "changing size to " << stx->stx_size << dendl;
|
||||
} else { //too big!
|
||||
put_request(req);
|
||||
ldout(cct,10) << "unable to set size to " << stx->stx_size << ". Too large!" << dendl;
|
||||
return -EFBIG;
|
||||
}
|
||||
req->inode_drop |= CEPH_CAP_AUTH_SHARED | CEPH_CAP_FILE_RD |
|
||||
@ -6682,6 +6684,23 @@ int Client::fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms)
|
||||
return _setattr(f->inode, attr, mask, perms);
|
||||
}
|
||||
|
||||
int Client::fsetattrx(int fd, struct ceph_statx *stx, int mask, const UserPerm& perms)
|
||||
{
|
||||
Mutex::Locker lock(client_lock);
|
||||
tout(cct) << "fsetattr" << std::endl;
|
||||
tout(cct) << fd << std::endl;
|
||||
tout(cct) << mask << std::endl;
|
||||
|
||||
Fh *f = get_filehandle(fd);
|
||||
if (!f)
|
||||
return -EBADF;
|
||||
#if defined(__linux__) && defined(O_PATH)
|
||||
if (f->flags & O_PATH)
|
||||
return -EBADF;
|
||||
#endif
|
||||
return _setattrx(f->inode, stx, mask, perms);
|
||||
}
|
||||
|
||||
int Client::stat(const char *relpath, struct stat *stbuf, const UserPerm& perms,
|
||||
frag_info_t *dirstat, int mask)
|
||||
{
|
||||
@ -7307,7 +7326,8 @@ struct dentry_off_lt {
|
||||
}
|
||||
};
|
||||
|
||||
int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p)
|
||||
int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p,
|
||||
int caps, bool getref)
|
||||
{
|
||||
assert(client_lock.is_locked());
|
||||
ldout(cct, 10) << "_readdir_cache_cb " << dirp << " on " << dirp->inode->ino
|
||||
@ -7343,21 +7363,30 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p)
|
||||
continue;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
int r = _getattr(dn->inode, caps, dirp->perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
struct ceph_statx stx;
|
||||
struct dirent de;
|
||||
int stmask = fill_stat(dn->inode, &st);
|
||||
fill_statx(dn->inode, caps, &stx);
|
||||
|
||||
uint64_t next_off = dn->offset + 1;
|
||||
++pd;
|
||||
if (pd == dir->readdir_cache.end())
|
||||
next_off = dir_result_t::END;
|
||||
|
||||
fill_dirent(&de, dn->name.c_str(), st.st_mode, st.st_ino, next_off);
|
||||
Inode *in = NULL;
|
||||
fill_dirent(&de, dn->name.c_str(), stx.stx_mode, stx.stx_ino, next_off);
|
||||
if (getref) {
|
||||
in = dn->inode.get();
|
||||
_ll_get(in);
|
||||
}
|
||||
|
||||
dn_name = dn->name; // fill in name while we have lock
|
||||
|
||||
client_lock.Unlock();
|
||||
int r = cb(p, &de, &st, stmask, next_off); // _next_ offset
|
||||
r = cb(p, &de, &stx, next_off, in); // _next_ offset
|
||||
client_lock.Lock();
|
||||
ldout(cct, 15) << " de " << de.d_name << " off " << hex << dn->offset << dec
|
||||
<< " = " << r << dendl;
|
||||
@ -7380,8 +7409,11 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p,
|
||||
unsigned want, unsigned flags, bool getref)
|
||||
{
|
||||
int caps = statx_to_mask(flags, want);
|
||||
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
dir_result_t *dirp = static_cast<dir_result_t*>(d);
|
||||
@ -7391,9 +7423,9 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
<< " hash_order=" << dirp->hash_order() << dendl;
|
||||
|
||||
struct dirent de;
|
||||
struct stat st;
|
||||
struct ceph_statx stx;
|
||||
memset(&de, 0, sizeof(de));
|
||||
memset(&st, 0, sizeof(st));
|
||||
memset(&stx, 0, sizeof(stx));
|
||||
|
||||
InodeRef& diri = dirp->inode;
|
||||
|
||||
@ -7405,11 +7437,22 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
assert(diri->dn_set.size() < 2); // can't have multiple hard-links to a dir
|
||||
uint64_t next_off = 1;
|
||||
|
||||
fill_stat(diri, &st);
|
||||
fill_dirent(&de, ".", S_IFDIR, st.st_ino, next_off);
|
||||
int r;
|
||||
r = _getattr(diri, caps, dirp->perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fill_statx(diri, caps, &stx);
|
||||
fill_dirent(&de, ".", S_IFDIR, stx.stx_ino, next_off);
|
||||
|
||||
Inode *inode = NULL;
|
||||
if (getref) {
|
||||
inode = diri.get();
|
||||
_ll_get(inode);
|
||||
}
|
||||
|
||||
client_lock.Unlock();
|
||||
int r = cb(p, &de, &st, -1, next_off);
|
||||
r = cb(p, &de, &stx, next_off, inode);
|
||||
client_lock.Lock();
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -7427,11 +7470,22 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
else
|
||||
in = diri->get_first_parent()->inode;
|
||||
|
||||
fill_stat(in, &st);
|
||||
fill_dirent(&de, "..", S_IFDIR, st.st_ino, next_off);
|
||||
int r;
|
||||
r = _getattr(diri, caps, dirp->perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fill_statx(in, caps, &stx);
|
||||
fill_dirent(&de, "..", S_IFDIR, stx.stx_ino, next_off);
|
||||
|
||||
Inode *inode = NULL;
|
||||
if (getref) {
|
||||
inode = in.get();
|
||||
_ll_get(inode);
|
||||
}
|
||||
|
||||
client_lock.Unlock();
|
||||
int r = cb(p, &de, &st, -1, next_off);
|
||||
r = cb(p, &de, &stx, next_off, inode);
|
||||
client_lock.Lock();
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -7450,7 +7504,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
if (dirp->inode->snapid != CEPH_SNAPDIR &&
|
||||
dirp->inode->is_complete_and_ordered() &&
|
||||
dirp->inode->caps_issued_mask(CEPH_CAP_FILE_SHARED)) {
|
||||
int err = _readdir_cache_cb(dirp, cb, p);
|
||||
int err = _readdir_cache_cb(dirp, cb, p, caps, getref);
|
||||
if (err != -EAGAIN)
|
||||
return err;
|
||||
}
|
||||
@ -7459,12 +7513,14 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
if (dirp->at_end())
|
||||
return 0;
|
||||
|
||||
bool check_caps = true;
|
||||
if (!dirp->is_cached()) {
|
||||
int r = _readdir_get_frag(dirp);
|
||||
if (r)
|
||||
return r;
|
||||
// _readdir_get_frag () may updates dirp->offset if the replied dirfrag is
|
||||
// different than the requested one. (our dirfragtree was outdated)
|
||||
check_caps = false;
|
||||
}
|
||||
frag_t fg = dirp->buffer_frag;
|
||||
|
||||
@ -7478,11 +7534,25 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
dir_result_t::dentry &entry = *it;
|
||||
|
||||
uint64_t next_off = entry.offset + 1;
|
||||
int stmask = fill_stat(entry.inode, &st);
|
||||
fill_dirent(&de, entry.name.c_str(), st.st_mode, st.st_ino, next_off);
|
||||
|
||||
int r;
|
||||
if (check_caps) {
|
||||
r = _getattr(entry.inode, caps, dirp->perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
fill_statx(entry.inode, caps, &stx);
|
||||
fill_dirent(&de, entry.name.c_str(), stx.stx_mode, stx.stx_ino, next_off);
|
||||
|
||||
Inode *inode = NULL;
|
||||
if (getref) {
|
||||
inode = entry.inode.get();
|
||||
_ll_get(inode);
|
||||
}
|
||||
|
||||
client_lock.Unlock();
|
||||
int r = cb(p, &de, &st, stmask, next_off); // _next_ offset
|
||||
r = cb(p, &de, &stx, next_off, inode); // _next_ offset
|
||||
client_lock.Lock();
|
||||
|
||||
ldout(cct, 15) << " de " << de.d_name << " off " << hex << next_off - 1 << dec
|
||||
@ -7532,7 +7602,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
||||
|
||||
int Client::readdir_r(dir_result_t *d, struct dirent *de)
|
||||
{
|
||||
return readdirplus_r(d, de, 0, 0);
|
||||
return readdirplus_r(d, de, 0, 0, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -7546,13 +7616,14 @@ int Client::readdir_r(dir_result_t *d, struct dirent *de)
|
||||
|
||||
struct single_readdir {
|
||||
struct dirent *de;
|
||||
struct stat *st;
|
||||
int *stmask;
|
||||
struct ceph_statx *stx;
|
||||
Inode *inode;
|
||||
bool full;
|
||||
};
|
||||
|
||||
static int _readdir_single_dirent_cb(void *p, struct dirent *de, struct stat *st,
|
||||
int stmask, off_t off)
|
||||
static int _readdir_single_dirent_cb(void *p, struct dirent *de,
|
||||
struct ceph_statx *stx, off_t off,
|
||||
Inode *in)
|
||||
{
|
||||
single_readdir *c = static_cast<single_readdir *>(p);
|
||||
|
||||
@ -7560,10 +7631,9 @@ static int _readdir_single_dirent_cb(void *p, struct dirent *de, struct stat *st
|
||||
return -1; // already filled this dirent
|
||||
|
||||
*c->de = *de;
|
||||
if (c->st)
|
||||
*c->st = *st;
|
||||
if (c->stmask)
|
||||
*c->stmask = stmask;
|
||||
if (c->stx)
|
||||
*c->stx = *stx;
|
||||
c->inode = in;
|
||||
c->full = true;
|
||||
return 1;
|
||||
}
|
||||
@ -7571,13 +7641,11 @@ static int _readdir_single_dirent_cb(void *p, struct dirent *de, struct stat *st
|
||||
struct dirent *Client::readdir(dir_result_t *d)
|
||||
{
|
||||
int ret;
|
||||
static int stmask;
|
||||
static struct dirent de;
|
||||
static struct stat st;
|
||||
single_readdir sr;
|
||||
sr.de = &de;
|
||||
sr.st = &st;
|
||||
sr.stmask = &stmask;
|
||||
sr.stx = NULL;
|
||||
sr.inode = NULL;
|
||||
sr.full = false;
|
||||
|
||||
// our callback fills the dirent and sets sr.full=true on first
|
||||
@ -7593,19 +7661,23 @@ struct dirent *Client::readdir(dir_result_t *d)
|
||||
return (dirent *) NULL;
|
||||
}
|
||||
|
||||
int Client::readdirplus_r(dir_result_t *d, struct dirent *de, struct stat *st, int *stmask)
|
||||
int Client::readdirplus_r(dir_result_t *d, struct dirent *de,
|
||||
struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, Inode **out)
|
||||
{
|
||||
single_readdir sr;
|
||||
sr.de = de;
|
||||
sr.st = st;
|
||||
sr.stmask = stmask;
|
||||
sr.stx = stx;
|
||||
sr.inode = NULL;
|
||||
sr.full = false;
|
||||
|
||||
// our callback fills the dirent and sets sr.full=true on first
|
||||
// call, and returns -1 the second time around.
|
||||
int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr);
|
||||
int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr, want, flags, out);
|
||||
if (r < -1)
|
||||
return r;
|
||||
if (out)
|
||||
*out = sr.inode;
|
||||
if (sr.full)
|
||||
return 1;
|
||||
return 0;
|
||||
@ -7620,7 +7692,8 @@ struct getdents_result {
|
||||
bool fullent;
|
||||
};
|
||||
|
||||
static int _readdir_getdent_cb(void *p, struct dirent *de, struct stat *st, int stmask, off_t off)
|
||||
static int _readdir_getdent_cb(void *p, struct dirent *de,
|
||||
struct ceph_statx *stx, off_t off, Inode *in)
|
||||
{
|
||||
struct getdents_result *c = static_cast<getdents_result *>(p);
|
||||
|
||||
@ -7672,7 +7745,7 @@ struct getdir_result {
|
||||
int num;
|
||||
};
|
||||
|
||||
static int _getdir_cb(void *p, struct dirent *de, struct stat *st, int stmask, off_t off)
|
||||
static int _getdir_cb(void *p, struct dirent *de, struct ceph_statx *stx, off_t off, Inode *in)
|
||||
{
|
||||
getdir_result *r = static_cast<getdir_result *>(p);
|
||||
|
||||
@ -9769,32 +9842,71 @@ int Client::ll_lookup(Inode *parent, const char *name, struct stat *attr,
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_walk(const char* name, Inode **out, struct stat *attr,
|
||||
const UserPerm& perms)
|
||||
int Client::ll_lookupx(Inode *parent, const char *name, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want, unsigned flags,
|
||||
const UserPerm& perms)
|
||||
{
|
||||
Mutex::Locker lock(client_lock);
|
||||
ldout(cct, 3) << "ll_lookupx " << parent << " " << name << dendl;
|
||||
tout(cct) << "ll_lookupx" << std::endl;
|
||||
tout(cct) << name << std::endl;
|
||||
|
||||
int r = 0;
|
||||
if (!cct->_conf->fuse_default_permissions) {
|
||||
r = may_lookup(parent, perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
string dname(name);
|
||||
InodeRef in;
|
||||
|
||||
unsigned mask = statx_to_mask(flags, want);
|
||||
r = _lookup(parent, dname, mask, &in, perms);
|
||||
if (r < 0) {
|
||||
stx->stx_ino = 0;
|
||||
stx->stx_mask = 0;
|
||||
} else {
|
||||
assert(in);
|
||||
fill_statx(in, mask, stx);
|
||||
_ll_get(in.get());
|
||||
}
|
||||
|
||||
ldout(cct, 3) << "ll_lookupx " << parent << " " << name
|
||||
<< " -> " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl;
|
||||
tout(cct) << stx->stx_ino << std::endl;
|
||||
*out = in.get();
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_walk(const char* name, Inode **out, struct ceph_statx *stx,
|
||||
unsigned int want, unsigned int flags, const UserPerm& perms)
|
||||
{
|
||||
Mutex::Locker lock(client_lock);
|
||||
filepath fp(name, 0);
|
||||
InodeRef in;
|
||||
int rc;
|
||||
unsigned mask = statx_to_mask(flags, want);
|
||||
|
||||
ldout(cct, 3) << "ll_walk" << name << dendl;
|
||||
tout(cct) << "ll_walk" << std::endl;
|
||||
tout(cct) << name << std::endl;
|
||||
|
||||
rc = path_walk(fp, &in, perms, false, CEPH_STAT_CAP_INODE_ALL);
|
||||
rc = path_walk(fp, &in, perms, !(flags & AT_SYMLINK_NOFOLLOW), mask);
|
||||
if (rc < 0) {
|
||||
attr->st_ino = 0;
|
||||
/* zero out mask, just in case... */
|
||||
stx->stx_mask = 0;
|
||||
stx->stx_ino = 0;
|
||||
*out = NULL;
|
||||
return rc;
|
||||
} else {
|
||||
assert(in);
|
||||
fill_stat(in, attr);
|
||||
fill_statx(in, mask, stx);
|
||||
*out = in.get();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::_ll_get(Inode *in)
|
||||
{
|
||||
if (in->ll_ref == 0) {
|
||||
@ -10846,6 +10958,42 @@ int Client::ll_mknod(Inode *parent, const char *name, mode_t mode,
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_mknodx(Inode *parent, const char *name, mode_t mode,
|
||||
dev_t rdev, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want, unsigned flags,
|
||||
const UserPerm& perms)
|
||||
{
|
||||
unsigned caps = statx_to_mask(flags, want);
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
vinodeno_t vparent = _get_vino(parent);
|
||||
|
||||
ldout(cct, 3) << "ll_mknodx " << vparent << " " << name << dendl;
|
||||
tout(cct) << "ll_mknodx" << std::endl;
|
||||
tout(cct) << vparent.ino.val << std::endl;
|
||||
tout(cct) << name << std::endl;
|
||||
tout(cct) << mode << std::endl;
|
||||
tout(cct) << rdev << std::endl;
|
||||
|
||||
if (!cct->_conf->fuse_default_permissions) {
|
||||
int r = may_create(parent, perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
InodeRef in;
|
||||
int r = _mknod(parent, name, mode, rdev, perms, &in);
|
||||
if (r == 0) {
|
||||
fill_statx(in, caps, stx);
|
||||
_ll_get(in.get());
|
||||
}
|
||||
tout(cct) << stx->stx_ino << std::endl;
|
||||
ldout(cct, 3) << "ll_mknodx " << vparent << " " << name
|
||||
<< " = " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl;
|
||||
*out = in.get();
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::_create(Inode *dir, const char *name, int flags, mode_t mode,
|
||||
InodeRef *inp, Fh **fhp, int stripe_unit, int stripe_count,
|
||||
int object_size, const char *data_pool, bool *created,
|
||||
@ -11027,6 +11175,42 @@ int Client::ll_mkdir(Inode *parent, const char *name, mode_t mode,
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_mkdirx(Inode *parent, const char *name, mode_t mode, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want, unsigned flags,
|
||||
const UserPerm& perms)
|
||||
{
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
vinodeno_t vparent = _get_vino(parent);
|
||||
|
||||
ldout(cct, 3) << "ll_mkdirx " << vparent << " " << name << dendl;
|
||||
tout(cct) << "ll_mkdirx" << std::endl;
|
||||
tout(cct) << vparent.ino.val << std::endl;
|
||||
tout(cct) << name << std::endl;
|
||||
tout(cct) << mode << std::endl;
|
||||
|
||||
if (!cct->_conf->fuse_default_permissions) {
|
||||
int r = may_create(parent, perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
InodeRef in;
|
||||
int r = _mkdir(parent, name, mode, perms, &in);
|
||||
if (r == 0) {
|
||||
fill_statx(in, statx_to_mask(flags, want), stx);
|
||||
_ll_get(in.get());
|
||||
} else {
|
||||
stx->stx_ino = 0;
|
||||
stx->stx_mask = 0;
|
||||
}
|
||||
tout(cct) << stx->stx_ino << std::endl;
|
||||
ldout(cct, 3) << "ll_mkdirx " << vparent << " " << name
|
||||
<< " = " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl;
|
||||
*out = in.get();
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::_symlink(Inode *dir, const char *name, const char *target,
|
||||
const UserPerm& perms, InodeRef *inp)
|
||||
{
|
||||
@ -11106,6 +11290,40 @@ int Client::ll_symlink(Inode *parent, const char *name, const char *value,
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_symlinkx(Inode *parent, const char *name, const char *value,
|
||||
Inode **out, struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, const UserPerm& perms)
|
||||
{
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
vinodeno_t vparent = _get_vino(parent);
|
||||
|
||||
ldout(cct, 3) << "ll_symlinkx " << vparent << " " << name << " -> " << value
|
||||
<< dendl;
|
||||
tout(cct) << "ll_symlinkx" << std::endl;
|
||||
tout(cct) << vparent.ino.val << std::endl;
|
||||
tout(cct) << name << std::endl;
|
||||
tout(cct) << value << std::endl;
|
||||
|
||||
if (!cct->_conf->fuse_default_permissions) {
|
||||
int r = may_create(parent, perms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
InodeRef in;
|
||||
int r = _symlink(parent, name, value, perms, &in);
|
||||
if (r == 0) {
|
||||
fill_statx(in, statx_to_mask(flags, want), stx);
|
||||
_ll_get(in.get());
|
||||
}
|
||||
tout(cct) << stx->stx_ino << std::endl;
|
||||
ldout(cct, 3) << "ll_symlinkx " << vparent << " " << name
|
||||
<< " = " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl;
|
||||
*out = in.get();
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::_unlink(Inode *dir, const char *name, const UserPerm& perm)
|
||||
{
|
||||
ldout(cct, 3) << "_unlink(" << dir->ino << " " << name
|
||||
@ -11404,7 +11622,7 @@ int Client::_link(Inode *in, Inode *dir, const char *newname, const UserPerm& pe
|
||||
}
|
||||
|
||||
int Client::ll_link(Inode *in, Inode *newparent, const char *newname,
|
||||
struct stat *attr, const UserPerm& perm)
|
||||
const UserPerm& perm)
|
||||
{
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
@ -11422,25 +11640,19 @@ int Client::ll_link(Inode *in, Inode *newparent, const char *newname,
|
||||
InodeRef target;
|
||||
|
||||
if (!cct->_conf->fuse_default_permissions) {
|
||||
if (S_ISDIR(in->mode)) {
|
||||
r = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
if (S_ISDIR(in->mode))
|
||||
return -EPERM;
|
||||
|
||||
r = may_hardlink(in, perm);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
return r;
|
||||
|
||||
r = may_create(newparent, perm);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = _link(in, newparent, newname, perm, &target);
|
||||
if (r == 0) {
|
||||
assert(target);
|
||||
fill_stat(target, attr);
|
||||
}
|
||||
out:
|
||||
return r;
|
||||
return _link(in, newparent, newname, perm, &target);
|
||||
}
|
||||
|
||||
int Client::ll_num_osds(void)
|
||||
@ -11614,17 +11826,15 @@ int Client::ll_open(Inode *in, int flags, Fh **fhp, const UserPerm& perms)
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
int flags, struct stat *attr, Inode **outp, Fh **fhp,
|
||||
int Client::_ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
int flags, InodeRef *in, int caps, Fh **fhp,
|
||||
const UserPerm& perms)
|
||||
{
|
||||
*fhp = NULL;
|
||||
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
vinodeno_t vparent = _get_vino(parent);
|
||||
|
||||
ldout(cct, 3) << "ll_create " << vparent << " " << name << " 0" << oct <<
|
||||
ldout(cct, 3) << "_ll_create " << vparent << " " << name << " 0" << oct <<
|
||||
mode << dec << " " << flags << ", uid " << perms.uid()
|
||||
<< ", gid " << perms.gid() << dendl;
|
||||
tout(cct) << "ll_create" << std::endl;
|
||||
@ -11634,8 +11844,7 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
tout(cct) << flags << std::endl;
|
||||
|
||||
bool created = false;
|
||||
InodeRef in;
|
||||
int r = _lookup(parent, name, CEPH_STAT_CAP_INODE_ALL, &in, perms);
|
||||
int r = _lookup(parent, name, caps, in, perms);
|
||||
|
||||
if (r == 0 && (flags & O_CREAT) && (flags & O_EXCL))
|
||||
return -EEXIST;
|
||||
@ -11646,7 +11855,7 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
r = _create(parent, name, flags, mode, &in, fhp, 0, 0, 0, NULL, &created,
|
||||
r = _create(parent, name, flags, mode, in, fhp, 0, 0, 0, NULL, &created,
|
||||
perms);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
@ -11655,13 +11864,12 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
assert(in);
|
||||
fill_stat(in, attr);
|
||||
assert(*in);
|
||||
|
||||
ldout(cct, 20) << "ll_create created = " << created << dendl;
|
||||
ldout(cct, 20) << "_ll_create created = " << created << dendl;
|
||||
if (!created) {
|
||||
if (!cct->_conf->fuse_default_permissions) {
|
||||
r = may_open(in.get(), flags, perms);
|
||||
r = may_open(in->get(), flags, perms);
|
||||
if (r < 0) {
|
||||
if (*fhp) {
|
||||
int release_r = _release_fh(*fhp);
|
||||
@ -11671,30 +11879,82 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
}
|
||||
}
|
||||
if (*fhp == NULL) {
|
||||
r = _open(in.get(), flags, mode, fhp, perms);
|
||||
r = _open(in->get(), flags, mode, fhp, perms);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (r < 0)
|
||||
attr->st_ino = 0;
|
||||
|
||||
if (*fhp) {
|
||||
ll_unclosed_fh_set.insert(*fhp);
|
||||
}
|
||||
tout(cct) << (unsigned long)*fhp << std::endl;
|
||||
tout(cct) << attr->st_ino << std::endl;
|
||||
ldout(cct, 3) << "ll_create " << parent << " " << name << " 0" << oct <<
|
||||
mode << dec << " " << flags << " = " << r << " (" << *fhp << " " <<
|
||||
hex << attr->st_ino << dec << ")" << dendl;
|
||||
|
||||
// passing an Inode in outp requires an additional ref
|
||||
if (outp) {
|
||||
if (in)
|
||||
ino_t ino = 0;
|
||||
if (r >= 0) {
|
||||
Inode *inode = in->get();
|
||||
if (use_faked_inos())
|
||||
ino = inode->faked_ino;
|
||||
else
|
||||
ino = inode->ino;
|
||||
}
|
||||
|
||||
tout(cct) << (unsigned long)*fhp << std::endl;
|
||||
tout(cct) << ino << std::endl;
|
||||
ldout(cct, 3) << "_ll_create " << parent << " " << name << " 0" << oct <<
|
||||
mode << dec << " " << flags << " = " << r << " (" << *fhp << " " <<
|
||||
hex << ino << dec << ")" << dendl;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
int flags, struct stat *attr, Inode **outp, Fh **fhp,
|
||||
const UserPerm& perms)
|
||||
{
|
||||
InodeRef in;
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
int r = _ll_create(parent, name, mode, flags, &in, CEPH_STAT_CAP_INODE_ALL,
|
||||
fhp, perms);
|
||||
if (r >= 0) {
|
||||
assert(in);
|
||||
|
||||
// passing an Inode in outp requires an additional ref
|
||||
if (outp) {
|
||||
_ll_get(in.get());
|
||||
*outp = in.get();
|
||||
*outp = in.get();
|
||||
}
|
||||
fill_stat(in, attr);
|
||||
} else {
|
||||
attr->st_ino = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int Client::ll_createx(Inode *parent, const char *name, mode_t mode,
|
||||
int oflags, Inode **outp, Fh **fhp,
|
||||
struct ceph_statx *stx, unsigned want, unsigned lflags,
|
||||
const UserPerm& perms)
|
||||
{
|
||||
unsigned caps = statx_to_mask(lflags, want);
|
||||
InodeRef in;
|
||||
Mutex::Locker lock(client_lock);
|
||||
|
||||
int r = _ll_create(parent, name, mode, oflags, &in, caps, fhp, perms);
|
||||
if (r >= 0) {
|
||||
assert(in);
|
||||
|
||||
// passing an Inode in outp requires an additional ref
|
||||
if (outp) {
|
||||
_ll_get(in.get());
|
||||
*outp = in.get();
|
||||
}
|
||||
fill_statx(in, caps, stx);
|
||||
} else {
|
||||
stx->stx_ino = 0;
|
||||
stx->stx_mask = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -48,6 +48,7 @@ using std::fstream;
|
||||
|
||||
#include "InodeRef.h"
|
||||
#include "UserPerm.h"
|
||||
#include "include/cephfs/ceph_statx.h"
|
||||
|
||||
class FSMap;
|
||||
class FSMapUser;
|
||||
@ -719,7 +720,7 @@ private:
|
||||
void fill_dirent(struct dirent *de, const char *name, int type, uint64_t ino, loff_t next_off);
|
||||
|
||||
// some readdir helpers
|
||||
typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct stat *st, int stmask, off_t off);
|
||||
typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct ceph_statx *stx, off_t off, Inode *in);
|
||||
|
||||
int _opendir(Inode *in, dir_result_t **dirpp, const UserPerm& perms);
|
||||
void _readdir_drop_dirp_buffer(dir_result_t *dirp);
|
||||
@ -727,7 +728,7 @@ private:
|
||||
void _readdir_next_frag(dir_result_t *dirp);
|
||||
void _readdir_rechoose_frag(dir_result_t *dirp);
|
||||
int _readdir_get_frag(dir_result_t *dirp);
|
||||
int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p);
|
||||
int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, int caps, bool getref);
|
||||
void _closedir(dir_result_t *dirp);
|
||||
|
||||
// other helpers
|
||||
@ -952,11 +953,13 @@ public:
|
||||
* Returns 0 if it reached the end of the directory.
|
||||
* If @a cb returns a negative error code, stop and return that.
|
||||
*/
|
||||
int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p);
|
||||
int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p,
|
||||
unsigned want=0, unsigned flags=AT_NO_ATTR_SYNC,
|
||||
bool getref=false);
|
||||
|
||||
struct dirent * readdir(dir_result_t *d);
|
||||
int readdir_r(dir_result_t *dirp, struct dirent *de);
|
||||
int readdirplus_r(dir_result_t *dirp, struct dirent *de, struct stat *st, int *stmask);
|
||||
int readdirplus_r(dir_result_t *dirp, struct dirent *de, struct ceph_statx *stx, unsigned want, unsigned flags, Inode **out);
|
||||
|
||||
int getdir(const char *relpath, list<string>& names,
|
||||
const UserPerm& perms); // get the whole dir at once.
|
||||
@ -1007,6 +1010,7 @@ public:
|
||||
int setattrx(const char *relpath, struct ceph_statx *stx, int mask,
|
||||
const UserPerm& perms, int flags=0);
|
||||
int fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms);
|
||||
int fsetattrx(int fd, struct ceph_statx *stx, int mask, const UserPerm& perms);
|
||||
int chmod(const char *path, mode_t mode, const UserPerm& perms);
|
||||
int fchmod(int fd, mode_t mode, const UserPerm& perms);
|
||||
int lchmod(const char *path, mode_t mode, const UserPerm& perms);
|
||||
@ -1113,6 +1117,9 @@ public:
|
||||
Inode *ll_get_inode(vinodeno_t vino);
|
||||
int ll_lookup(Inode *parent, const char *name, struct stat *attr,
|
||||
Inode **out, const UserPerm& perms);
|
||||
int ll_lookupx(Inode *parent, const char *name, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want, unsigned flags,
|
||||
const UserPerm& perms);
|
||||
bool ll_forget(Inode *in, int count);
|
||||
bool ll_put(Inode *in);
|
||||
int ll_getattr(Inode *in, struct stat *st, const UserPerm& perms);
|
||||
@ -1135,20 +1142,36 @@ public:
|
||||
int ll_readlink(Inode *in, char *buf, size_t bufsize, const UserPerm& perms);
|
||||
int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev,
|
||||
struct stat *attr, Inode **out, const UserPerm& perms);
|
||||
int ll_mknodx(Inode *parent, const char *name, mode_t mode, dev_t rdev,
|
||||
Inode **out, struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, const UserPerm& perms);
|
||||
int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr,
|
||||
Inode **out, const UserPerm& perm);
|
||||
int ll_mkdirx(Inode *parent, const char *name, mode_t mode, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want, unsigned flags,
|
||||
const UserPerm& perms);
|
||||
int ll_symlink(Inode *in, const char *name, const char *value,
|
||||
struct stat *attr, Inode **out, const UserPerm& perms);
|
||||
int ll_symlinkx(Inode *parent, const char *name, const char *value,
|
||||
Inode **out, struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, const UserPerm& perms);
|
||||
int ll_unlink(Inode *in, const char *name, const UserPerm& perm);
|
||||
int ll_rmdir(Inode *in, const char *name, const UserPerm& perms);
|
||||
int ll_rename(Inode *parent, const char *name, Inode *newparent,
|
||||
const char *newname, const UserPerm& perm);
|
||||
int ll_link(Inode *in, Inode *newparent, const char *newname,
|
||||
struct stat *attr, const UserPerm& perm);
|
||||
const UserPerm& perm);
|
||||
int ll_open(Inode *in, int flags, Fh **fh, const UserPerm& perms);
|
||||
int _ll_create(Inode *parent, const char *name, mode_t mode,
|
||||
int flags, InodeRef *in, int caps, Fh **fhp,
|
||||
const UserPerm& perms);
|
||||
int ll_create(Inode *parent, const char *name, mode_t mode, int flags,
|
||||
struct stat *attr, Inode **out, Fh **fhp,
|
||||
const UserPerm& perms);
|
||||
int ll_createx(Inode *parent, const char *name, mode_t mode,
|
||||
int oflags, Inode **outp, Fh **fhp,
|
||||
struct ceph_statx *stx, unsigned want, unsigned lflags,
|
||||
const UserPerm& perms);
|
||||
int ll_read_block(Inode *in, uint64_t blockid, char *buf, uint64_t offset,
|
||||
uint64_t length, file_layout_t* layout);
|
||||
|
||||
@ -1159,8 +1182,8 @@ public:
|
||||
int ll_commit_blocks(Inode *in, uint64_t offset, uint64_t length);
|
||||
|
||||
int ll_statfs(Inode *in, struct statvfs *stbuf, const UserPerm& perms);
|
||||
int ll_walk(const char* name, Inode **i, struct stat *attr,
|
||||
const UserPerm& perms); // XXX in?
|
||||
int ll_walk(const char* name, Inode **i, struct ceph_statx *stx,
|
||||
unsigned int want, unsigned int flags, const UserPerm& perms);
|
||||
uint32_t ll_stripe_unit(Inode *in);
|
||||
int ll_file_layout(Inode *in, file_layout_t *layout);
|
||||
uint64_t ll_snap_seq(Inode *in);
|
||||
|
@ -37,6 +37,7 @@ using namespace std;
|
||||
|
||||
#include "common/errno.h"
|
||||
#include "include/assert.h"
|
||||
#include "include/cephfs/ceph_statx.h"
|
||||
|
||||
#define dout_subsys ceph_subsys_client
|
||||
#undef dout_prefix
|
||||
@ -1023,11 +1024,11 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only)
|
||||
const char *p = prefix.c_str();
|
||||
if (prefix.length()) {
|
||||
client->mkdir(prefix.c_str(), 0755, perms);
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
i1 = client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP));
|
||||
if (client->ll_lookup(i1, prefix.c_str(), &attr, &i2, perms) == 0) {
|
||||
ll_inos[1] = attr.st_ino;
|
||||
dout(5) << "'root' ino is " << inodeno_t(attr.st_ino) << dendl;
|
||||
if (client->ll_lookupx(i1, prefix.c_str(), &i2, &stx, CEPH_STATX_INO, 0, perms) == 0) {
|
||||
ll_inos[1] = stx.stx_ino;
|
||||
dout(5) << "'root' ino is " << inodeno_t(stx.stx_ino) << dendl;
|
||||
client->ll_put(i1);
|
||||
} else {
|
||||
dout(0) << "warning: play_trace couldn't lookup up my per-client directory" << dendl;
|
||||
@ -1227,11 +1228,11 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only)
|
||||
int64_t i = t.get_int();
|
||||
const char *name = t.get_string(buf, p);
|
||||
int64_t r = t.get_int();
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
if (ll_inos.count(i)) {
|
||||
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
|
||||
if (client->ll_lookup(i1, name, &attr, &i2, perms) == 0)
|
||||
ll_inos[r] = attr.st_ino;
|
||||
if (client->ll_lookupx(i1, name, &i2, &stx, CEPH_STATX_INO, 0, perms) == 0)
|
||||
ll_inos[r] = stx.stx_ino;
|
||||
client->ll_put(i1);
|
||||
}
|
||||
} else if (strcmp(op, "ll_forget") == 0) {
|
||||
@ -1343,12 +1344,11 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only)
|
||||
int64_t i = t.get_int();
|
||||
int64_t ni = t.get_int();
|
||||
const char *nn = t.get_string(buf, p);
|
||||
struct stat attr;
|
||||
if (ll_inos.count(i) &&
|
||||
ll_inos.count(ni)) {
|
||||
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
|
||||
i2 = client->ll_get_inode(vinodeno_t(ll_inos[ni],CEPH_NOSNAP));
|
||||
client->ll_link(i1, i2, nn, &attr, perms);
|
||||
client->ll_link(i1, i2, nn, perms);
|
||||
client->ll_put(i1);
|
||||
client->ll_put(i2);
|
||||
}
|
||||
|
@ -42,8 +42,9 @@ private:
|
||||
public:
|
||||
UserPerm() : m_uid(-1), m_gid(-1), gid_count(0),
|
||||
gids(NULL), alloced_gids(false) {}
|
||||
UserPerm(int uid, int gid) : m_uid(uid), m_gid(gid), gid_count(0),
|
||||
gids(NULL), alloced_gids(false) {}
|
||||
UserPerm(uid_t uid, gid_t gid, int ngids=0, gid_t *gidlist=NULL) :
|
||||
m_uid(uid), m_gid(gid), gid_count(ngids),
|
||||
gids(gidlist), alloced_gids(false) {}
|
||||
UserPerm(const UserPerm& o) : UserPerm() {
|
||||
deep_copy_from(o);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "ioctl.h"
|
||||
#include "common/config.h"
|
||||
#include "include/assert.h"
|
||||
#include "include/cephfs/ceph_statx.h"
|
||||
|
||||
#include "fuse_ll.h"
|
||||
#include <fuse.h>
|
||||
@ -515,14 +516,22 @@ static void fuse_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
|
||||
UserPerm perm(ctx->uid, ctx->gid);
|
||||
GET_GROUPS(perm, req);
|
||||
|
||||
int r = cfuse->client->ll_link(in, nin, newname, &fe.attr, perm);
|
||||
/*
|
||||
* Note that we could successfully link, but then fail the subsequent
|
||||
* getattr and return an error. Perhaps we should ignore getattr errors,
|
||||
* but then how do we tell FUSE that the attrs are bogus?
|
||||
*/
|
||||
int r = cfuse->client->ll_link(in, nin, newname, perm);
|
||||
if (r == 0) {
|
||||
fe.ino = cfuse->make_fake_ino(fe.attr.st_ino, fe.attr.st_dev);
|
||||
fe.attr.st_rdev = new_encode_dev(fe.attr.st_rdev);
|
||||
fuse_reply_entry(req, &fe);
|
||||
} else {
|
||||
fuse_reply_err(req, -r);
|
||||
r = cfuse->client->ll_getattr(in, &fe.attr, perm);
|
||||
if (r == 0) {
|
||||
fe.ino = cfuse->make_fake_ino(fe.attr.st_ino, fe.attr.st_dev);
|
||||
fe.attr.st_rdev = new_encode_dev(fe.attr.st_rdev);
|
||||
fuse_reply_entry(req, &fe);
|
||||
}
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
/*
|
||||
* Many ll operations in libcephfs return an extra inode reference, but
|
||||
* ll_link currently does not. Still, FUSE needs one for the new dentry,
|
||||
@ -530,6 +539,7 @@ static void fuse_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
|
||||
* On error however, we must put that reference.
|
||||
*/
|
||||
cfuse->iput(in);
|
||||
fuse_reply_err(req, -r);
|
||||
}
|
||||
|
||||
cfuse->iput(nin);
|
||||
@ -669,19 +679,21 @@ struct readdir_context {
|
||||
/*
|
||||
* return 0 on success, -1 if out of space
|
||||
*/
|
||||
static int fuse_ll_add_dirent(void *p, struct dirent *de, struct stat *st,
|
||||
int stmask, off_t next_off)
|
||||
static int fuse_ll_add_dirent(void *p, struct dirent *de,
|
||||
struct ceph_statx *stx, off_t next_off,
|
||||
Inode *in)
|
||||
{
|
||||
struct readdir_context *c = (struct readdir_context *)p;
|
||||
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(c->req);
|
||||
|
||||
st->st_ino = cfuse->make_fake_ino(de->d_ino, c->snap);
|
||||
st->st_mode = DTTOIF(de->d_type);
|
||||
st->st_rdev = new_encode_dev(st->st_rdev);
|
||||
struct stat st;
|
||||
st.st_ino = cfuse->make_fake_ino(stx->stx_ino, c->snap);
|
||||
st.st_mode = stx->stx_mode;
|
||||
st.st_rdev = new_encode_dev(stx->stx_rdev);
|
||||
|
||||
size_t room = c->size - c->pos;
|
||||
size_t entrysize = fuse_add_direntry(c->req, c->buf + c->pos, room,
|
||||
de->d_name, st, next_off);
|
||||
de->d_name, &st, next_off);
|
||||
if (entrysize > room)
|
||||
return -ENOSPC;
|
||||
|
||||
|
@ -384,17 +384,17 @@ void CephBroker::rmdir(ResponseCallback *cb, const char *dname) {
|
||||
int CephBroker::rmdir_recursive(const char *directory) {
|
||||
struct ceph_dir_result *dirp;
|
||||
struct dirent de;
|
||||
struct stat st;
|
||||
struct ceph_statx stx;
|
||||
int r;
|
||||
if ((r = ceph_opendir(cmount, directory, &dirp)) < 0)
|
||||
return r; //failed to open
|
||||
while ((r = ceph_readdirplus_r(cmount, dirp, &de, &st, 0)) > 0) {
|
||||
while ((r = ceph_readdirplus_r(cmount, dirp, &de, &stx, CEPH_STATX_INO, AT_NO_ATTR_SYNC, NULL)) > 0) {
|
||||
String new_dir = de.d_name;
|
||||
if(!(new_dir.compare(".")==0 || new_dir.compare("..")==0)) {
|
||||
new_dir = directory;
|
||||
new_dir += '/';
|
||||
new_dir += de.d_name;
|
||||
if (S_ISDIR(st.st_mode)) { //it's a dir, clear it out...
|
||||
if (S_ISDIR(stx.stx_mode)) { //it's a dir, clear it out...
|
||||
if((r=rmdir_recursive(new_dir.c_str())) < 0) return r;
|
||||
} else { //delete this file
|
||||
if((r=ceph_unlink(cmount, new_dir.c_str())) < 0) return r;
|
||||
|
@ -97,6 +97,9 @@ typedef struct vinodeno_t vinodeno;
|
||||
|
||||
#endif /* ! __cplusplus */
|
||||
|
||||
struct UserPerm;
|
||||
typedef struct UserPerm UserPerm;
|
||||
|
||||
struct Inode;
|
||||
typedef struct Inode Inode;
|
||||
|
||||
@ -121,6 +124,34 @@ struct CephContext;
|
||||
# define CEPHFS_ERROR_NEW_CLIENT 1002
|
||||
# define CEPHFS_ERROR_MESSENGER_START 1003
|
||||
|
||||
/**
|
||||
* Create a UserPerm credential object.
|
||||
*
|
||||
* Some calls (most notably, the ceph_ll_* ones), take a credential object
|
||||
* that represents the credentials that the calling program is using. This
|
||||
* function creates a new credential object for this purpose. Returns a
|
||||
* pointer to the object, or NULL if it can't be allocated.
|
||||
*
|
||||
* Note that the gidlist array is used directly and is not copied. It must
|
||||
* remain valid over the lifetime of the created UserPerm object.
|
||||
*
|
||||
* @param uid uid to be used
|
||||
* @param gid gid to be used
|
||||
* @param ngids number of gids in supplemental grouplist
|
||||
* @param gidlist array of gid_t's in the list of groups
|
||||
*/
|
||||
UserPerm *ceph_userperm_new(uid_t uid, gid_t gid, int ngids, gid_t *gidlist);
|
||||
|
||||
/**
|
||||
* Destroy a UserPerm credential object.
|
||||
*
|
||||
* @param perm pointer to object to be destroyed
|
||||
*
|
||||
* Currently this just frees the object. Note that the gidlist array is not
|
||||
* freed. The caller must do so if it's necessary.
|
||||
*/
|
||||
void ceph_userperm_destroy(UserPerm *perm);
|
||||
|
||||
/**
|
||||
* @defgroup libcephfs_h_init Setup and Teardown
|
||||
* These are the first and last functions that should be called
|
||||
@ -200,6 +231,8 @@ int ceph_init(struct ceph_mount_info *cmount);
|
||||
int ceph_mount(struct ceph_mount_info *cmount, const char *root);
|
||||
|
||||
|
||||
struct UserPerm *ceph_mount_perms(struct ceph_mount_info *cmount);
|
||||
|
||||
/**
|
||||
* Execute a management command remotely on an MDS.
|
||||
*
|
||||
@ -447,13 +480,16 @@ int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
|
||||
* @param dirp the directory stream pointer from an opendir holding the state of the
|
||||
* next entry to return.
|
||||
* @param de the directory entry pointer filled in with the next directory entry of the dirp state.
|
||||
* @param st the stats of the file/directory of the entry returned
|
||||
* @param stmask a mask that gets filled in with the stats fields that are being set in the st parameter.
|
||||
* @param stx the stats of the file/directory of the entry returned
|
||||
* @param want mask showing desired inode attrs for returned entry
|
||||
* @param flags bitmask of flags to use when filling out attributes
|
||||
* @param out optional returned Inode argument. If non-NULL, then a reference will be taken on
|
||||
* the inode and the pointer set on success.
|
||||
* @returns 1 if the next entry was filled in, 0 if the end of the directory stream was reached,
|
||||
* and a negative error code on failure.
|
||||
*/
|
||||
int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, struct dirent *de,
|
||||
struct stat *st, int *stmask);
|
||||
struct ceph_statx *stx, unsigned want, unsigned flags, struct Inode **out);
|
||||
|
||||
/**
|
||||
* Gets multiple directory entries.
|
||||
@ -611,16 +647,6 @@ int ceph_unlink(struct ceph_mount_info *cmount, const char *path);
|
||||
*/
|
||||
int ceph_rename(struct ceph_mount_info *cmount, const char *from, const char *to);
|
||||
|
||||
/**
|
||||
* Get a file's statistics and attributes.
|
||||
*
|
||||
* @param cmount the ceph mount handle to use for performing the stat.
|
||||
* @param path the file or directory to get the statistics of.
|
||||
* @param stbuf the stat struct that will be filled in with the file's statistics.
|
||||
* @returns 0 on success or negative error code on failure.
|
||||
*/
|
||||
int ceph_stat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf);
|
||||
|
||||
/**
|
||||
* Get a file's extended statistics and attributes.
|
||||
*
|
||||
@ -634,40 +660,8 @@ int ceph_stat(struct ceph_mount_info *cmount, const char *path, struct stat *stb
|
||||
int ceph_statx(struct ceph_mount_info *cmount, const char *path, struct ceph_statx *stx,
|
||||
unsigned int want, unsigned int flags);
|
||||
|
||||
/**
|
||||
* Get a file's statistics and attributes, without following symlinks.
|
||||
*
|
||||
* @param cmount the ceph mount handle to use for performing the stat.
|
||||
* @param path the file or directory to get the statistics of.
|
||||
* @param stbuf the stat struct that will be filled in with the file's statistics.
|
||||
* @returns 0 on success or negative error code on failure.
|
||||
*/
|
||||
int ceph_lstat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf);
|
||||
|
||||
/**
|
||||
* Set a file's attributes.
|
||||
*
|
||||
* @param cmount the ceph mount handle to use for performing the setattr.
|
||||
* @param relpath the path to the file/directory to set the attributes of.
|
||||
* @param attr the stat struct that must include attribute values to set on the file.
|
||||
* @param mask a mask of all the CEPH_SETATTR_* values that have been set in the stat struct.
|
||||
* @returns 0 on success or negative error code on failure.
|
||||
*/
|
||||
int ceph_setattr(struct ceph_mount_info *cmount, const char *relpath, struct stat *attr, int mask);
|
||||
|
||||
/**
|
||||
* Set a file's attributes.
|
||||
*
|
||||
* @param cmount the ceph mount handle to use for performing the setattr.
|
||||
* @param fd the fd of the open file/directory to set the attributes of.
|
||||
* @param attr the stat struct that must include attribute values to set on the file.
|
||||
* @param mask a mask of all the stat values that have been set on the stat struct.
|
||||
* @returns 0 on success or negative error code on failure.
|
||||
*/
|
||||
int ceph_fsetattr(struct ceph_mount_info *cmount, int fd, struct stat *attr, int mask);
|
||||
|
||||
/**
|
||||
* Set a file's attributes (extended version).
|
||||
*
|
||||
* @param cmount the ceph mount handle to use for performing the setattr.
|
||||
* @param relpath the path to the file/directory to set the attributes of.
|
||||
@ -678,6 +672,17 @@ int ceph_fsetattr(struct ceph_mount_info *cmount, int fd, struct stat *attr, int
|
||||
*/
|
||||
int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath, struct ceph_statx *stx, int mask, int flags);
|
||||
|
||||
/**
|
||||
* Set a file's attributes (extended version).
|
||||
*
|
||||
* @param cmount the ceph mount handle to use for performing the setattr.
|
||||
* @param fd the fd of the open file/directory to set the attributes of.
|
||||
* @param stx the statx struct that must include attribute values to set on the file.
|
||||
* @param mask a mask of all the stat values that have been set on the stat struct.
|
||||
* @returns 0 on success or negative error code on failure.
|
||||
*/
|
||||
int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx, int mask);
|
||||
|
||||
/**
|
||||
* Change the mode bits (permissions) of a file/directory.
|
||||
*
|
||||
@ -928,17 +933,6 @@ int ceph_fsync(struct ceph_mount_info *cmount, int fd, int syncdataonly);
|
||||
int ceph_fallocate(struct ceph_mount_info *cmount, int fd, int mode,
|
||||
int64_t offset, int64_t length);
|
||||
|
||||
/**
|
||||
* Get the open file's statistics.
|
||||
*
|
||||
* @param cmount the ceph mount handle to use for performing the fstat.
|
||||
* @param fd the file descriptor of the file to get statistics of.
|
||||
* @param stbuf the stat struct of the file's statistics, filled in by the
|
||||
* function.
|
||||
* @returns 0 on success or a negative error code on failure
|
||||
*/
|
||||
int ceph_fstat(struct ceph_mount_info *cmount, int fd, struct stat *stbuf);
|
||||
|
||||
/**
|
||||
* Get an open file's extended statistics and attributes.
|
||||
*
|
||||
@ -1434,26 +1428,22 @@ int ceph_ll_lookup_inode(
|
||||
*/
|
||||
int ceph_ll_lookup_root(struct ceph_mount_info *cmount,
|
||||
Inode **parent);
|
||||
int ceph_ll_lookup(struct ceph_mount_info *cmount, struct Inode *parent,
|
||||
const char *name, struct stat *attr,
|
||||
Inode **out, int uid, int gid);
|
||||
int ceph_ll_lookup(struct ceph_mount_info *cmount, Inode *parent,
|
||||
const char *name, Inode **out, struct ceph_statx *stx,
|
||||
unsigned want, unsigned flags, const UserPerm *perms);
|
||||
int ceph_ll_put(struct ceph_mount_info *cmount, struct Inode *in);
|
||||
int ceph_ll_forget(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
int count);
|
||||
int ceph_ll_walk(struct ceph_mount_info *cmount, const char *name,
|
||||
struct Inode **i,
|
||||
struct stat *attr);
|
||||
int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i,
|
||||
struct ceph_statx *stx, unsigned int want, unsigned int flags,
|
||||
const UserPerm *perms);
|
||||
int ceph_ll_getattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
struct stat *attr, int uid, int gid);
|
||||
int ceph_ll_getattrx(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
struct ceph_statx *stx, unsigned int want, unsigned int flags,
|
||||
int uid, int gid);
|
||||
const UserPerm *perms);
|
||||
int ceph_ll_setattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
struct stat *st, int mask, int uid, int gid);
|
||||
int ceph_ll_setattrx(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
struct ceph_statx *stx, int mask, int uid, int gid);
|
||||
struct ceph_statx *stx, int mask, const UserPerm *perms);
|
||||
int ceph_ll_open(struct ceph_mount_info *cmount, struct Inode *in, int flags,
|
||||
struct Fh **fh, int uid, int gid);
|
||||
struct Fh **fh, const UserPerm *perms);
|
||||
off_t ceph_ll_lseek(struct ceph_mount_info *cmount, struct Fh* filehandle,
|
||||
off_t offset, int whence);
|
||||
int ceph_ll_read(struct ceph_mount_info *cmount, struct Fh* filehandle,
|
||||
@ -1476,54 +1466,55 @@ int ceph_ll_iclose(struct ceph_mount_info *cmount, struct Inode *in, int mode);
|
||||
* @param name name of attribute
|
||||
* @param value pointer to begin buffer
|
||||
* @param size buffer size
|
||||
* @param uid user ID
|
||||
* @param gid group ID
|
||||
* @param perms pointer to UserPerms object
|
||||
* @returns size of returned buffer. Negative number in error case
|
||||
*/
|
||||
int ceph_ll_getxattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
const char *name, void *value, size_t size, int uid,
|
||||
int gid);
|
||||
const char *name, void *value, size_t size,
|
||||
const UserPerm *perms);
|
||||
int ceph_ll_setxattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
const char *name, const void *value, size_t size,
|
||||
int flags, int uid, int gid);
|
||||
int flags, const UserPerm *perms);
|
||||
int ceph_ll_listxattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
char *list, size_t buf_size, size_t *list_size, int uid, int gid);
|
||||
char *list, size_t buf_size, size_t *list_size,
|
||||
const UserPerm *perms);
|
||||
int ceph_ll_removexattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
const char *name, int uid, int gid);
|
||||
int ceph_ll_create(struct ceph_mount_info *cmount, struct Inode *parent,
|
||||
const char *name, mode_t mode, int flags,
|
||||
struct stat *attr, struct Inode **out, Fh **fhp,
|
||||
int uid, int gid);
|
||||
int ceph_ll_mknod(struct ceph_mount_info *cmount, struct Inode *parent,
|
||||
const char *name, mode_t mode, dev_t rdev,
|
||||
struct stat *attr, struct Inode **out,
|
||||
int uid, int gid);
|
||||
int ceph_ll_mkdir(struct ceph_mount_info *cmount, struct Inode *parent,
|
||||
const char *name, mode_t mode, struct stat *attr,
|
||||
Inode **out, int uid, int gid);
|
||||
const char *name, const UserPerm *perms);
|
||||
int ceph_ll_create(struct ceph_mount_info *cmount, Inode *parent,
|
||||
const char *name, mode_t mode, int oflags, Inode **outp,
|
||||
Fh **fhp, struct ceph_statx *stx, unsigned want,
|
||||
unsigned lflags, const UserPerm *perms);
|
||||
int ceph_ll_mknod(struct ceph_mount_info *cmount, Inode *parent,
|
||||
const char *name, mode_t mode, dev_t rdev, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want, unsigned flags,
|
||||
const UserPerm *perms);
|
||||
int ceph_ll_mkdir(struct ceph_mount_info *cmount, Inode *parent,
|
||||
const char *name, mode_t mode, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, const UserPerm *perms);
|
||||
int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
struct Inode *newparrent, const char *name,
|
||||
struct stat *attr, int uid, int gid);
|
||||
int ceph_ll_truncate(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
uint64_t length, int uid, int gid);
|
||||
struct Inode *newparent, const char *name,
|
||||
const UserPerm *perms);
|
||||
int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
struct ceph_dir_result **dirpp, int uid, int gid);
|
||||
struct ceph_dir_result **dirpp, const UserPerm *perms);
|
||||
int ceph_ll_releasedir(struct ceph_mount_info *cmount,
|
||||
struct ceph_dir_result* dir);
|
||||
int ceph_ll_rename(struct ceph_mount_info *cmount, struct Inode *parent,
|
||||
const char *name, struct Inode *newparent,
|
||||
const char *newname, int uid, int gid);
|
||||
const char *newname, const UserPerm *perms);
|
||||
int ceph_ll_unlink(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
const char *name, int uid, int gid);
|
||||
const char *name, const UserPerm *perms);
|
||||
int ceph_ll_statfs(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
struct statvfs *stbuf);
|
||||
int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
char *buf, size_t bufsize, int uid, int gid);
|
||||
int ceph_ll_symlink(struct ceph_mount_info *cmount, struct Inode *parent,
|
||||
const char *name, const char *value, struct stat *attr,
|
||||
struct Inode **in, int uid, int gid);
|
||||
char *buf, size_t bufsize, const UserPerm *perms);
|
||||
int ceph_ll_symlink(struct ceph_mount_info *cmount,
|
||||
Inode *in, const char *name, const char *value,
|
||||
Inode **out, struct ceph_statx *stx,
|
||||
unsigned want, unsigned flags,
|
||||
const UserPerm *perms);
|
||||
int ceph_ll_rmdir(struct ceph_mount_info *cmount, struct Inode *in,
|
||||
const char *name, int uid, int gid);
|
||||
const char *name, const UserPerm *perms);
|
||||
uint32_t ceph_ll_stripe_unit(struct ceph_mount_info *cmount,
|
||||
struct Inode *in);
|
||||
uint32_t ceph_ll_file_layout(struct ceph_mount_info *cmount,
|
||||
|
234
src/libcephfs.cc
234
src/libcephfs.cc
@ -284,6 +284,17 @@ static void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen)
|
||||
*outbuflen = outbl.length();
|
||||
}
|
||||
|
||||
extern "C" UserPerm *ceph_userperm_new(uid_t uid, gid_t gid, int ngids,
|
||||
gid_t *gidlist)
|
||||
{
|
||||
return new (std::nothrow) UserPerm(uid, gid, ngids, gidlist);
|
||||
}
|
||||
|
||||
extern "C" void ceph_userperm_destroy(UserPerm *perm)
|
||||
{
|
||||
delete perm;
|
||||
}
|
||||
|
||||
extern "C" const char *ceph_version(int *pmajor, int *pminor, int *ppatch)
|
||||
{
|
||||
int major, minor, patch;
|
||||
@ -441,6 +452,11 @@ extern "C" int ceph_is_mounted(struct ceph_mount_info *cmount)
|
||||
return cmount->is_mounted() ? 1 : 0;
|
||||
}
|
||||
|
||||
extern "C" struct UserPerm *ceph_mount_perms(struct ceph_mount_info *cmount)
|
||||
{
|
||||
return &cmount->default_perms;
|
||||
}
|
||||
|
||||
extern "C" int ceph_statfs(struct ceph_mount_info *cmount, const char *path,
|
||||
struct statvfs *stbuf)
|
||||
{
|
||||
@ -501,11 +517,12 @@ extern "C" int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_re
|
||||
}
|
||||
|
||||
extern "C" int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
|
||||
struct dirent *de, struct stat *st, int *stmask)
|
||||
struct dirent *de, struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, struct Inode **out)
|
||||
{
|
||||
if (!cmount->is_mounted())
|
||||
return -ENOTCONN;
|
||||
return cmount->get_client()->readdirplus_r(reinterpret_cast<dir_result_t*>(dirp), de, st, stmask);
|
||||
return cmount->get_client()->readdirplus_r(reinterpret_cast<dir_result_t*>(dirp), de, stx, want, flags, out);
|
||||
}
|
||||
|
||||
extern "C" int ceph_getdents(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
|
||||
@ -607,15 +624,6 @@ extern "C" int ceph_symlink(struct ceph_mount_info *cmount, const char *existing
|
||||
return cmount->get_client()->symlink(existing, newname, cmount->default_perms);
|
||||
}
|
||||
|
||||
// inode stuff
|
||||
extern "C" int ceph_stat(struct ceph_mount_info *cmount, const char *path,
|
||||
struct stat *stbuf)
|
||||
{
|
||||
if (!cmount->is_mounted())
|
||||
return -ENOTCONN;
|
||||
return cmount->get_client()->stat(path, stbuf, cmount->default_perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_statx(struct ceph_mount_info *cmount, const char *path,
|
||||
struct ceph_statx *stx, unsigned int want, unsigned int flags)
|
||||
{
|
||||
@ -625,28 +633,12 @@ extern "C" int ceph_statx(struct ceph_mount_info *cmount, const char *path,
|
||||
want, flags);
|
||||
}
|
||||
|
||||
extern "C" int ceph_lstat(struct ceph_mount_info *cmount, const char *path,
|
||||
struct stat *stbuf)
|
||||
extern "C" int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd,
|
||||
struct ceph_statx *stx, int mask)
|
||||
{
|
||||
if (!cmount->is_mounted())
|
||||
return -ENOTCONN;
|
||||
return cmount->get_client()->lstat(path, stbuf, cmount->default_perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_setattr(struct ceph_mount_info *cmount, const char *relpath,
|
||||
struct stat *attr, int mask)
|
||||
{
|
||||
if (!cmount->is_mounted())
|
||||
return -ENOTCONN;
|
||||
return cmount->get_client()->setattr(relpath, attr, mask, cmount->default_perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_fsetattr(struct ceph_mount_info *cmount, int fd,
|
||||
struct stat *attr, int mask)
|
||||
{
|
||||
if (!cmount->is_mounted())
|
||||
return -ENOTCONN;
|
||||
return cmount->get_client()->fsetattr(fd, attr, mask, cmount->default_perms);
|
||||
return cmount->get_client()->fsetattrx(fd, stx, mask, cmount->default_perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath,
|
||||
@ -901,13 +893,6 @@ extern "C" int ceph_fallocate(struct ceph_mount_info *cmount, int fd, int mode,
|
||||
return cmount->get_client()->fallocate(fd, mode, offset, length);
|
||||
}
|
||||
|
||||
extern "C" int ceph_fstat(struct ceph_mount_info *cmount, int fd, struct stat *stbuf)
|
||||
{
|
||||
if (!cmount->is_mounted())
|
||||
return -ENOTCONN;
|
||||
return cmount->get_client()->fstat(fd, stbuf, cmount->default_perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_fstatx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx,
|
||||
unsigned int want, unsigned int flags)
|
||||
{
|
||||
@ -1418,13 +1403,13 @@ extern "C" int ceph_ll_lookup_inode(
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_lookup(class ceph_mount_info *cmount,
|
||||
struct Inode *parent, const char *name,
|
||||
struct stat *attr, Inode **out,
|
||||
int uid, int gid)
|
||||
extern "C" int ceph_ll_lookup(struct ceph_mount_info *cmount,
|
||||
Inode *parent, const char *name, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client())->ll_lookup(parent, name, attr, out, perms);
|
||||
return (cmount->get_client())->ll_lookupx(parent, name, out, stx, want,
|
||||
flags, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_put(class ceph_mount_info *cmount, Inode *in)
|
||||
@ -1438,51 +1423,32 @@ extern "C" int ceph_ll_forget(class ceph_mount_info *cmount, Inode *in,
|
||||
return (cmount->get_client()->ll_forget(in, count));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_walk(class ceph_mount_info *cmount, const char *name,
|
||||
struct Inode **i,
|
||||
struct stat *attr)
|
||||
int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i,
|
||||
struct ceph_statx *stx, unsigned int want, unsigned int flags,
|
||||
const UserPerm *perms)
|
||||
{
|
||||
return (cmount->get_client()->ll_walk(name, i, attr, cmount->default_perms));
|
||||
return(cmount->get_client()->ll_walk(name, i, stx, want, flags, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount,
|
||||
Inode *in, struct stat *attr,
|
||||
int uid, int gid)
|
||||
Inode *in, struct ceph_statx *stx,
|
||||
unsigned int want, unsigned int flags,
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_getattr(in, attr, perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_getattrx(class ceph_mount_info *cmount,
|
||||
Inode *in, struct ceph_statx *stx,
|
||||
unsigned int want, unsigned int flags,
|
||||
int uid, int gid)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_getattrx(in, stx, want, flags, perms));
|
||||
return (cmount->get_client()->ll_getattrx(in, stx, want, flags, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount,
|
||||
Inode *in, struct stat *st,
|
||||
int mask, int uid, int gid)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_setattr(in, st, mask, perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_setattrx(class ceph_mount_info *cmount,
|
||||
Inode *in, struct ceph_statx *stx,
|
||||
int mask, int uid, int gid)
|
||||
int mask, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_setattrx(in, stx, mask, perms));
|
||||
return (cmount->get_client()->ll_setattrx(in, stx, mask, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_open(class ceph_mount_info *cmount, Inode *in,
|
||||
int flags, Fh **fh, int uid, int gid)
|
||||
int flags, Fh **fh, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_open(in, flags, fh, perms));
|
||||
return (cmount->get_client()->ll_open(in, flags, fh, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_read(class ceph_mount_info *cmount, Fh* filehandle,
|
||||
@ -1573,62 +1539,48 @@ extern "C" int ceph_ll_close(class ceph_mount_info *cmount, Fh* fh)
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_create(class ceph_mount_info *cmount,
|
||||
struct Inode *parent, const char *name,
|
||||
mode_t mode, int flags, struct stat *attr,
|
||||
struct Inode **out, Fh **fhp, int uid, int gid)
|
||||
Inode *parent, const char *name, mode_t mode,
|
||||
int oflags, Inode **outp, Fh **fhp,
|
||||
struct ceph_statx *stx, unsigned want,
|
||||
unsigned lflags, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client())->ll_create(parent, name, mode, flags,
|
||||
attr, out, fhp, perms);
|
||||
return (cmount->get_client())->ll_createx(parent, name, mode, oflags, outp,
|
||||
fhp, stx, want, lflags, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount,
|
||||
struct Inode *parent, const char *name,
|
||||
mode_t mode, dev_t rdev, struct stat *attr,
|
||||
struct Inode **out, int uid, int gid)
|
||||
extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, Inode *parent,
|
||||
const char *name, mode_t mode, dev_t rdev,
|
||||
Inode **out, struct ceph_statx *stx,
|
||||
unsigned want, unsigned flags,
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client())->ll_mknod(parent, name, mode, rdev,
|
||||
attr, out, perms);
|
||||
return (cmount->get_client())->ll_mknodx(parent, name, mode, rdev,
|
||||
out, stx, want, flags, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount,
|
||||
Inode *parent, const char *name,
|
||||
mode_t mode, struct stat *attr, Inode **out,
|
||||
int uid, int gid)
|
||||
extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, Inode *parent,
|
||||
const char *name, mode_t mode, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_mkdir(parent, name, mode, attr, out, perms));
|
||||
return cmount->get_client()->ll_mkdirx(parent, name, mode, out, stx, want,
|
||||
flags, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_link(class ceph_mount_info *cmount,
|
||||
Inode *in, Inode *newparent,
|
||||
const char *name, struct stat *attr, int uid,
|
||||
int gid)
|
||||
const char *name, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_link(in, newparent, name, attr, perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_truncate(class ceph_mount_info *cmount,
|
||||
Inode *in, uint64_t length, int uid,
|
||||
int gid)
|
||||
{
|
||||
struct stat st;
|
||||
st.st_size=length;
|
||||
UserPerm perms(uid, gid);
|
||||
|
||||
return(cmount->get_client()->ll_setattr(in, &st, CEPH_SETATTR_SIZE, perms));
|
||||
return cmount->get_client()->ll_link(in, newparent, name, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount,
|
||||
Inode *in,
|
||||
struct ceph_dir_result **dirpp,
|
||||
int uid, int gid)
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_opendir(in, O_RDONLY, (dir_result_t**) dirpp,
|
||||
perms));
|
||||
*perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount,
|
||||
@ -1641,19 +1593,16 @@ extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount,
|
||||
extern "C" int ceph_ll_rename(class ceph_mount_info *cmount,
|
||||
Inode *parent, const char *name,
|
||||
Inode *newparent, const char *newname,
|
||||
int uid, int gid)
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_rename(parent, name,
|
||||
newparent, newname, perms));
|
||||
return cmount->get_client()->ll_rename(parent, name, newparent,
|
||||
newname, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount,
|
||||
Inode *in, const char *name,
|
||||
int uid, int gid)
|
||||
extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount, Inode *in,
|
||||
const char *name, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_unlink(in, name, perms));
|
||||
return cmount->get_client()->ll_unlink(in, name, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount,
|
||||
@ -1662,44 +1611,43 @@ extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount,
|
||||
return (cmount->get_client()->ll_statfs(in, stbuf, cmount->default_perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount,
|
||||
Inode *in, char *buf, size_t bufsiz, int uid,
|
||||
int gid)
|
||||
extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount, Inode *in,
|
||||
char *buf, size_t bufsiz,
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_readlink(in, buf, bufsiz, perms));
|
||||
return cmount->get_client()->ll_readlink(in, buf, bufsiz, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount,
|
||||
Inode *in, const char *name,
|
||||
const char *value, struct stat *attr,
|
||||
Inode **out, int uid, int gid)
|
||||
const char *value, Inode **out,
|
||||
struct ceph_statx *stx, unsigned want,
|
||||
unsigned flags, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_symlink(in, name, value, attr, out, perms));
|
||||
return (cmount->get_client()->ll_symlinkx(in, name, value, out, stx, want,
|
||||
flags, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount,
|
||||
Inode *in, const char *name,
|
||||
int uid, int gid)
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_rmdir(in, name, perms));
|
||||
return cmount->get_client()->ll_rmdir(in, name, *perms);
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount,
|
||||
Inode *in, const char *name, void *value,
|
||||
size_t size, int uid, int gid)
|
||||
size_t size, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_getxattr(in, name, value, size, perms));
|
||||
return (cmount->get_client()->ll_getxattr(in, name, value, size, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount,
|
||||
Inode *in, char *list,
|
||||
size_t buf_size, size_t *list_size, int uid, int gid)
|
||||
size_t buf_size, size_t *list_size,
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
int res = cmount->get_client()->ll_listxattr(in, list, buf_size, perms);
|
||||
int res = cmount->get_client()->ll_listxattr(in, list, buf_size, *perms);
|
||||
if (res >= 0) {
|
||||
*list_size = (size_t)res;
|
||||
return 0;
|
||||
@ -1710,18 +1658,16 @@ extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount,
|
||||
extern "C" int ceph_ll_setxattr(class ceph_mount_info *cmount,
|
||||
Inode *in, const char *name,
|
||||
const void *value, size_t size,
|
||||
int flags, int uid, int gid)
|
||||
int flags, const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_setxattr(in, name, value, size, flags, perms));
|
||||
return (cmount->get_client()->ll_setxattr(in, name, value, size, flags, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_removexattr(class ceph_mount_info *cmount,
|
||||
Inode *in, const char *name,
|
||||
int uid, int gid)
|
||||
const UserPerm *perms)
|
||||
{
|
||||
UserPerm perms(uid, gid);
|
||||
return (cmount->get_client()->ll_removexattr(in, name, perms));
|
||||
return (cmount->get_client()->ll_removexattr(in, name, *perms));
|
||||
}
|
||||
|
||||
extern "C" int ceph_ll_getlk(struct ceph_mount_info *cmount,
|
||||
|
@ -80,17 +80,18 @@ TEST(LibCephFS, BasicRecordLocking) {
|
||||
sprintf(c_file, "recordlock_test_%d", getpid());
|
||||
Fh *fh = NULL;
|
||||
Inode *root = NULL, *inode = NULL;
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
int rc;
|
||||
struct flock lock1, lock2;
|
||||
UserPerm *perms = ceph_mount_perms(cmount);
|
||||
|
||||
// Get the root inode
|
||||
rc = ceph_ll_lookup_root(cmount, &root);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Get the inode and Fh corresponding to c_file
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
||||
&inode, &fh, 0, 0);
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||
&inode, &fh, &stx, 0, 0, perms);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// write lock twice
|
||||
@ -228,7 +229,7 @@ TEST(LibCephFS, BasicRecordLocking) {
|
||||
ASSERT_EQ(lock2.l_pid, getpid());
|
||||
|
||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms));
|
||||
CLEANUP_CEPH();
|
||||
}
|
||||
|
||||
@ -282,7 +283,7 @@ static void thread_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
||||
struct ceph_mount_info *const cmount = s.cmount;
|
||||
Fh *fh = NULL;
|
||||
Inode *root = NULL, *inode = NULL;
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
struct flock lock1;
|
||||
int rc;
|
||||
struct timespec ts;
|
||||
@ -292,8 +293,8 @@ static void thread_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Get the inode and Fh corresponding to c_file
|
||||
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, &attr,
|
||||
&inode, &fh, 0, 0);
|
||||
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT,
|
||||
&inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount));
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
lock1.l_type = F_WRLCK;
|
||||
@ -373,17 +374,18 @@ TEST(LibCephFS, ConcurrentRecordLocking) {
|
||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||
Fh *fh = NULL;
|
||||
Inode *root = NULL, *inode = NULL;
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
struct flock lock1;
|
||||
int rc;
|
||||
UserPerm *perms = ceph_mount_perms(cmount);
|
||||
|
||||
// Get the root inode
|
||||
rc = ceph_ll_lookup_root(cmount, &root);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Get the inode and Fh corresponding to c_file
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
||||
&inode, &fh, 0, 0);
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||
&inode, &fh, &stx, 0, 0, perms);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Lock
|
||||
@ -502,7 +504,7 @@ TEST(LibCephFS, ConcurrentRecordLocking) {
|
||||
ASSERT_EQ(NULL, retval);
|
||||
s.sem_destroy();
|
||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms));
|
||||
CLEANUP_CEPH();
|
||||
}
|
||||
|
||||
@ -515,17 +517,18 @@ TEST(LibCephFS, ThreesomeRecordLocking) {
|
||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||
Fh *fh = NULL;
|
||||
Inode *root = NULL, *inode = NULL;
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
struct flock lock1;
|
||||
int rc;
|
||||
UserPerm *perms = ceph_mount_perms(cmount);
|
||||
|
||||
// Get the root inode
|
||||
rc = ceph_ll_lookup_root(cmount, &root);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Get the inode and Fh corresponding to c_file
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
||||
&inode, &fh, 0, 0);
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||
&inode, &fh, &stx, 0, 0, perms);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Lock
|
||||
@ -648,7 +651,7 @@ TEST(LibCephFS, ThreesomeRecordLocking) {
|
||||
ASSERT_EQ(NULL, retval);
|
||||
s.sem_destroy();
|
||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms));
|
||||
CLEANUP_CEPH();
|
||||
}
|
||||
|
||||
@ -667,7 +670,7 @@ static void process_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
||||
struct timespec ts;
|
||||
Fh *fh = NULL;
|
||||
Inode *root = NULL, *inode = NULL;
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
int rc;
|
||||
struct flock lock1;
|
||||
|
||||
@ -679,8 +682,8 @@ static void process_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Get the inode and Fh corresponding to c_file
|
||||
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, &attr,
|
||||
&inode, &fh, 0, 0);
|
||||
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT,
|
||||
&inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount));
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
WAIT_MAIN(1); // (R1)
|
||||
@ -758,7 +761,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) {
|
||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||
Fh *fh = NULL;
|
||||
Inode *root = NULL, *inode = NULL;
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
struct flock lock1;
|
||||
int rc;
|
||||
|
||||
@ -782,14 +785,15 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) {
|
||||
struct timespec ts;
|
||||
struct ceph_mount_info *cmount;
|
||||
STARTUP_CEPH();
|
||||
UserPerm *perms = ceph_mount_perms(cmount);
|
||||
|
||||
// Get the root inode
|
||||
rc = ceph_ll_lookup_root(cmount, &root);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Get the inode and Fh corresponding to c_file
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
||||
&inode, &fh, 0, 0);
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||
&inode, &fh, &stx, 0, 0, perms);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Lock
|
||||
@ -906,7 +910,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) {
|
||||
s.sem_destroy();
|
||||
ASSERT_EQ(0, munmap(shs, sizeof(*shs)));
|
||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms));
|
||||
CLEANUP_CEPH();
|
||||
}
|
||||
|
||||
@ -919,7 +923,7 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) {
|
||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||
Fh *fh = NULL;
|
||||
Inode *root = NULL, *inode = NULL;
|
||||
struct stat attr;
|
||||
struct ceph_statx stx;
|
||||
struct flock lock1;
|
||||
int rc;
|
||||
|
||||
@ -956,8 +960,9 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) {
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Get the inode and Fh corresponding to c_file
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
||||
&inode, &fh, 0, 0);
|
||||
UserPerm *perms = ceph_mount_perms(cmount);
|
||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||
&inode, &fh, &stx, 0, 0, perms);
|
||||
ASSERT_EQ(rc, 0);
|
||||
|
||||
// Lock
|
||||
@ -1077,6 +1082,6 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) {
|
||||
s.sem_destroy();
|
||||
ASSERT_EQ(0, munmap(shs, sizeof(*shs)));
|
||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0));
|
||||
ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms));
|
||||
CLEANUP_CEPH();
|
||||
}
|
||||
|
@ -424,9 +424,9 @@ TEST(LibCephFS, DirLs) {
|
||||
found.clear();
|
||||
while (true) {
|
||||
struct dirent rdent;
|
||||
struct stat st;
|
||||
int stmask;
|
||||
int len = ceph_readdirplus_r(cmount, ls_dir, &rdent, &st, &stmask);
|
||||
struct ceph_statx stx;
|
||||
int len = ceph_readdirplus_r(cmount, ls_dir, &rdent, &stx,
|
||||
CEPH_STATX_SIZE, AT_NO_ATTR_SYNC, NULL);
|
||||
if (len == 0)
|
||||
break;
|
||||
ASSERT_EQ(len, 1);
|
||||
@ -434,8 +434,9 @@ TEST(LibCephFS, DirLs) {
|
||||
found.push_back(name);
|
||||
int size;
|
||||
sscanf(name, "dirf%d", &size);
|
||||
ASSERT_EQ(st.st_size, size);
|
||||
ASSERT_EQ(st.st_ino, rdent.d_ino);
|
||||
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_SIZE);
|
||||
ASSERT_EQ(stx.stx_size, (size_t)size);
|
||||
ASSERT_EQ(stx.stx_ino, rdent.d_ino);
|
||||
//ASSERT_EQ(st.st_mode, (mode_t)0666);
|
||||
}
|
||||
ASSERT_EQ(found, entries);
|
||||
@ -568,21 +569,25 @@ TEST(LibCephFS, Xattrs_ll) {
|
||||
|
||||
Inode *root = NULL;
|
||||
Inode *existent_file_handle = NULL;
|
||||
struct stat attr;
|
||||
|
||||
int res = ceph_ll_lookup_root(cmount, &root);
|
||||
ASSERT_EQ(res, 0);
|
||||
res = ceph_ll_lookup(cmount, root, test_xattr_file, &attr, &existent_file_handle, 0, 0);
|
||||
|
||||
UserPerm *perms = ceph_mount_perms(cmount);
|
||||
struct ceph_statx stx;
|
||||
|
||||
res = ceph_ll_lookup(cmount, root, test_xattr_file, &existent_file_handle,
|
||||
&stx, 0, 0, perms);
|
||||
ASSERT_EQ(res, 0);
|
||||
|
||||
const char *valid_name = "user.attrname";
|
||||
const char *value = "attrvalue";
|
||||
char value_buf[256] = { 0 };
|
||||
|
||||
res = ceph_ll_setxattr(cmount, existent_file_handle, valid_name, value, strlen(value), 0, 0, 0);
|
||||
res = ceph_ll_setxattr(cmount, existent_file_handle, valid_name, value, strlen(value), 0, perms);
|
||||
ASSERT_EQ(res, 0);
|
||||
|
||||
res = ceph_ll_getxattr(cmount, existent_file_handle, valid_name, value_buf, 256, 0, 0);
|
||||
res = ceph_ll_getxattr(cmount, existent_file_handle, valid_name, value_buf, 256, perms);
|
||||
ASSERT_EQ(res, (int)strlen(value));
|
||||
|
||||
value_buf[res] = '\0';
|
||||
@ -1132,10 +1137,8 @@ TEST(LibCephFS, UseUnmounted) {
|
||||
struct dirent rdent;
|
||||
EXPECT_EQ(-ENOTCONN, ceph_readdir_r(cmount, dirp, &rdent));
|
||||
|
||||
int stmask;
|
||||
struct ceph_statx stx;
|
||||
struct stat st;
|
||||
EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &st, &stmask));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &stx, 0, 0, NULL));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_getdents(cmount, dirp, NULL, 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_getdnames(cmount, dirp, NULL, 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_telldir(cmount, dirp));
|
||||
@ -1157,7 +1160,7 @@ TEST(LibCephFS, UseUnmounted) {
|
||||
EXPECT_EQ(-ENOTCONN, ceph_lremovexattr(cmount, "/path", "name"));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_setxattr(cmount, "/path", "name", NULL, 0, 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_lsetxattr(cmount, "/path", "name", NULL, 0, 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_fsetattr(cmount, 0, &st, 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_fsetattrx(cmount, 0, &stx, 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_chmod(cmount, "/path", 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_fchmod(cmount, 0, 0));
|
||||
EXPECT_EQ(-ENOTCONN, ceph_chown(cmount, "/path", 0, 0));
|
||||
@ -1392,20 +1395,23 @@ TEST(LibCephFS, Nlink) {
|
||||
sprintf(filename, "nlinkorig%x", getpid());
|
||||
sprintf(linkname, "nlinklink%x", getpid());
|
||||
|
||||
struct stat st;
|
||||
struct ceph_statx stx;
|
||||
Fh *fh;
|
||||
UserPerm *perms = ceph_mount_perms(cmount);
|
||||
|
||||
ASSERT_EQ(ceph_ll_mkdir(cmount, root, dirname, 0755, &st, &dir, getuid(), getgid()), 0);
|
||||
ASSERT_EQ(ceph_ll_mkdir(cmount, root, dirname, 0755, &dir, &stx, 0, 0, perms), 0);
|
||||
ASSERT_EQ(ceph_ll_create(cmount, dir, filename, 0666, O_RDWR|O_CREAT|O_EXCL,
|
||||
&st, &file, &fh, getuid(), getgid()), 0);
|
||||
ASSERT_EQ(st.st_nlink, (nlink_t)1);
|
||||
&file, &fh, &stx, CEPH_STATX_NLINK, 0, perms), 0);
|
||||
ASSERT_EQ(stx.stx_nlink, (nlink_t)1);
|
||||
|
||||
ASSERT_EQ(ceph_ll_link(cmount, file, dir, linkname, &st, getuid(), getgid()), 0);
|
||||
ASSERT_EQ(st.st_nlink, (nlink_t)2);
|
||||
ASSERT_EQ(ceph_ll_link(cmount, file, dir, linkname, perms), 0);
|
||||
ASSERT_EQ(ceph_ll_getattr(cmount, file, &stx, CEPH_STATX_NLINK, 0, perms), 0);
|
||||
ASSERT_EQ(stx.stx_nlink, (nlink_t)2);
|
||||
|
||||
ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, getuid(), getgid()), 0);
|
||||
ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &st, &file, getuid(), getgid()), 0);
|
||||
ASSERT_EQ(st.st_nlink, (nlink_t)1);
|
||||
ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, perms), 0);
|
||||
ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &file, &stx,
|
||||
CEPH_STATX_NLINK, 0, perms), 0);
|
||||
ASSERT_EQ(stx.stx_nlink, (nlink_t)1);
|
||||
|
||||
ceph_shutdown(cmount);
|
||||
}
|
||||
@ -1558,30 +1564,31 @@ TEST(LibCephFS, LazyStatx) {
|
||||
sprintf(filename, "lazystatx%x", getpid());
|
||||
|
||||
Inode *root1, *file1, *root2, *file2;
|
||||
struct stat st;
|
||||
struct ceph_statx stx;
|
||||
Fh *fh;
|
||||
UserPerm *perms1 = ceph_mount_perms(cmount1);
|
||||
UserPerm *perms2 = ceph_mount_perms(cmount2);
|
||||
|
||||
ASSERT_EQ(ceph_ll_lookup_root(cmount1, &root1), 0);
|
||||
ceph_ll_unlink(cmount1, root1, filename, getuid(), getgid());
|
||||
ceph_ll_unlink(cmount1, root1, filename, perms1);
|
||||
ASSERT_EQ(ceph_ll_create(cmount1, root1, filename, 0666, O_RDWR|O_CREAT|O_EXCL,
|
||||
&st, &file1, &fh, getuid(), getgid()), 0);
|
||||
|
||||
&file1, &fh, &stx, 0, 0, perms1), 0);
|
||||
|
||||
ASSERT_EQ(ceph_ll_lookup_root(cmount2, &root2), 0);
|
||||
ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &st, &file2, getuid(), getgid()), 0);
|
||||
|
||||
struct timespec old_ctime = st.st_ctim;
|
||||
ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &file2, &stx, CEPH_STATX_CTIME, 0, perms2), 0);
|
||||
|
||||
struct timespec old_ctime = stx.stx_ctime;
|
||||
|
||||
/*
|
||||
* Now sleep, do a chmod on the first client and the see whether we get a
|
||||
* different ctime with a statx that uses AT_NO_ATTR_SYNC
|
||||
*/
|
||||
sleep(1);
|
||||
st.st_mode = 0644;
|
||||
ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &st, CEPH_SETATTR_MODE, getuid(), getgid()), 0);
|
||||
stx.stx_mode = 0644;
|
||||
ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &stx, CEPH_SETATTR_MODE, perms1), 0);
|
||||
|
||||
struct ceph_statx stx;
|
||||
ASSERT_EQ(ceph_ll_getattrx(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, getuid(), getgid()), 0);
|
||||
ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, perms2), 0);
|
||||
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME);
|
||||
ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec &&
|
||||
stx.stx_ctime.tv_nsec == old_ctime.tv_nsec);
|
||||
@ -1685,14 +1692,12 @@ TEST(LibCephFS, SetSize) {
|
||||
int fd = ceph_open(cmount, filename, O_RDWR|O_CREAT|O_EXCL, 0666);
|
||||
ASSERT_LT(0, fd);
|
||||
|
||||
struct stat st;
|
||||
struct ceph_statx stx;
|
||||
uint64_t size = 8388608;
|
||||
st.st_size = (off_t)size;
|
||||
ASSERT_EQ(ceph_fsetattr(cmount, fd, &st, CEPH_SETATTR_SIZE), 0);
|
||||
|
||||
struct stat stbuf;
|
||||
ASSERT_EQ(ceph_fstat(cmount, fd, &stbuf), 0);
|
||||
ASSERT_EQ(stbuf.st_size, (off_t)size);
|
||||
stx.stx_size = (off_t)size;
|
||||
ASSERT_EQ(ceph_fsetattrx(cmount, fd, &stx, CEPH_SETATTR_SIZE), 0);
|
||||
ASSERT_EQ(ceph_fstatx(cmount, fd, &stx, CEPH_STATX_SIZE, 0), 0);
|
||||
ASSERT_EQ(stx.stx_size, (off_t)size);
|
||||
|
||||
ceph_close(cmount, fd);
|
||||
ceph_shutdown(cmount);
|
||||
|
@ -69,9 +69,10 @@ void PgFiles::hit_dir(std::string const &path)
|
||||
continue;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
struct ceph_statx stx;
|
||||
std::string de_path = (path + std::string("/") + de.d_name);
|
||||
r = ceph_stat(cmount, de_path.c_str(), &st);
|
||||
r = ceph_statx(cmount, de_path.c_str(), &stx,
|
||||
CEPH_STATX_INO|CEPH_STATX_SIZE, 0);
|
||||
if (r != 0) {
|
||||
derr << "Failed to stat path " << de_path << ": "
|
||||
<< cpp_strerror(r) << dendl;
|
||||
@ -79,9 +80,9 @@ void PgFiles::hit_dir(std::string const &path)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
hit_file(de_path, st);
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
if (S_ISREG(stx.stx_mode)) {
|
||||
hit_file(de_path, stx);
|
||||
} else if (S_ISDIR(stx.stx_mode)) {
|
||||
hit_dir(de_path);
|
||||
} else {
|
||||
dout(20) << "Skipping non reg/dir file: " << de_path << dendl;
|
||||
@ -95,9 +96,9 @@ void PgFiles::hit_dir(std::string const &path)
|
||||
}
|
||||
}
|
||||
|
||||
void PgFiles::hit_file(std::string const &path, struct stat const &st)
|
||||
void PgFiles::hit_file(std::string const &path, const struct ceph_statx &stx)
|
||||
{
|
||||
assert(S_ISREG(st.st_mode));
|
||||
assert(S_ISREG(stx.stx_mode));
|
||||
|
||||
dout(20) << "Hitting file '" << path << "'" << dendl;
|
||||
|
||||
@ -127,11 +128,11 @@ void PgFiles::hit_file(std::string const &path, struct stat const &st)
|
||||
return;
|
||||
}
|
||||
|
||||
auto num_objects = Striper::get_num_objects(layout, st.st_size);
|
||||
auto num_objects = Striper::get_num_objects(layout, stx.stx_size);
|
||||
|
||||
for (uint64_t i = 0; i < num_objects; ++i) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)st.st_ino,
|
||||
snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)stx.stx_ino,
|
||||
(long long unsigned int)i);
|
||||
dout(20) << " object " << std::string(buf) << dendl;
|
||||
|
||||
|
@ -35,7 +35,7 @@ private:
|
||||
std::set<pg_t> pgs;
|
||||
std::set<uint64_t> pools;
|
||||
|
||||
void hit_file(std::string const &path, const struct stat &st);
|
||||
void hit_file(std::string const &path, const struct ceph_statx &stx);
|
||||
void hit_dir(std::string const &path);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user