mirror of
https://github.com/ceph/ceph
synced 2025-04-11 04:02:04 +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: ceph-common = %{epoch}:%{version}-%{release}
|
||||||
Requires: librbd1 = %{epoch}:%{version}-%{release}
|
Requires: librbd1 = %{epoch}:%{version}-%{release}
|
||||||
Requires: librados2 = %{epoch}:%{version}-%{release}
|
Requires: librados2 = %{epoch}:%{version}-%{release}
|
||||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||||
Requires: librgw2 = %{epoch}:%{version}-%{release}
|
Requires: librgw2 = %{epoch}:%{version}-%{release}
|
||||||
%if 0%{with selinux}
|
%if 0%{with selinux}
|
||||||
Requires: ceph-selinux = %{epoch}:%{version}-%{release}
|
Requires: ceph-selinux = %{epoch}:%{version}-%{release}
|
||||||
@ -247,7 +247,7 @@ Summary: Ceph Common
|
|||||||
Group: System Environment/Base
|
Group: System Environment/Base
|
||||||
Requires: librbd1 = %{epoch}:%{version}-%{release}
|
Requires: librbd1 = %{epoch}:%{version}-%{release}
|
||||||
Requires: librados2 = %{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-rados = %{epoch}:%{version}-%{release}
|
||||||
Requires: python-rbd = %{epoch}:%{version}-%{release}
|
Requires: python-rbd = %{epoch}:%{version}-%{release}
|
||||||
Requires: python-cephfs = %{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
|
This package contains Python 3 libraries for interacting with Cephs RADOS
|
||||||
block device.
|
block device.
|
||||||
|
|
||||||
%package -n libcephfs1
|
%package -n libcephfs2
|
||||||
Summary: Ceph distributed file system client library
|
Summary: Ceph distributed file system client library
|
||||||
Group: System Environment/Libraries
|
Group: System Environment/Libraries
|
||||||
License: LGPL-2.0
|
License: LGPL-2.0
|
||||||
@ -525,7 +525,7 @@ License: LGPL-2.0
|
|||||||
Obsoletes: ceph-libs < %{epoch}:%{version}-%{release}
|
Obsoletes: ceph-libs < %{epoch}:%{version}-%{release}
|
||||||
Obsoletes: ceph-libcephfs
|
Obsoletes: ceph-libcephfs
|
||||||
%endif
|
%endif
|
||||||
%description -n libcephfs1
|
%description -n libcephfs2
|
||||||
Ceph is a distributed network file system designed to provide excellent
|
Ceph is a distributed network file system designed to provide excellent
|
||||||
performance, reliability, and scalability. This is a shared library
|
performance, reliability, and scalability. This is a shared library
|
||||||
allowing applications to access a Ceph distributed file system via a
|
allowing applications to access a Ceph distributed file system via a
|
||||||
@ -535,11 +535,11 @@ POSIX-like interface.
|
|||||||
Summary: Ceph distributed file system headers
|
Summary: Ceph distributed file system headers
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
License: LGPL-2.0
|
License: LGPL-2.0
|
||||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||||
Requires: librados-devel = %{epoch}:%{version}-%{release}
|
Requires: librados-devel = %{epoch}:%{version}-%{release}
|
||||||
Obsoletes: ceph-devel < %{epoch}:%{version}-%{release}
|
Obsoletes: ceph-devel < %{epoch}:%{version}-%{release}
|
||||||
Provides: libcephfs1-devel = %{epoch}:%{version}-%{release}
|
Provides: libcephfs2-devel = %{epoch}:%{version}-%{release}
|
||||||
Obsoletes: libcephfs1-devel < %{epoch}:%{version}-%{release}
|
Obsoletes: libcephfs2-devel < %{epoch}:%{version}-%{release}
|
||||||
%description -n libcephfs-devel
|
%description -n libcephfs-devel
|
||||||
This package contains libraries and headers needed to develop programs
|
This package contains libraries and headers needed to develop programs
|
||||||
that use Cephs distributed file system.
|
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
|
Summary: Python 2 libraries for Ceph distributed file system
|
||||||
Group: System Environment/Libraries
|
Group: System Environment/Libraries
|
||||||
License: LGPL-2.0
|
License: LGPL-2.0
|
||||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||||
Requires: python-rados = %{epoch}:%{version}-%{release}
|
Requires: python-rados = %{epoch}:%{version}-%{release}
|
||||||
Obsoletes: python-ceph < %{epoch}:%{version}-%{release}
|
Obsoletes: python-ceph < %{epoch}:%{version}-%{release}
|
||||||
%description -n python-cephfs
|
%description -n python-cephfs
|
||||||
@ -559,7 +559,7 @@ file system.
|
|||||||
Summary: Python 3 libraries for Ceph distributed file system
|
Summary: Python 3 libraries for Ceph distributed file system
|
||||||
Group: System Environment/Libraries
|
Group: System Environment/Libraries
|
||||||
License: LGPL-2.0
|
License: LGPL-2.0
|
||||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||||
Requires: python%{python3_pkgversion}-rados = %{epoch}:%{version}-%{release}
|
Requires: python%{python3_pkgversion}-rados = %{epoch}:%{version}-%{release}
|
||||||
%description -n python%{python3_pkgversion}-cephfs
|
%description -n python%{python3_pkgversion}-cephfs
|
||||||
This package contains Python 3 libraries for interacting with Cephs distributed
|
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
|
Group: System Environment/Libraries
|
||||||
License: LGPL-2.0
|
License: LGPL-2.0
|
||||||
Requires: java
|
Requires: java
|
||||||
Requires: libcephfs1 = %{epoch}:%{version}-%{release}
|
Requires: libcephfs2 = %{epoch}:%{version}-%{release}
|
||||||
%description -n libcephfs_jni1
|
%description -n libcephfs_jni1
|
||||||
This package contains the Java Native Interface library for CephFS Java
|
This package contains the Java Native Interface library for CephFS Java
|
||||||
bindings.
|
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.cpython*.so
|
||||||
%{python3_sitearch}/rbd-*.egg-info
|
%{python3_sitearch}/rbd-*.egg-info
|
||||||
|
|
||||||
%files -n libcephfs1
|
%files -n libcephfs2
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
%{_libdir}/libcephfs.so.*
|
%{_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
|
%files -n libcephfs-devel
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
|
4
debian/.gitignore
vendored
4
debian/.gitignore
vendored
@ -21,9 +21,9 @@
|
|||||||
/*.debhelper
|
/*.debhelper
|
||||||
/ceph
|
/ceph
|
||||||
/files
|
/files
|
||||||
/libcephfs1-dbg
|
/libcephfs2-dbg
|
||||||
/libcephfs-dev
|
/libcephfs-dev
|
||||||
/libcephfs1
|
/libcephfs2
|
||||||
/librados2-dbg
|
/librados2-dbg
|
||||||
/librados-dev
|
/librados-dev
|
||||||
/librados2
|
/librados2
|
||||||
|
24
debian/control
vendored
24
debian/control
vendored
@ -120,7 +120,7 @@ Depends: ceph-base (= ${binary:Version}),
|
|||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends}
|
${shlibs:Depends}
|
||||||
Recommends: ceph-fuse (= ${binary:Version}),
|
Recommends: ceph-fuse (= ${binary:Version}),
|
||||||
libcephfs1 (= ${binary:Version})
|
libcephfs2 (= ${binary:Version})
|
||||||
Replaces: ceph (<< 0.93-417)
|
Replaces: ceph (<< 0.93-417)
|
||||||
Breaks: ceph (<< 0.93-417)
|
Breaks: ceph (<< 0.93-417)
|
||||||
Description: metadata server for the ceph distributed file system
|
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
|
This package contains development files needed for building applications that
|
||||||
link against librbd1.
|
link against librbd1.
|
||||||
|
|
||||||
Package: libcephfs1
|
Package: libcephfs2
|
||||||
Conflicts: libceph, libceph1, libcephfs
|
Conflicts: libceph, libceph1, libcephfs
|
||||||
Replaces: libceph, libceph1, libcephfs
|
Replaces: libceph, libceph1, libcephfs
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
@ -529,28 +529,28 @@ Description: Ceph distributed file system client library
|
|||||||
shared library allowing applications to access a Ceph distributed
|
shared library allowing applications to access a Ceph distributed
|
||||||
file system via a POSIX-like interface.
|
file system via a POSIX-like interface.
|
||||||
|
|
||||||
Package: libcephfs1-dbg
|
Package: libcephfs2-dbg
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
Section: debug
|
Section: debug
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Depends: libcephfs1 (= ${binary:Version}), ${misc:Depends}
|
Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}
|
||||||
Conflicts: libceph1-dbg
|
Conflicts: libceph1-dbg
|
||||||
Replaces: libceph1-dbg
|
Replaces: libceph1-dbg
|
||||||
Description: debugging symbols for libcephfs1
|
Description: debugging symbols for libcephfs2
|
||||||
Ceph is a massively scalable, open-source, distributed
|
Ceph is a massively scalable, open-source, distributed
|
||||||
storage system that runs on commodity hardware and delivers object,
|
storage system that runs on commodity hardware and delivers object,
|
||||||
block and file system storage. This is a
|
block and file system storage. This is a
|
||||||
shared library allowing applications to access a Ceph distributed
|
shared library allowing applications to access a Ceph distributed
|
||||||
file system via a POSIX-like interface.
|
file system via a POSIX-like interface.
|
||||||
.
|
.
|
||||||
This package contains debugging symbols for libcephfs1.
|
This package contains debugging symbols for libcephfs2.
|
||||||
|
|
||||||
Package: libcephfs-dev
|
Package: libcephfs-dev
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
Section: libdevel
|
Section: libdevel
|
||||||
Depends: libcephfs1 (= ${binary:Version}), ${misc:Depends}
|
Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}
|
||||||
Conflicts: libceph-dev, libceph1-dev, libcephfs1-dev
|
Conflicts: libceph-dev, libceph1-dev, libcephfs2-dev
|
||||||
Replaces: libceph-dev, libceph1-dev, libcephfs1-dev
|
Replaces: libceph-dev, libceph1-dev, libcephfs2-dev
|
||||||
Description: Ceph distributed file system client library (development files)
|
Description: Ceph distributed file system client library (development files)
|
||||||
Ceph is a massively scalable, open-source, distributed
|
Ceph is a massively scalable, open-source, distributed
|
||||||
storage system that runs on commodity hardware and delivers object,
|
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
|
Package: python-cephfs
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
Section: python
|
Section: python
|
||||||
Depends: libcephfs1 (= ${binary:Version}),
|
Depends: libcephfs2 (= ${binary:Version}),
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
${python:Depends}
|
${python:Depends}
|
||||||
@ -743,7 +743,7 @@ Description: Python 2 libraries for the Ceph libcephfs library
|
|||||||
Package: python3-cephfs
|
Package: python3-cephfs
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
Section: python
|
Section: python
|
||||||
Depends: libcephfs1 (= ${binary:Version}),
|
Depends: libcephfs2 (= ${binary:Version}),
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
${python3:Depends}
|
${python3:Depends}
|
||||||
@ -776,6 +776,6 @@ Description: Java libraries for the Ceph File System
|
|||||||
Package: libcephfs-jni
|
Package: libcephfs-jni
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
Section: java
|
Section: java
|
||||||
Depends: libcephfs1 (= ${binary:Version}), ${java:Depends},
|
Depends: libcephfs2 (= ${binary:Version}), ${java:Depends},
|
||||||
${misc:Depends}, ${shlibs:Depends}
|
${misc:Depends}, ${shlibs:Depends}
|
||||||
Description: Java Native Interface library for CephFS Java bindings
|
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 -plibrados2 --dbg-package=librados2-dbg
|
||||||
dh_strip -plibradosstriper1 --dbg-package=libradosstriper1-dbg
|
dh_strip -plibradosstriper1 --dbg-package=libradosstriper1-dbg
|
||||||
dh_strip -plibrbd1 --dbg-package=librbd1-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 -plibrgw2 --dbg-package=librgw2-dbg
|
||||||
dh_strip -pradosgw --dbg-package=radosgw-dbg
|
dh_strip -pradosgw --dbg-package=radosgw-dbg
|
||||||
dh_strip -pceph-test --dbg-package=ceph-test-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
|
||||||
sudo apt-get -y purge librbd1-dbg
|
sudo apt-get -y purge librbd1-dbg
|
||||||
sudo apt-get -y purge librbd-dev
|
sudo apt-get -y purge librbd-dev
|
||||||
sudo apt-get -y purge libcephfs1
|
sudo apt-get -y purge libcephfs2
|
||||||
sudo apt-get -y purge libcephfs1-dbg
|
sudo apt-get -y purge libcephfs2-dbg
|
||||||
sudo apt-get -y purge libcephfs-dev
|
sudo apt-get -y purge libcephfs-dev
|
||||||
sudo apt-get -y purge radosgw
|
sudo apt-get -y purge radosgw
|
||||||
sudo apt-get -y purge radosgw-dbg
|
sudo apt-get -y purge radosgw-dbg
|
||||||
|
@ -806,8 +806,8 @@ if(WITH_LIBCEPHFS)
|
|||||||
endforeach()
|
endforeach()
|
||||||
set_target_properties(cephfs PROPERTIES
|
set_target_properties(cephfs PROPERTIES
|
||||||
OUTPUT_NAME cephfs
|
OUTPUT_NAME cephfs
|
||||||
VERSION 1.0.0
|
VERSION 2.0.0
|
||||||
SOVERSION 1
|
SOVERSION 2
|
||||||
LINK_FLAGS ${CEPHFS_LINK_FLAGS})
|
LINK_FLAGS ${CEPHFS_LINK_FLAGS})
|
||||||
endif(ENABLE_SHARED)
|
endif(ENABLE_SHARED)
|
||||||
install(TARGETS cephfs DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
install(TARGETS cephfs DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
@ -6568,10 +6568,12 @@ force_request:
|
|||||||
CEPH_CAP_FILE_WR;
|
CEPH_CAP_FILE_WR;
|
||||||
}
|
}
|
||||||
if (mask & CEPH_SETATTR_SIZE) {
|
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;
|
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);
|
put_request(req);
|
||||||
|
ldout(cct,10) << "unable to set size to " << stx->stx_size << ". Too large!" << dendl;
|
||||||
return -EFBIG;
|
return -EFBIG;
|
||||||
}
|
}
|
||||||
req->inode_drop |= CEPH_CAP_AUTH_SHARED | CEPH_CAP_FILE_RD |
|
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);
|
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,
|
int Client::stat(const char *relpath, struct stat *stbuf, const UserPerm& perms,
|
||||||
frag_info_t *dirstat, int mask)
|
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());
|
assert(client_lock.is_locked());
|
||||||
ldout(cct, 10) << "_readdir_cache_cb " << dirp << " on " << dirp->inode->ino
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
int r = _getattr(dn->inode, caps, dirp->perms);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
struct ceph_statx stx;
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
int stmask = fill_stat(dn->inode, &st);
|
fill_statx(dn->inode, caps, &stx);
|
||||||
|
|
||||||
uint64_t next_off = dn->offset + 1;
|
uint64_t next_off = dn->offset + 1;
|
||||||
++pd;
|
++pd;
|
||||||
if (pd == dir->readdir_cache.end())
|
if (pd == dir->readdir_cache.end())
|
||||||
next_off = dir_result_t::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
|
dn_name = dn->name; // fill in name while we have lock
|
||||||
|
|
||||||
client_lock.Unlock();
|
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();
|
client_lock.Lock();
|
||||||
ldout(cct, 15) << " de " << de.d_name << " off " << hex << dn->offset << dec
|
ldout(cct, 15) << " de " << de.d_name << " off " << hex << dn->offset << dec
|
||||||
<< " = " << r << dendl;
|
<< " = " << r << dendl;
|
||||||
@ -7380,8 +7409,11 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p)
|
|||||||
return 0;
|
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);
|
Mutex::Locker lock(client_lock);
|
||||||
|
|
||||||
dir_result_t *dirp = static_cast<dir_result_t*>(d);
|
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;
|
<< " hash_order=" << dirp->hash_order() << dendl;
|
||||||
|
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
struct stat st;
|
struct ceph_statx stx;
|
||||||
memset(&de, 0, sizeof(de));
|
memset(&de, 0, sizeof(de));
|
||||||
memset(&st, 0, sizeof(st));
|
memset(&stx, 0, sizeof(stx));
|
||||||
|
|
||||||
InodeRef& diri = dirp->inode;
|
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
|
assert(diri->dn_set.size() < 2); // can't have multiple hard-links to a dir
|
||||||
uint64_t next_off = 1;
|
uint64_t next_off = 1;
|
||||||
|
|
||||||
fill_stat(diri, &st);
|
int r;
|
||||||
fill_dirent(&de, ".", S_IFDIR, st.st_ino, next_off);
|
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();
|
client_lock.Unlock();
|
||||||
int r = cb(p, &de, &st, -1, next_off);
|
r = cb(p, &de, &stx, next_off, inode);
|
||||||
client_lock.Lock();
|
client_lock.Lock();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -7427,11 +7470,22 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
|
|||||||
else
|
else
|
||||||
in = diri->get_first_parent()->inode;
|
in = diri->get_first_parent()->inode;
|
||||||
|
|
||||||
fill_stat(in, &st);
|
int r;
|
||||||
fill_dirent(&de, "..", S_IFDIR, st.st_ino, next_off);
|
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();
|
client_lock.Unlock();
|
||||||
int r = cb(p, &de, &st, -1, next_off);
|
r = cb(p, &de, &stx, next_off, inode);
|
||||||
client_lock.Lock();
|
client_lock.Lock();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
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 &&
|
if (dirp->inode->snapid != CEPH_SNAPDIR &&
|
||||||
dirp->inode->is_complete_and_ordered() &&
|
dirp->inode->is_complete_and_ordered() &&
|
||||||
dirp->inode->caps_issued_mask(CEPH_CAP_FILE_SHARED)) {
|
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)
|
if (err != -EAGAIN)
|
||||||
return err;
|
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())
|
if (dirp->at_end())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
bool check_caps = true;
|
||||||
if (!dirp->is_cached()) {
|
if (!dirp->is_cached()) {
|
||||||
int r = _readdir_get_frag(dirp);
|
int r = _readdir_get_frag(dirp);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
// _readdir_get_frag () may updates dirp->offset if the replied dirfrag is
|
// _readdir_get_frag () may updates dirp->offset if the replied dirfrag is
|
||||||
// different than the requested one. (our dirfragtree was outdated)
|
// different than the requested one. (our dirfragtree was outdated)
|
||||||
|
check_caps = false;
|
||||||
}
|
}
|
||||||
frag_t fg = dirp->buffer_frag;
|
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;
|
dir_result_t::dentry &entry = *it;
|
||||||
|
|
||||||
uint64_t next_off = entry.offset + 1;
|
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();
|
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();
|
client_lock.Lock();
|
||||||
|
|
||||||
ldout(cct, 15) << " de " << de.d_name << " off " << hex << next_off - 1 << dec
|
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)
|
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 single_readdir {
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
struct stat *st;
|
struct ceph_statx *stx;
|
||||||
int *stmask;
|
Inode *inode;
|
||||||
bool full;
|
bool full;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int _readdir_single_dirent_cb(void *p, struct dirent *de, struct stat *st,
|
static int _readdir_single_dirent_cb(void *p, struct dirent *de,
|
||||||
int stmask, off_t off)
|
struct ceph_statx *stx, off_t off,
|
||||||
|
Inode *in)
|
||||||
{
|
{
|
||||||
single_readdir *c = static_cast<single_readdir *>(p);
|
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
|
return -1; // already filled this dirent
|
||||||
|
|
||||||
*c->de = *de;
|
*c->de = *de;
|
||||||
if (c->st)
|
if (c->stx)
|
||||||
*c->st = *st;
|
*c->stx = *stx;
|
||||||
if (c->stmask)
|
c->inode = in;
|
||||||
*c->stmask = stmask;
|
|
||||||
c->full = true;
|
c->full = true;
|
||||||
return 1;
|
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)
|
struct dirent *Client::readdir(dir_result_t *d)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
static int stmask;
|
|
||||||
static struct dirent de;
|
static struct dirent de;
|
||||||
static struct stat st;
|
|
||||||
single_readdir sr;
|
single_readdir sr;
|
||||||
sr.de = &de;
|
sr.de = &de;
|
||||||
sr.st = &st;
|
sr.stx = NULL;
|
||||||
sr.stmask = &stmask;
|
sr.inode = NULL;
|
||||||
sr.full = false;
|
sr.full = false;
|
||||||
|
|
||||||
// our callback fills the dirent and sets sr.full=true on first
|
// 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;
|
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;
|
single_readdir sr;
|
||||||
sr.de = de;
|
sr.de = de;
|
||||||
sr.st = st;
|
sr.stx = stx;
|
||||||
sr.stmask = stmask;
|
sr.inode = NULL;
|
||||||
sr.full = false;
|
sr.full = false;
|
||||||
|
|
||||||
// our callback fills the dirent and sets sr.full=true on first
|
// our callback fills the dirent and sets sr.full=true on first
|
||||||
// call, and returns -1 the second time around.
|
// 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)
|
if (r < -1)
|
||||||
return r;
|
return r;
|
||||||
|
if (out)
|
||||||
|
*out = sr.inode;
|
||||||
if (sr.full)
|
if (sr.full)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -7620,7 +7692,8 @@ struct getdents_result {
|
|||||||
bool fullent;
|
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);
|
struct getdents_result *c = static_cast<getdents_result *>(p);
|
||||||
|
|
||||||
@ -7672,7 +7745,7 @@ struct getdir_result {
|
|||||||
int num;
|
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);
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::ll_walk(const char* name, Inode **out, struct stat *attr,
|
int Client::ll_lookupx(Inode *parent, const char *name, Inode **out,
|
||||||
const UserPerm& perms)
|
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);
|
Mutex::Locker lock(client_lock);
|
||||||
filepath fp(name, 0);
|
filepath fp(name, 0);
|
||||||
InodeRef in;
|
InodeRef in;
|
||||||
int rc;
|
int rc;
|
||||||
|
unsigned mask = statx_to_mask(flags, want);
|
||||||
|
|
||||||
ldout(cct, 3) << "ll_walk" << name << dendl;
|
ldout(cct, 3) << "ll_walk" << name << dendl;
|
||||||
tout(cct) << "ll_walk" << std::endl;
|
tout(cct) << "ll_walk" << std::endl;
|
||||||
tout(cct) << name << 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) {
|
if (rc < 0) {
|
||||||
attr->st_ino = 0;
|
/* zero out mask, just in case... */
|
||||||
|
stx->stx_mask = 0;
|
||||||
|
stx->stx_ino = 0;
|
||||||
*out = NULL;
|
*out = NULL;
|
||||||
return rc;
|
return rc;
|
||||||
} else {
|
} else {
|
||||||
assert(in);
|
assert(in);
|
||||||
fill_stat(in, attr);
|
fill_statx(in, mask, stx);
|
||||||
*out = in.get();
|
*out = in.get();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::_ll_get(Inode *in)
|
void Client::_ll_get(Inode *in)
|
||||||
{
|
{
|
||||||
if (in->ll_ref == 0) {
|
if (in->ll_ref == 0) {
|
||||||
@ -10846,6 +10958,42 @@ int Client::ll_mknod(Inode *parent, const char *name, mode_t mode,
|
|||||||
return r;
|
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,
|
int Client::_create(Inode *dir, const char *name, int flags, mode_t mode,
|
||||||
InodeRef *inp, Fh **fhp, int stripe_unit, int stripe_count,
|
InodeRef *inp, Fh **fhp, int stripe_unit, int stripe_count,
|
||||||
int object_size, const char *data_pool, bool *created,
|
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;
|
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,
|
int Client::_symlink(Inode *dir, const char *name, const char *target,
|
||||||
const UserPerm& perms, InodeRef *inp)
|
const UserPerm& perms, InodeRef *inp)
|
||||||
{
|
{
|
||||||
@ -11106,6 +11290,40 @@ int Client::ll_symlink(Inode *parent, const char *name, const char *value,
|
|||||||
return r;
|
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)
|
int Client::_unlink(Inode *dir, const char *name, const UserPerm& perm)
|
||||||
{
|
{
|
||||||
ldout(cct, 3) << "_unlink(" << dir->ino << " " << name
|
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,
|
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);
|
Mutex::Locker lock(client_lock);
|
||||||
|
|
||||||
@ -11422,25 +11640,19 @@ int Client::ll_link(Inode *in, Inode *newparent, const char *newname,
|
|||||||
InodeRef target;
|
InodeRef target;
|
||||||
|
|
||||||
if (!cct->_conf->fuse_default_permissions) {
|
if (!cct->_conf->fuse_default_permissions) {
|
||||||
if (S_ISDIR(in->mode)) {
|
if (S_ISDIR(in->mode))
|
||||||
r = -EPERM;
|
return -EPERM;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
r = may_hardlink(in, perm);
|
r = may_hardlink(in, perm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
return r;
|
||||||
|
|
||||||
r = may_create(newparent, perm);
|
r = may_create(newparent, perm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = _link(in, newparent, newname, perm, &target);
|
return _link(in, newparent, newname, perm, &target);
|
||||||
if (r == 0) {
|
|
||||||
assert(target);
|
|
||||||
fill_stat(target, attr);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::ll_num_osds(void)
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
int Client::_ll_create(Inode *parent, const char *name, mode_t mode,
|
||||||
int flags, struct stat *attr, Inode **outp, Fh **fhp,
|
int flags, InodeRef *in, int caps, Fh **fhp,
|
||||||
const UserPerm& perms)
|
const UserPerm& perms)
|
||||||
{
|
{
|
||||||
*fhp = NULL;
|
*fhp = NULL;
|
||||||
|
|
||||||
Mutex::Locker lock(client_lock);
|
|
||||||
|
|
||||||
vinodeno_t vparent = _get_vino(parent);
|
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()
|
mode << dec << " " << flags << ", uid " << perms.uid()
|
||||||
<< ", gid " << perms.gid() << dendl;
|
<< ", gid " << perms.gid() << dendl;
|
||||||
tout(cct) << "ll_create" << std::endl;
|
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;
|
tout(cct) << flags << std::endl;
|
||||||
|
|
||||||
bool created = false;
|
bool created = false;
|
||||||
InodeRef in;
|
int r = _lookup(parent, name, caps, in, perms);
|
||||||
int r = _lookup(parent, name, CEPH_STAT_CAP_INODE_ALL, &in, perms);
|
|
||||||
|
|
||||||
if (r == 0 && (flags & O_CREAT) && (flags & O_EXCL))
|
if (r == 0 && (flags & O_CREAT) && (flags & O_EXCL))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
@ -11646,7 +11855,7 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
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);
|
perms);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@ -11655,13 +11864,12 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
assert(in);
|
assert(*in);
|
||||||
fill_stat(in, attr);
|
|
||||||
|
|
||||||
ldout(cct, 20) << "ll_create created = " << created << dendl;
|
ldout(cct, 20) << "_ll_create created = " << created << dendl;
|
||||||
if (!created) {
|
if (!created) {
|
||||||
if (!cct->_conf->fuse_default_permissions) {
|
if (!cct->_conf->fuse_default_permissions) {
|
||||||
r = may_open(in.get(), flags, perms);
|
r = may_open(in->get(), flags, perms);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (*fhp) {
|
if (*fhp) {
|
||||||
int release_r = _release_fh(*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) {
|
if (*fhp == NULL) {
|
||||||
r = _open(in.get(), flags, mode, fhp, perms);
|
r = _open(in->get(), flags, mode, fhp, perms);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (r < 0)
|
|
||||||
attr->st_ino = 0;
|
|
||||||
|
|
||||||
if (*fhp) {
|
if (*fhp) {
|
||||||
ll_unclosed_fh_set.insert(*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
|
ino_t ino = 0;
|
||||||
if (outp) {
|
if (r >= 0) {
|
||||||
if (in)
|
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());
|
_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;
|
return r;
|
||||||
|
@ -48,6 +48,7 @@ using std::fstream;
|
|||||||
|
|
||||||
#include "InodeRef.h"
|
#include "InodeRef.h"
|
||||||
#include "UserPerm.h"
|
#include "UserPerm.h"
|
||||||
|
#include "include/cephfs/ceph_statx.h"
|
||||||
|
|
||||||
class FSMap;
|
class FSMap;
|
||||||
class FSMapUser;
|
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);
|
void fill_dirent(struct dirent *de, const char *name, int type, uint64_t ino, loff_t next_off);
|
||||||
|
|
||||||
// some readdir helpers
|
// 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);
|
int _opendir(Inode *in, dir_result_t **dirpp, const UserPerm& perms);
|
||||||
void _readdir_drop_dirp_buffer(dir_result_t *dirp);
|
void _readdir_drop_dirp_buffer(dir_result_t *dirp);
|
||||||
@ -727,7 +728,7 @@ private:
|
|||||||
void _readdir_next_frag(dir_result_t *dirp);
|
void _readdir_next_frag(dir_result_t *dirp);
|
||||||
void _readdir_rechoose_frag(dir_result_t *dirp);
|
void _readdir_rechoose_frag(dir_result_t *dirp);
|
||||||
int _readdir_get_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);
|
void _closedir(dir_result_t *dirp);
|
||||||
|
|
||||||
// other helpers
|
// other helpers
|
||||||
@ -952,11 +953,13 @@ public:
|
|||||||
* Returns 0 if it reached the end of the directory.
|
* Returns 0 if it reached the end of the directory.
|
||||||
* If @a cb returns a negative error code, stop and return that.
|
* 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);
|
struct dirent * readdir(dir_result_t *d);
|
||||||
int readdir_r(dir_result_t *dirp, struct dirent *de);
|
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,
|
int getdir(const char *relpath, list<string>& names,
|
||||||
const UserPerm& perms); // get the whole dir at once.
|
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,
|
int setattrx(const char *relpath, struct ceph_statx *stx, int mask,
|
||||||
const UserPerm& perms, int flags=0);
|
const UserPerm& perms, int flags=0);
|
||||||
int fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms);
|
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 chmod(const char *path, mode_t mode, const UserPerm& perms);
|
||||||
int fchmod(int fd, 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);
|
int lchmod(const char *path, mode_t mode, const UserPerm& perms);
|
||||||
@ -1113,6 +1117,9 @@ public:
|
|||||||
Inode *ll_get_inode(vinodeno_t vino);
|
Inode *ll_get_inode(vinodeno_t vino);
|
||||||
int ll_lookup(Inode *parent, const char *name, struct stat *attr,
|
int ll_lookup(Inode *parent, const char *name, struct stat *attr,
|
||||||
Inode **out, const UserPerm& perms);
|
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_forget(Inode *in, int count);
|
||||||
bool ll_put(Inode *in);
|
bool ll_put(Inode *in);
|
||||||
int ll_getattr(Inode *in, struct stat *st, const UserPerm& perms);
|
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_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,
|
int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev,
|
||||||
struct stat *attr, Inode **out, const UserPerm& perms);
|
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,
|
int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr,
|
||||||
Inode **out, const UserPerm& perm);
|
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,
|
int ll_symlink(Inode *in, const char *name, const char *value,
|
||||||
struct stat *attr, Inode **out, const UserPerm& perms);
|
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_unlink(Inode *in, const char *name, const UserPerm& perm);
|
||||||
int ll_rmdir(Inode *in, const char *name, const UserPerm& perms);
|
int ll_rmdir(Inode *in, const char *name, const UserPerm& perms);
|
||||||
int ll_rename(Inode *parent, const char *name, Inode *newparent,
|
int ll_rename(Inode *parent, const char *name, Inode *newparent,
|
||||||
const char *newname, const UserPerm& perm);
|
const char *newname, const UserPerm& perm);
|
||||||
int ll_link(Inode *in, Inode *newparent, const char *newname,
|
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_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,
|
int ll_create(Inode *parent, const char *name, mode_t mode, int flags,
|
||||||
struct stat *attr, Inode **out, Fh **fhp,
|
struct stat *attr, Inode **out, Fh **fhp,
|
||||||
const UserPerm& perms);
|
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,
|
int ll_read_block(Inode *in, uint64_t blockid, char *buf, uint64_t offset,
|
||||||
uint64_t length, file_layout_t* layout);
|
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_commit_blocks(Inode *in, uint64_t offset, uint64_t length);
|
||||||
|
|
||||||
int ll_statfs(Inode *in, struct statvfs *stbuf, const UserPerm& perms);
|
int ll_statfs(Inode *in, struct statvfs *stbuf, const UserPerm& perms);
|
||||||
int ll_walk(const char* name, Inode **i, struct stat *attr,
|
int ll_walk(const char* name, Inode **i, struct ceph_statx *stx,
|
||||||
const UserPerm& perms); // XXX in?
|
unsigned int want, unsigned int flags, const UserPerm& perms);
|
||||||
uint32_t ll_stripe_unit(Inode *in);
|
uint32_t ll_stripe_unit(Inode *in);
|
||||||
int ll_file_layout(Inode *in, file_layout_t *layout);
|
int ll_file_layout(Inode *in, file_layout_t *layout);
|
||||||
uint64_t ll_snap_seq(Inode *in);
|
uint64_t ll_snap_seq(Inode *in);
|
||||||
|
@ -37,6 +37,7 @@ using namespace std;
|
|||||||
|
|
||||||
#include "common/errno.h"
|
#include "common/errno.h"
|
||||||
#include "include/assert.h"
|
#include "include/assert.h"
|
||||||
|
#include "include/cephfs/ceph_statx.h"
|
||||||
|
|
||||||
#define dout_subsys ceph_subsys_client
|
#define dout_subsys ceph_subsys_client
|
||||||
#undef dout_prefix
|
#undef dout_prefix
|
||||||
@ -1023,11 +1024,11 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only)
|
|||||||
const char *p = prefix.c_str();
|
const char *p = prefix.c_str();
|
||||||
if (prefix.length()) {
|
if (prefix.length()) {
|
||||||
client->mkdir(prefix.c_str(), 0755, perms);
|
client->mkdir(prefix.c_str(), 0755, perms);
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
i1 = client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP));
|
i1 = client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP));
|
||||||
if (client->ll_lookup(i1, prefix.c_str(), &attr, &i2, perms) == 0) {
|
if (client->ll_lookupx(i1, prefix.c_str(), &i2, &stx, CEPH_STATX_INO, 0, perms) == 0) {
|
||||||
ll_inos[1] = attr.st_ino;
|
ll_inos[1] = stx.stx_ino;
|
||||||
dout(5) << "'root' ino is " << inodeno_t(attr.st_ino) << dendl;
|
dout(5) << "'root' ino is " << inodeno_t(stx.stx_ino) << dendl;
|
||||||
client->ll_put(i1);
|
client->ll_put(i1);
|
||||||
} else {
|
} else {
|
||||||
dout(0) << "warning: play_trace couldn't lookup up my per-client directory" << dendl;
|
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();
|
int64_t i = t.get_int();
|
||||||
const char *name = t.get_string(buf, p);
|
const char *name = t.get_string(buf, p);
|
||||||
int64_t r = t.get_int();
|
int64_t r = t.get_int();
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
if (ll_inos.count(i)) {
|
if (ll_inos.count(i)) {
|
||||||
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
|
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
|
||||||
if (client->ll_lookup(i1, name, &attr, &i2, perms) == 0)
|
if (client->ll_lookupx(i1, name, &i2, &stx, CEPH_STATX_INO, 0, perms) == 0)
|
||||||
ll_inos[r] = attr.st_ino;
|
ll_inos[r] = stx.stx_ino;
|
||||||
client->ll_put(i1);
|
client->ll_put(i1);
|
||||||
}
|
}
|
||||||
} else if (strcmp(op, "ll_forget") == 0) {
|
} 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 i = t.get_int();
|
||||||
int64_t ni = t.get_int();
|
int64_t ni = t.get_int();
|
||||||
const char *nn = t.get_string(buf, p);
|
const char *nn = t.get_string(buf, p);
|
||||||
struct stat attr;
|
|
||||||
if (ll_inos.count(i) &&
|
if (ll_inos.count(i) &&
|
||||||
ll_inos.count(ni)) {
|
ll_inos.count(ni)) {
|
||||||
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
|
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
|
||||||
i2 = client->ll_get_inode(vinodeno_t(ll_inos[ni],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(i1);
|
||||||
client->ll_put(i2);
|
client->ll_put(i2);
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
UserPerm() : m_uid(-1), m_gid(-1), gid_count(0),
|
UserPerm() : m_uid(-1), m_gid(-1), gid_count(0),
|
||||||
gids(NULL), alloced_gids(false) {}
|
gids(NULL), alloced_gids(false) {}
|
||||||
UserPerm(int uid, int gid) : m_uid(uid), m_gid(gid), gid_count(0),
|
UserPerm(uid_t uid, gid_t gid, int ngids=0, gid_t *gidlist=NULL) :
|
||||||
gids(NULL), alloced_gids(false) {}
|
m_uid(uid), m_gid(gid), gid_count(ngids),
|
||||||
|
gids(gidlist), alloced_gids(false) {}
|
||||||
UserPerm(const UserPerm& o) : UserPerm() {
|
UserPerm(const UserPerm& o) : UserPerm() {
|
||||||
deep_copy_from(o);
|
deep_copy_from(o);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "ioctl.h"
|
#include "ioctl.h"
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "include/assert.h"
|
#include "include/assert.h"
|
||||||
|
#include "include/cephfs/ceph_statx.h"
|
||||||
|
|
||||||
#include "fuse_ll.h"
|
#include "fuse_ll.h"
|
||||||
#include <fuse.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);
|
UserPerm perm(ctx->uid, ctx->gid);
|
||||||
GET_GROUPS(perm, req);
|
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) {
|
if (r == 0) {
|
||||||
fe.ino = cfuse->make_fake_ino(fe.attr.st_ino, fe.attr.st_dev);
|
r = cfuse->client->ll_getattr(in, &fe.attr, perm);
|
||||||
fe.attr.st_rdev = new_encode_dev(fe.attr.st_rdev);
|
if (r == 0) {
|
||||||
fuse_reply_entry(req, &fe);
|
fe.ino = cfuse->make_fake_ino(fe.attr.st_ino, fe.attr.st_dev);
|
||||||
} else {
|
fe.attr.st_rdev = new_encode_dev(fe.attr.st_rdev);
|
||||||
fuse_reply_err(req, -r);
|
fuse_reply_entry(req, &fe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r != 0) {
|
||||||
/*
|
/*
|
||||||
* Many ll operations in libcephfs return an extra inode reference, but
|
* Many ll operations in libcephfs return an extra inode reference, but
|
||||||
* ll_link currently does not. Still, FUSE needs one for the new dentry,
|
* 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.
|
* On error however, we must put that reference.
|
||||||
*/
|
*/
|
||||||
cfuse->iput(in);
|
cfuse->iput(in);
|
||||||
|
fuse_reply_err(req, -r);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfuse->iput(nin);
|
cfuse->iput(nin);
|
||||||
@ -669,19 +679,21 @@ struct readdir_context {
|
|||||||
/*
|
/*
|
||||||
* return 0 on success, -1 if out of space
|
* return 0 on success, -1 if out of space
|
||||||
*/
|
*/
|
||||||
static int fuse_ll_add_dirent(void *p, struct dirent *de, struct stat *st,
|
static int fuse_ll_add_dirent(void *p, struct dirent *de,
|
||||||
int stmask, off_t next_off)
|
struct ceph_statx *stx, off_t next_off,
|
||||||
|
Inode *in)
|
||||||
{
|
{
|
||||||
struct readdir_context *c = (struct readdir_context *)p;
|
struct readdir_context *c = (struct readdir_context *)p;
|
||||||
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(c->req);
|
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(c->req);
|
||||||
|
|
||||||
st->st_ino = cfuse->make_fake_ino(de->d_ino, c->snap);
|
struct stat st;
|
||||||
st->st_mode = DTTOIF(de->d_type);
|
st.st_ino = cfuse->make_fake_ino(stx->stx_ino, c->snap);
|
||||||
st->st_rdev = new_encode_dev(st->st_rdev);
|
st.st_mode = stx->stx_mode;
|
||||||
|
st.st_rdev = new_encode_dev(stx->stx_rdev);
|
||||||
|
|
||||||
size_t room = c->size - c->pos;
|
size_t room = c->size - c->pos;
|
||||||
size_t entrysize = fuse_add_direntry(c->req, c->buf + c->pos, room,
|
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)
|
if (entrysize > room)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
|
@ -384,17 +384,17 @@ void CephBroker::rmdir(ResponseCallback *cb, const char *dname) {
|
|||||||
int CephBroker::rmdir_recursive(const char *directory) {
|
int CephBroker::rmdir_recursive(const char *directory) {
|
||||||
struct ceph_dir_result *dirp;
|
struct ceph_dir_result *dirp;
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
struct stat st;
|
struct ceph_statx stx;
|
||||||
int r;
|
int r;
|
||||||
if ((r = ceph_opendir(cmount, directory, &dirp)) < 0)
|
if ((r = ceph_opendir(cmount, directory, &dirp)) < 0)
|
||||||
return r; //failed to open
|
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;
|
String new_dir = de.d_name;
|
||||||
if(!(new_dir.compare(".")==0 || new_dir.compare("..")==0)) {
|
if(!(new_dir.compare(".")==0 || new_dir.compare("..")==0)) {
|
||||||
new_dir = directory;
|
new_dir = directory;
|
||||||
new_dir += '/';
|
new_dir += '/';
|
||||||
new_dir += de.d_name;
|
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;
|
if((r=rmdir_recursive(new_dir.c_str())) < 0) return r;
|
||||||
} else { //delete this file
|
} else { //delete this file
|
||||||
if((r=ceph_unlink(cmount, new_dir.c_str())) < 0) return r;
|
if((r=ceph_unlink(cmount, new_dir.c_str())) < 0) return r;
|
||||||
|
@ -97,6 +97,9 @@ typedef struct vinodeno_t vinodeno;
|
|||||||
|
|
||||||
#endif /* ! __cplusplus */
|
#endif /* ! __cplusplus */
|
||||||
|
|
||||||
|
struct UserPerm;
|
||||||
|
typedef struct UserPerm UserPerm;
|
||||||
|
|
||||||
struct Inode;
|
struct Inode;
|
||||||
typedef struct Inode Inode;
|
typedef struct Inode Inode;
|
||||||
|
|
||||||
@ -121,6 +124,34 @@ struct CephContext;
|
|||||||
# define CEPHFS_ERROR_NEW_CLIENT 1002
|
# define CEPHFS_ERROR_NEW_CLIENT 1002
|
||||||
# define CEPHFS_ERROR_MESSENGER_START 1003
|
# 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
|
* @defgroup libcephfs_h_init Setup and Teardown
|
||||||
* These are the first and last functions that should be called
|
* 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);
|
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.
|
* 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
|
* @param dirp the directory stream pointer from an opendir holding the state of the
|
||||||
* next entry to return.
|
* next entry to return.
|
||||||
* @param de the directory entry pointer filled in with the next directory entry of the dirp state.
|
* @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 stx 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 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,
|
* @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.
|
* and a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, struct dirent *de,
|
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.
|
* 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);
|
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.
|
* 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,
|
int ceph_statx(struct ceph_mount_info *cmount, const char *path, struct ceph_statx *stx,
|
||||||
unsigned int want, unsigned int flags);
|
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.
|
* 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 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 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);
|
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.
|
* 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,
|
int ceph_fallocate(struct ceph_mount_info *cmount, int fd, int mode,
|
||||||
int64_t offset, int64_t length);
|
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.
|
* 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,
|
int ceph_ll_lookup_root(struct ceph_mount_info *cmount,
|
||||||
Inode **parent);
|
Inode **parent);
|
||||||
int ceph_ll_lookup(struct ceph_mount_info *cmount, struct Inode *parent,
|
int ceph_ll_lookup(struct ceph_mount_info *cmount, Inode *parent,
|
||||||
const char *name, struct stat *attr,
|
const char *name, Inode **out, struct ceph_statx *stx,
|
||||||
Inode **out, int uid, int gid);
|
unsigned want, unsigned flags, const UserPerm *perms);
|
||||||
int ceph_ll_put(struct ceph_mount_info *cmount, struct Inode *in);
|
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 ceph_ll_forget(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
int count);
|
int count);
|
||||||
int ceph_ll_walk(struct ceph_mount_info *cmount, const char *name,
|
int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i,
|
||||||
struct Inode **i,
|
struct ceph_statx *stx, unsigned int want, unsigned int flags,
|
||||||
struct stat *attr);
|
const UserPerm *perms);
|
||||||
int ceph_ll_getattr(struct ceph_mount_info *cmount, struct Inode *in,
|
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,
|
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,
|
int ceph_ll_setattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
struct stat *st, int mask, int uid, int gid);
|
struct ceph_statx *stx, int mask, const UserPerm *perms);
|
||||||
int ceph_ll_setattrx(struct ceph_mount_info *cmount, struct Inode *in,
|
|
||||||
struct ceph_statx *stx, int mask, int uid, int gid);
|
|
||||||
int ceph_ll_open(struct ceph_mount_info *cmount, struct Inode *in, int flags,
|
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 ceph_ll_lseek(struct ceph_mount_info *cmount, struct Fh* filehandle,
|
||||||
off_t offset, int whence);
|
off_t offset, int whence);
|
||||||
int ceph_ll_read(struct ceph_mount_info *cmount, struct Fh* filehandle,
|
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 name name of attribute
|
||||||
* @param value pointer to begin buffer
|
* @param value pointer to begin buffer
|
||||||
* @param size buffer size
|
* @param size buffer size
|
||||||
* @param uid user ID
|
* @param perms pointer to UserPerms object
|
||||||
* @param gid group ID
|
|
||||||
* @returns size of returned buffer. Negative number in error case
|
* @returns size of returned buffer. Negative number in error case
|
||||||
*/
|
*/
|
||||||
int ceph_ll_getxattr(struct ceph_mount_info *cmount, struct Inode *in,
|
int ceph_ll_getxattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
const char *name, void *value, size_t size, int uid,
|
const char *name, void *value, size_t size,
|
||||||
int gid);
|
const UserPerm *perms);
|
||||||
int ceph_ll_setxattr(struct ceph_mount_info *cmount, struct Inode *in,
|
int ceph_ll_setxattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
const char *name, const void *value, size_t size,
|
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,
|
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,
|
int ceph_ll_removexattr(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
const char *name, int uid, int gid);
|
const char *name, const UserPerm *perms);
|
||||||
int ceph_ll_create(struct ceph_mount_info *cmount, struct Inode *parent,
|
int ceph_ll_create(struct ceph_mount_info *cmount, Inode *parent,
|
||||||
const char *name, mode_t mode, int flags,
|
const char *name, mode_t mode, int oflags, Inode **outp,
|
||||||
struct stat *attr, struct Inode **out, Fh **fhp,
|
Fh **fhp, struct ceph_statx *stx, unsigned want,
|
||||||
int uid, int gid);
|
unsigned lflags, const UserPerm *perms);
|
||||||
int ceph_ll_mknod(struct ceph_mount_info *cmount, struct Inode *parent,
|
int ceph_ll_mknod(struct ceph_mount_info *cmount, Inode *parent,
|
||||||
const char *name, mode_t mode, dev_t rdev,
|
const char *name, mode_t mode, dev_t rdev, Inode **out,
|
||||||
struct stat *attr, struct Inode **out,
|
struct ceph_statx *stx, unsigned want, unsigned flags,
|
||||||
int uid, int gid);
|
const UserPerm *perms);
|
||||||
int ceph_ll_mkdir(struct ceph_mount_info *cmount, struct Inode *parent,
|
int ceph_ll_mkdir(struct ceph_mount_info *cmount, Inode *parent,
|
||||||
const char *name, mode_t mode, struct stat *attr,
|
const char *name, mode_t mode, Inode **out,
|
||||||
Inode **out, int uid, int gid);
|
struct ceph_statx *stx, unsigned want,
|
||||||
|
unsigned flags, const UserPerm *perms);
|
||||||
int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in,
|
int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
struct Inode *newparrent, const char *name,
|
struct Inode *newparent, const char *name,
|
||||||
struct stat *attr, int uid, int gid);
|
const UserPerm *perms);
|
||||||
int ceph_ll_truncate(struct ceph_mount_info *cmount, struct Inode *in,
|
|
||||||
uint64_t length, int uid, int gid);
|
|
||||||
int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in,
|
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,
|
int ceph_ll_releasedir(struct ceph_mount_info *cmount,
|
||||||
struct ceph_dir_result* dir);
|
struct ceph_dir_result* dir);
|
||||||
int ceph_ll_rename(struct ceph_mount_info *cmount, struct Inode *parent,
|
int ceph_ll_rename(struct ceph_mount_info *cmount, struct Inode *parent,
|
||||||
const char *name, struct Inode *newparent,
|
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,
|
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,
|
int ceph_ll_statfs(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
struct statvfs *stbuf);
|
struct statvfs *stbuf);
|
||||||
int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in,
|
int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in,
|
||||||
char *buf, size_t bufsize, int uid, int gid);
|
char *buf, size_t bufsize, const UserPerm *perms);
|
||||||
int ceph_ll_symlink(struct ceph_mount_info *cmount, struct Inode *parent,
|
int ceph_ll_symlink(struct ceph_mount_info *cmount,
|
||||||
const char *name, const char *value, struct stat *attr,
|
Inode *in, const char *name, const char *value,
|
||||||
struct Inode **in, int uid, int gid);
|
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,
|
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,
|
uint32_t ceph_ll_stripe_unit(struct ceph_mount_info *cmount,
|
||||||
struct Inode *in);
|
struct Inode *in);
|
||||||
uint32_t ceph_ll_file_layout(struct ceph_mount_info *cmount,
|
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();
|
*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)
|
extern "C" const char *ceph_version(int *pmajor, int *pminor, int *ppatch)
|
||||||
{
|
{
|
||||||
int major, minor, patch;
|
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;
|
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,
|
extern "C" int ceph_statfs(struct ceph_mount_info *cmount, const char *path,
|
||||||
struct statvfs *stbuf)
|
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,
|
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())
|
if (!cmount->is_mounted())
|
||||||
return -ENOTCONN;
|
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,
|
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);
|
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,
|
extern "C" int ceph_statx(struct ceph_mount_info *cmount, const char *path,
|
||||||
struct ceph_statx *stx, unsigned int want, unsigned int flags)
|
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);
|
want, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_lstat(struct ceph_mount_info *cmount, const char *path,
|
extern "C" int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd,
|
||||||
struct stat *stbuf)
|
struct ceph_statx *stx, int mask)
|
||||||
{
|
{
|
||||||
if (!cmount->is_mounted())
|
if (!cmount->is_mounted())
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
return cmount->get_client()->lstat(path, stbuf, cmount->default_perms);
|
return cmount->get_client()->fsetattrx(fd, stx, mask, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath,
|
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);
|
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,
|
extern "C" int ceph_fstatx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx,
|
||||||
unsigned int want, unsigned int flags)
|
unsigned int want, unsigned int flags)
|
||||||
{
|
{
|
||||||
@ -1418,13 +1403,13 @@ extern "C" int ceph_ll_lookup_inode(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_lookup(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_lookup(struct ceph_mount_info *cmount,
|
||||||
struct Inode *parent, const char *name,
|
Inode *parent, const char *name, Inode **out,
|
||||||
struct stat *attr, Inode **out,
|
struct ceph_statx *stx, unsigned want,
|
||||||
int uid, int gid)
|
unsigned flags, const UserPerm *perms)
|
||||||
{
|
{
|
||||||
UserPerm perms(uid, gid);
|
return (cmount->get_client())->ll_lookupx(parent, name, out, stx, want,
|
||||||
return (cmount->get_client())->ll_lookup(parent, name, attr, out, perms);
|
flags, *perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_put(class ceph_mount_info *cmount, Inode *in)
|
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));
|
return (cmount->get_client()->ll_forget(in, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_walk(class ceph_mount_info *cmount, const char *name,
|
int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i,
|
||||||
struct Inode **i,
|
struct ceph_statx *stx, unsigned int want, unsigned int flags,
|
||||||
struct stat *attr)
|
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,
|
extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount,
|
||||||
Inode *in, struct stat *attr,
|
Inode *in, struct ceph_statx *stx,
|
||||||
int uid, int gid)
|
unsigned int want, unsigned int flags,
|
||||||
|
const UserPerm *perms)
|
||||||
{
|
{
|
||||||
UserPerm perms(uid, gid);
|
return (cmount->get_client()->ll_getattrx(in, stx, want, flags, *perms));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount,
|
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,
|
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,
|
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,
|
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,
|
extern "C" int ceph_ll_create(class ceph_mount_info *cmount,
|
||||||
struct Inode *parent, const char *name,
|
Inode *parent, const char *name, mode_t mode,
|
||||||
mode_t mode, int flags, struct stat *attr,
|
int oflags, Inode **outp, Fh **fhp,
|
||||||
struct Inode **out, Fh **fhp, int uid, int gid)
|
struct ceph_statx *stx, unsigned want,
|
||||||
|
unsigned lflags, const UserPerm *perms)
|
||||||
{
|
{
|
||||||
UserPerm perms(uid, gid);
|
return (cmount->get_client())->ll_createx(parent, name, mode, oflags, outp,
|
||||||
return (cmount->get_client())->ll_create(parent, name, mode, flags,
|
fhp, stx, want, lflags, *perms);
|
||||||
attr, out, fhp, perms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, Inode *parent,
|
||||||
struct Inode *parent, const char *name,
|
const char *name, mode_t mode, dev_t rdev,
|
||||||
mode_t mode, dev_t rdev, struct stat *attr,
|
Inode **out, struct ceph_statx *stx,
|
||||||
struct Inode **out, int uid, int gid)
|
unsigned want, unsigned flags,
|
||||||
|
const UserPerm *perms)
|
||||||
{
|
{
|
||||||
UserPerm perms(uid, gid);
|
return (cmount->get_client())->ll_mknodx(parent, name, mode, rdev,
|
||||||
return (cmount->get_client())->ll_mknod(parent, name, mode, rdev,
|
out, stx, want, flags, *perms);
|
||||||
attr, out, perms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, Inode *parent,
|
||||||
Inode *parent, const char *name,
|
const char *name, mode_t mode, Inode **out,
|
||||||
mode_t mode, struct stat *attr, Inode **out,
|
struct ceph_statx *stx, unsigned want,
|
||||||
int uid, int gid)
|
unsigned flags, const UserPerm *perms)
|
||||||
{
|
{
|
||||||
UserPerm perms(uid, gid);
|
return cmount->get_client()->ll_mkdirx(parent, name, mode, out, stx, want,
|
||||||
return (cmount->get_client()->ll_mkdir(parent, name, mode, attr, out, perms));
|
flags, *perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_link(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_link(class ceph_mount_info *cmount,
|
||||||
Inode *in, Inode *newparent,
|
Inode *in, Inode *newparent,
|
||||||
const char *name, struct stat *attr, int uid,
|
const char *name, const UserPerm *perms)
|
||||||
int gid)
|
|
||||||
{
|
{
|
||||||
UserPerm perms(uid, gid);
|
return cmount->get_client()->ll_link(in, newparent, name, *perms);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount,
|
||||||
Inode *in,
|
Inode *in,
|
||||||
struct ceph_dir_result **dirpp,
|
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,
|
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,
|
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,
|
extern "C" int ceph_ll_rename(class ceph_mount_info *cmount,
|
||||||
Inode *parent, const char *name,
|
Inode *parent, const char *name,
|
||||||
Inode *newparent, const char *newname,
|
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,
|
||||||
return (cmount->get_client()->ll_rename(parent, name,
|
newname, *perms);
|
||||||
newparent, newname, perms));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount, Inode *in,
|
||||||
Inode *in, const char *name,
|
const char *name, const UserPerm *perms)
|
||||||
int uid, int gid)
|
|
||||||
{
|
{
|
||||||
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,
|
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));
|
return (cmount->get_client()->ll_statfs(in, stbuf, cmount->default_perms));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount, Inode *in,
|
||||||
Inode *in, char *buf, size_t bufsiz, int uid,
|
char *buf, size_t bufsiz,
|
||||||
int gid)
|
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,
|
extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount,
|
||||||
Inode *in, const char *name,
|
Inode *in, const char *name,
|
||||||
const char *value, struct stat *attr,
|
const char *value, Inode **out,
|
||||||
Inode **out, int uid, int gid)
|
struct ceph_statx *stx, unsigned want,
|
||||||
|
unsigned flags, const UserPerm *perms)
|
||||||
{
|
{
|
||||||
UserPerm perms(uid, gid);
|
return (cmount->get_client()->ll_symlinkx(in, name, value, out, stx, want,
|
||||||
return (cmount->get_client()->ll_symlink(in, name, value, attr, out, perms));
|
flags, *perms));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount,
|
extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount,
|
||||||
Inode *in, const char *name,
|
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,
|
extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount,
|
||||||
Inode *in, const char *name, void *value,
|
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,
|
extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount,
|
||||||
Inode *in, char *list,
|
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) {
|
if (res >= 0) {
|
||||||
*list_size = (size_t)res;
|
*list_size = (size_t)res;
|
||||||
return 0;
|
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,
|
extern "C" int ceph_ll_setxattr(class ceph_mount_info *cmount,
|
||||||
Inode *in, const char *name,
|
Inode *in, const char *name,
|
||||||
const void *value, size_t size,
|
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,
|
extern "C" int ceph_ll_removexattr(class ceph_mount_info *cmount,
|
||||||
Inode *in, const char *name,
|
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,
|
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());
|
sprintf(c_file, "recordlock_test_%d", getpid());
|
||||||
Fh *fh = NULL;
|
Fh *fh = NULL;
|
||||||
Inode *root = NULL, *inode = NULL;
|
Inode *root = NULL, *inode = NULL;
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
int rc;
|
int rc;
|
||||||
struct flock lock1, lock2;
|
struct flock lock1, lock2;
|
||||||
|
UserPerm *perms = ceph_mount_perms(cmount);
|
||||||
|
|
||||||
// Get the root inode
|
// Get the root inode
|
||||||
rc = ceph_ll_lookup_root(cmount, &root);
|
rc = ceph_ll_lookup_root(cmount, &root);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Get the inode and Fh corresponding to c_file
|
// Get the inode and Fh corresponding to c_file
|
||||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||||
&inode, &fh, 0, 0);
|
&inode, &fh, &stx, 0, 0, perms);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// write lock twice
|
// write lock twice
|
||||||
@ -228,7 +229,7 @@ TEST(LibCephFS, BasicRecordLocking) {
|
|||||||
ASSERT_EQ(lock2.l_pid, getpid());
|
ASSERT_EQ(lock2.l_pid, getpid());
|
||||||
|
|
||||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
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();
|
CLEANUP_CEPH();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +283,7 @@ static void thread_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
|||||||
struct ceph_mount_info *const cmount = s.cmount;
|
struct ceph_mount_info *const cmount = s.cmount;
|
||||||
Fh *fh = NULL;
|
Fh *fh = NULL;
|
||||||
Inode *root = NULL, *inode = NULL;
|
Inode *root = NULL, *inode = NULL;
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
struct flock lock1;
|
struct flock lock1;
|
||||||
int rc;
|
int rc;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
@ -292,8 +293,8 @@ static void thread_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
|||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Get the inode and Fh corresponding to c_file
|
// Get the inode and Fh corresponding to c_file
|
||||||
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, &attr,
|
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT,
|
||||||
&inode, &fh, 0, 0);
|
&inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount));
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
lock1.l_type = F_WRLCK;
|
lock1.l_type = F_WRLCK;
|
||||||
@ -373,17 +374,18 @@ TEST(LibCephFS, ConcurrentRecordLocking) {
|
|||||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||||
Fh *fh = NULL;
|
Fh *fh = NULL;
|
||||||
Inode *root = NULL, *inode = NULL;
|
Inode *root = NULL, *inode = NULL;
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
struct flock lock1;
|
struct flock lock1;
|
||||||
int rc;
|
int rc;
|
||||||
|
UserPerm *perms = ceph_mount_perms(cmount);
|
||||||
|
|
||||||
// Get the root inode
|
// Get the root inode
|
||||||
rc = ceph_ll_lookup_root(cmount, &root);
|
rc = ceph_ll_lookup_root(cmount, &root);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Get the inode and Fh corresponding to c_file
|
// Get the inode and Fh corresponding to c_file
|
||||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||||
&inode, &fh, 0, 0);
|
&inode, &fh, &stx, 0, 0, perms);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
@ -502,7 +504,7 @@ TEST(LibCephFS, ConcurrentRecordLocking) {
|
|||||||
ASSERT_EQ(NULL, retval);
|
ASSERT_EQ(NULL, retval);
|
||||||
s.sem_destroy();
|
s.sem_destroy();
|
||||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
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();
|
CLEANUP_CEPH();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,17 +517,18 @@ TEST(LibCephFS, ThreesomeRecordLocking) {
|
|||||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||||
Fh *fh = NULL;
|
Fh *fh = NULL;
|
||||||
Inode *root = NULL, *inode = NULL;
|
Inode *root = NULL, *inode = NULL;
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
struct flock lock1;
|
struct flock lock1;
|
||||||
int rc;
|
int rc;
|
||||||
|
UserPerm *perms = ceph_mount_perms(cmount);
|
||||||
|
|
||||||
// Get the root inode
|
// Get the root inode
|
||||||
rc = ceph_ll_lookup_root(cmount, &root);
|
rc = ceph_ll_lookup_root(cmount, &root);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Get the inode and Fh corresponding to c_file
|
// Get the inode and Fh corresponding to c_file
|
||||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||||
&inode, &fh, 0, 0);
|
&inode, &fh, &stx, 0, 0, perms);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
@ -648,7 +651,7 @@ TEST(LibCephFS, ThreesomeRecordLocking) {
|
|||||||
ASSERT_EQ(NULL, retval);
|
ASSERT_EQ(NULL, retval);
|
||||||
s.sem_destroy();
|
s.sem_destroy();
|
||||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
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();
|
CLEANUP_CEPH();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,7 +670,7 @@ static void process_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
|||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
Fh *fh = NULL;
|
Fh *fh = NULL;
|
||||||
Inode *root = NULL, *inode = NULL;
|
Inode *root = NULL, *inode = NULL;
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
int rc;
|
int rc;
|
||||||
struct flock lock1;
|
struct flock lock1;
|
||||||
|
|
||||||
@ -679,8 +682,8 @@ static void process_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) {
|
|||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Get the inode and Fh corresponding to c_file
|
// Get the inode and Fh corresponding to c_file
|
||||||
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, &attr,
|
rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT,
|
||||||
&inode, &fh, 0, 0);
|
&inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount));
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
WAIT_MAIN(1); // (R1)
|
WAIT_MAIN(1); // (R1)
|
||||||
@ -758,7 +761,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) {
|
|||||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||||
Fh *fh = NULL;
|
Fh *fh = NULL;
|
||||||
Inode *root = NULL, *inode = NULL;
|
Inode *root = NULL, *inode = NULL;
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
struct flock lock1;
|
struct flock lock1;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -782,14 +785,15 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) {
|
|||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
struct ceph_mount_info *cmount;
|
struct ceph_mount_info *cmount;
|
||||||
STARTUP_CEPH();
|
STARTUP_CEPH();
|
||||||
|
UserPerm *perms = ceph_mount_perms(cmount);
|
||||||
|
|
||||||
// Get the root inode
|
// Get the root inode
|
||||||
rc = ceph_ll_lookup_root(cmount, &root);
|
rc = ceph_ll_lookup_root(cmount, &root);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Get the inode and Fh corresponding to c_file
|
// Get the inode and Fh corresponding to c_file
|
||||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT,
|
||||||
&inode, &fh, 0, 0);
|
&inode, &fh, &stx, 0, 0, perms);
|
||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
@ -906,7 +910,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) {
|
|||||||
s.sem_destroy();
|
s.sem_destroy();
|
||||||
ASSERT_EQ(0, munmap(shs, sizeof(*shs)));
|
ASSERT_EQ(0, munmap(shs, sizeof(*shs)));
|
||||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
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();
|
CLEANUP_CEPH();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,7 +923,7 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) {
|
|||||||
sprintf(c_file, "recordlock_test_%d", mypid);
|
sprintf(c_file, "recordlock_test_%d", mypid);
|
||||||
Fh *fh = NULL;
|
Fh *fh = NULL;
|
||||||
Inode *root = NULL, *inode = NULL;
|
Inode *root = NULL, *inode = NULL;
|
||||||
struct stat attr;
|
struct ceph_statx stx;
|
||||||
struct flock lock1;
|
struct flock lock1;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -956,8 +960,9 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) {
|
|||||||
ASSERT_EQ(rc, 0);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Get the inode and Fh corresponding to c_file
|
// Get the inode and Fh corresponding to c_file
|
||||||
rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr,
|
UserPerm *perms = ceph_mount_perms(cmount);
|
||||||
&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);
|
ASSERT_EQ(rc, 0);
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
@ -1077,6 +1082,6 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) {
|
|||||||
s.sem_destroy();
|
s.sem_destroy();
|
||||||
ASSERT_EQ(0, munmap(shs, sizeof(*shs)));
|
ASSERT_EQ(0, munmap(shs, sizeof(*shs)));
|
||||||
ASSERT_EQ(0, ceph_ll_close(cmount, fh));
|
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();
|
CLEANUP_CEPH();
|
||||||
}
|
}
|
||||||
|
@ -424,9 +424,9 @@ TEST(LibCephFS, DirLs) {
|
|||||||
found.clear();
|
found.clear();
|
||||||
while (true) {
|
while (true) {
|
||||||
struct dirent rdent;
|
struct dirent rdent;
|
||||||
struct stat st;
|
struct ceph_statx stx;
|
||||||
int stmask;
|
int len = ceph_readdirplus_r(cmount, ls_dir, &rdent, &stx,
|
||||||
int len = ceph_readdirplus_r(cmount, ls_dir, &rdent, &st, &stmask);
|
CEPH_STATX_SIZE, AT_NO_ATTR_SYNC, NULL);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
break;
|
break;
|
||||||
ASSERT_EQ(len, 1);
|
ASSERT_EQ(len, 1);
|
||||||
@ -434,8 +434,9 @@ TEST(LibCephFS, DirLs) {
|
|||||||
found.push_back(name);
|
found.push_back(name);
|
||||||
int size;
|
int size;
|
||||||
sscanf(name, "dirf%d", &size);
|
sscanf(name, "dirf%d", &size);
|
||||||
ASSERT_EQ(st.st_size, size);
|
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_SIZE);
|
||||||
ASSERT_EQ(st.st_ino, rdent.d_ino);
|
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(st.st_mode, (mode_t)0666);
|
||||||
}
|
}
|
||||||
ASSERT_EQ(found, entries);
|
ASSERT_EQ(found, entries);
|
||||||
@ -568,21 +569,25 @@ TEST(LibCephFS, Xattrs_ll) {
|
|||||||
|
|
||||||
Inode *root = NULL;
|
Inode *root = NULL;
|
||||||
Inode *existent_file_handle = NULL;
|
Inode *existent_file_handle = NULL;
|
||||||
struct stat attr;
|
|
||||||
|
|
||||||
int res = ceph_ll_lookup_root(cmount, &root);
|
int res = ceph_ll_lookup_root(cmount, &root);
|
||||||
ASSERT_EQ(res, 0);
|
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);
|
ASSERT_EQ(res, 0);
|
||||||
|
|
||||||
const char *valid_name = "user.attrname";
|
const char *valid_name = "user.attrname";
|
||||||
const char *value = "attrvalue";
|
const char *value = "attrvalue";
|
||||||
char value_buf[256] = { 0 };
|
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);
|
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));
|
ASSERT_EQ(res, (int)strlen(value));
|
||||||
|
|
||||||
value_buf[res] = '\0';
|
value_buf[res] = '\0';
|
||||||
@ -1132,10 +1137,8 @@ TEST(LibCephFS, UseUnmounted) {
|
|||||||
struct dirent rdent;
|
struct dirent rdent;
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_readdir_r(cmount, dirp, &rdent));
|
EXPECT_EQ(-ENOTCONN, ceph_readdir_r(cmount, dirp, &rdent));
|
||||||
|
|
||||||
int stmask;
|
|
||||||
struct ceph_statx stx;
|
struct ceph_statx stx;
|
||||||
struct stat st;
|
EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &stx, 0, 0, NULL));
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &st, &stmask));
|
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_getdents(cmount, dirp, NULL, 0));
|
EXPECT_EQ(-ENOTCONN, ceph_getdents(cmount, dirp, NULL, 0));
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_getdnames(cmount, dirp, NULL, 0));
|
EXPECT_EQ(-ENOTCONN, ceph_getdnames(cmount, dirp, NULL, 0));
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_telldir(cmount, dirp));
|
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_lremovexattr(cmount, "/path", "name"));
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_setxattr(cmount, "/path", "name", NULL, 0, 0));
|
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_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_chmod(cmount, "/path", 0));
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_fchmod(cmount, 0, 0));
|
EXPECT_EQ(-ENOTCONN, ceph_fchmod(cmount, 0, 0));
|
||||||
EXPECT_EQ(-ENOTCONN, ceph_chown(cmount, "/path", 0, 0));
|
EXPECT_EQ(-ENOTCONN, ceph_chown(cmount, "/path", 0, 0));
|
||||||
@ -1392,20 +1395,23 @@ TEST(LibCephFS, Nlink) {
|
|||||||
sprintf(filename, "nlinkorig%x", getpid());
|
sprintf(filename, "nlinkorig%x", getpid());
|
||||||
sprintf(linkname, "nlinklink%x", getpid());
|
sprintf(linkname, "nlinklink%x", getpid());
|
||||||
|
|
||||||
struct stat st;
|
struct ceph_statx stx;
|
||||||
Fh *fh;
|
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,
|
ASSERT_EQ(ceph_ll_create(cmount, dir, filename, 0666, O_RDWR|O_CREAT|O_EXCL,
|
||||||
&st, &file, &fh, getuid(), getgid()), 0);
|
&file, &fh, &stx, CEPH_STATX_NLINK, 0, perms), 0);
|
||||||
ASSERT_EQ(st.st_nlink, (nlink_t)1);
|
ASSERT_EQ(stx.stx_nlink, (nlink_t)1);
|
||||||
|
|
||||||
ASSERT_EQ(ceph_ll_link(cmount, file, dir, linkname, &st, getuid(), getgid()), 0);
|
ASSERT_EQ(ceph_ll_link(cmount, file, dir, linkname, perms), 0);
|
||||||
ASSERT_EQ(st.st_nlink, (nlink_t)2);
|
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_unlink(cmount, dir, linkname, perms), 0);
|
||||||
ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &st, &file, getuid(), getgid()), 0);
|
ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &file, &stx,
|
||||||
ASSERT_EQ(st.st_nlink, (nlink_t)1);
|
CEPH_STATX_NLINK, 0, perms), 0);
|
||||||
|
ASSERT_EQ(stx.stx_nlink, (nlink_t)1);
|
||||||
|
|
||||||
ceph_shutdown(cmount);
|
ceph_shutdown(cmount);
|
||||||
}
|
}
|
||||||
@ -1558,30 +1564,31 @@ TEST(LibCephFS, LazyStatx) {
|
|||||||
sprintf(filename, "lazystatx%x", getpid());
|
sprintf(filename, "lazystatx%x", getpid());
|
||||||
|
|
||||||
Inode *root1, *file1, *root2, *file2;
|
Inode *root1, *file1, *root2, *file2;
|
||||||
struct stat st;
|
struct ceph_statx stx;
|
||||||
Fh *fh;
|
Fh *fh;
|
||||||
|
UserPerm *perms1 = ceph_mount_perms(cmount1);
|
||||||
|
UserPerm *perms2 = ceph_mount_perms(cmount2);
|
||||||
|
|
||||||
ASSERT_EQ(ceph_ll_lookup_root(cmount1, &root1), 0);
|
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,
|
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_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
|
* 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
|
* different ctime with a statx that uses AT_NO_ATTR_SYNC
|
||||||
*/
|
*/
|
||||||
sleep(1);
|
sleep(1);
|
||||||
st.st_mode = 0644;
|
stx.stx_mode = 0644;
|
||||||
ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &st, CEPH_SETATTR_MODE, getuid(), getgid()), 0);
|
ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &stx, CEPH_SETATTR_MODE, perms1), 0);
|
||||||
|
|
||||||
struct ceph_statx stx;
|
ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, perms2), 0);
|
||||||
ASSERT_EQ(ceph_ll_getattrx(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, getuid(), getgid()), 0);
|
|
||||||
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME);
|
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME);
|
||||||
ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec &&
|
ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec &&
|
||||||
stx.stx_ctime.tv_nsec == old_ctime.tv_nsec);
|
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);
|
int fd = ceph_open(cmount, filename, O_RDWR|O_CREAT|O_EXCL, 0666);
|
||||||
ASSERT_LT(0, fd);
|
ASSERT_LT(0, fd);
|
||||||
|
|
||||||
struct stat st;
|
struct ceph_statx stx;
|
||||||
uint64_t size = 8388608;
|
uint64_t size = 8388608;
|
||||||
st.st_size = (off_t)size;
|
stx.stx_size = (off_t)size;
|
||||||
ASSERT_EQ(ceph_fsetattr(cmount, fd, &st, CEPH_SETATTR_SIZE), 0);
|
ASSERT_EQ(ceph_fsetattrx(cmount, fd, &stx, CEPH_SETATTR_SIZE), 0);
|
||||||
|
ASSERT_EQ(ceph_fstatx(cmount, fd, &stx, CEPH_STATX_SIZE, 0), 0);
|
||||||
struct stat stbuf;
|
ASSERT_EQ(stx.stx_size, (off_t)size);
|
||||||
ASSERT_EQ(ceph_fstat(cmount, fd, &stbuf), 0);
|
|
||||||
ASSERT_EQ(stbuf.st_size, (off_t)size);
|
|
||||||
|
|
||||||
ceph_close(cmount, fd);
|
ceph_close(cmount, fd);
|
||||||
ceph_shutdown(cmount);
|
ceph_shutdown(cmount);
|
||||||
|
@ -69,9 +69,10 @@ void PgFiles::hit_dir(std::string const &path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct ceph_statx stx;
|
||||||
std::string de_path = (path + std::string("/") + de.d_name);
|
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) {
|
if (r != 0) {
|
||||||
derr << "Failed to stat path " << de_path << ": "
|
derr << "Failed to stat path " << de_path << ": "
|
||||||
<< cpp_strerror(r) << dendl;
|
<< cpp_strerror(r) << dendl;
|
||||||
@ -79,9 +80,9 @@ void PgFiles::hit_dir(std::string const &path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISREG(st.st_mode)) {
|
if (S_ISREG(stx.stx_mode)) {
|
||||||
hit_file(de_path, st);
|
hit_file(de_path, stx);
|
||||||
} else if (S_ISDIR(st.st_mode)) {
|
} else if (S_ISDIR(stx.stx_mode)) {
|
||||||
hit_dir(de_path);
|
hit_dir(de_path);
|
||||||
} else {
|
} else {
|
||||||
dout(20) << "Skipping non reg/dir file: " << de_path << dendl;
|
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;
|
dout(20) << "Hitting file '" << path << "'" << dendl;
|
||||||
|
|
||||||
@ -127,11 +128,11 @@ void PgFiles::hit_file(std::string const &path, struct stat const &st)
|
|||||||
return;
|
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) {
|
for (uint64_t i = 0; i < num_objects; ++i) {
|
||||||
char buf[32];
|
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);
|
(long long unsigned int)i);
|
||||||
dout(20) << " object " << std::string(buf) << dendl;
|
dout(20) << " object " << std::string(buf) << dendl;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ private:
|
|||||||
std::set<pg_t> pgs;
|
std::set<pg_t> pgs;
|
||||||
std::set<uint64_t> pools;
|
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);
|
void hit_dir(std::string const &path);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user