From ccb64cde7fd890a5143a44c9abe9262e2cb8b201 Mon Sep 17 00:00:00 2001 From: Emoly Liu Date: Sun, 25 Apr 2021 08:48:42 +0800 Subject: [PATCH] LU-14612 utils: Add functions llapi_group_lock64/unlock64() Add new functions llapi_group_lock64/unlock64() for 64-bit usage. Test-Parameters: trivial Signed-off-by: Emoly Liu Change-Id: Id79ae634ba6a787974be481b51743604c4adb536 Reviewed-on: https://review.whamcloud.com/43310 Tested-by: jenkins Reviewed-by: Bobi Jam Reviewed-by: Wang Shilong Tested-by: Maloo Reviewed-by: Andreas Dilger --- lustre/doc/llapi_group_lock.3 | 27 ++- lustre/include/lustre/lustreapi.h | 12 ++ lustre/utils/LCOPYING | 1 + lustre/utils/Makefile.am | 2 +- lustre/utils/liblustreapi.c | 331 ------------------------------- lustre/utils/liblustreapi_swap.c | 399 ++++++++++++++++++++++++++++++++++++++ lustre/utils/wirehdr.c | 11 -- lustre/utils/wiretest.c | 12 +- 8 files changed, 432 insertions(+), 363 deletions(-) create mode 100644 lustre/utils/liblustreapi_swap.c diff --git a/lustre/doc/llapi_group_lock.3 b/lustre/doc/llapi_group_lock.3 index 18b529c..6a48384 100644 --- a/lustre/doc/llapi_group_lock.3 +++ b/lustre/doc/llapi_group_lock.3 @@ -1,37 +1,46 @@ .TH llapi_group_lock 3 "2014 Oct 03" "Lustre User API" .SH NAME -llapi_group_lock, llapi_group_unlock \- get and put a Lustre group lock. +llapi_group_lock, llapi_group_unlock, llapi_group_lock64, llapi_group_unlock64 \- get and put a Lustre group lock. .SH SYNOPSIS .nf .B #include .PP .BI "int llapi_group_lock(int "fd ", int "gid ); +.BI "int llapi_group_lock64(int "fd ", __u64 "gid ); .BI "int llapi_group_unlock(int "fd ", int "gid ); +.BI "int llapi_group_unlock64(int "fd ", __u64 "gid ); .fi .SH DESCRIPTION .PP -The function +The functions .BR llapi_group_lock() -takes a group lock on the file descriptor +and +.BR llapi_group_lock64() +take a group lock on the file descriptor .I fd with group identifier -.IR gid . +.IR gid +(int or __u64 type) . -The function +The functions .BR llapi_group_unlock() -releases a group lock identified by group identifier +and +.BR llapi_group_unlock64() +release a group lock identified by group identifier .I gid -on the file descriptor +(int or __u64 type) on the file descriptor .IR fd . The group lock is a whole file lock that blocks concurrent I/O originating from descriptors that have not been locked. Multiple processes can acquire a lock by specifying the same group identifier. .SH RETURN VALUES .LP -.B llapi_group_lock(\|) -and +.B llapi_group_lock(\|), +.B llapi_group_lock64(\|), .B llapi_group_unlock(\|) +and +.B llapi_group_unlock64(\|) return 0 on success or a negative errno value on failure. .SH ERRORS .TP 15 diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 78a2e44..8beeefc 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -65,6 +65,16 @@ typedef struct statx lstatx_t; #define lustre_fid struct lu_fid +/* + * BUILD_BUG_ON() is Compile-time check which verifies correctness at + * compile-time rather than runtime. If "cond" is true, (1 - 2*!!(cond)) + * will be a negative value, which will cause the compiler to complain. + * + */ +#ifndef BUILD_BUG_ON +#define BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2*!!(cond)])) +#endif + /* Currently external applications can access this but in the * future this will no longer be exposed for the user. Instead * if you want to know if the library is initialized just call @@ -609,6 +619,8 @@ int llapi_lease_put(int fd); /* obsoleted */ /* Group lock */ int llapi_group_lock(int fd, int gid); int llapi_group_unlock(int fd, int gid); +int llapi_group_lock64(int fd, __u64 gid); +int llapi_group_unlock64(int fd, __u64 gid); bool llapi_file_is_sparse(int fd); off_t llapi_data_seek(int src_fd, off_t offset, size_t *length); diff --git a/lustre/utils/LCOPYING b/lustre/utils/LCOPYING index 105f1fd..6e12b62 100644 --- a/lustre/utils/LCOPYING +++ b/lustre/utils/LCOPYING @@ -6,6 +6,7 @@ lustre/utils/liblustreapi_layout.c lustre/utils/liblustreapi_lease.c lustre/utils/liblustreapi_nodemap.c lustre/utils/liblustreapi_util.c +lustre/utils/liblustreapi_swap.c lustre/utils/lustreapi_internal.h ------------------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index 898a36f..a806331 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -104,7 +104,7 @@ liblustreapi_la_SOURCES = liblustreapi.c liblustreapi_hsm.c \ liblustreapi_mirror.c liblustreapi_fid.c \ liblustreapi_ladvise.c liblustreapi_chlg.c \ liblustreapi_heat.c liblustreapi_pcc.c \ - liblustreapi_lseek.c + liblustreapi_lseek.c liblustreapi_swap.c liblustreapi_la_LDFLAGS = $(LIBREADLINE) -version-info 1:0:0 \ -Wl,--version-script=liblustreapi.map liblustreapi_la_LIBADD = $(top_builddir)/libcfs/libcfs/libcfs.la diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 40a6ee7..8ffd467 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -5824,39 +5824,6 @@ int llapi_get_connect_flags(const char *mnt, __u64 *flags) } /** - * Get a 64-bit value representing the version of file data pointed by fd. - * - * Each write or truncate, flushed on OST, will change this value. You can use - * this value to verify if file data was modified. This only checks the file - * data, not metadata. - * - * \param flags 0: no flush pages, usually used it the process has already - * taken locks; - * LL_DV_RD_FLUSH: OSTs will take LCK_PR to flush dirty pages - * from clients; - * LL_DV_WR_FLUSH: OSTs will take LCK_PW to flush all caching - * pages from clients. - * - * \retval 0 on success. - * \retval -errno on error. - */ -int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags) -{ - int rc; - struct ioc_data_version idv; - - idv.idv_flags = (__u32)flags; - - rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv); - if (rc) - rc = -errno; - else - *data_version = idv.idv_version; - - return rc; -} - -/** * Flush cached pages from all clients. * * \param fd File descriptor @@ -5870,301 +5837,3 @@ int llapi_file_flush(int fd) return llapi_get_data_version(fd, &dv, LL_DV_WR_FLUSH); } -/* - * Fetch layout version from OST objects. Layout version on OST objects are - * only set when the file is a mirrored file AND after the file has been - * written at least once. - * - * It actually fetches the least layout version from the objects. - */ -int llapi_get_ost_layout_version(int fd, __u32 *layout_version) -{ - int rc; - struct ioc_data_version idv = { 0 }; - - rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv); - if (rc) - rc = -errno; - else - *layout_version = idv.idv_layout_version; - - return rc; -} - -/* - * Create a file without any name and open it for read/write - * - * - file is created as if it were a standard file in the given \a directory - * - file does not appear in \a directory and mtime does not change because - * the filename is handled specially by the Lustre MDS. - * - file is destroyed at final close - * - * \param[in] directory directory from which to inherit layout/MDT idx - * \param[in] mdt_idx MDT index on which the file is created, - * \a idx == -1 means no specific MDT is requested - * \param[in] mode standard open(2) mode - * \param[in] stripe_param stripe parameters. May be NULL. - * - * \retval a file descriptor on success. - * \retval -errno on error. - */ -int llapi_create_volatile_param(const char *directory, int mdt_idx, - int open_flags, mode_t mode, - const struct llapi_stripe_param *stripe_param) -{ - char file_path[PATH_MAX]; - int saved_errno = errno; - int fd; - unsigned int rnumber; - int rc; - - do { - rnumber = random(); - if (mdt_idx == -1) - rc = snprintf(file_path, sizeof(file_path), - "%s/" LUSTRE_VOLATILE_HDR "::%.4X", - directory, rnumber); - else - rc = snprintf(file_path, sizeof(file_path), - "%s/" LUSTRE_VOLATILE_HDR ":%.4X:%.4X", - directory, mdt_idx, rnumber); - - if (rc < 0 || rc >= sizeof(file_path)) - return -ENAMETOOLONG; - - /* - * Either open O_WRONLY or O_RDWR, creating RDONLY - * is non-sensical here - */ - if ((open_flags & O_ACCMODE) == O_RDONLY) - open_flags = O_RDWR | (open_flags & ~O_ACCMODE); - - open_flags |= O_CREAT | O_EXCL | O_NOFOLLOW; - - if (stripe_param != NULL) { - fd = llapi_file_open_param(file_path, open_flags, - mode, stripe_param); - if (fd < 0) - rc = fd; - } else { - fd = open(file_path, open_flags, mode); - if (fd < 0) - rc = -errno; - } - } while (fd < 0 && rc == -EEXIST); - - if (fd < 0) { - llapi_error(LLAPI_MSG_ERROR, rc, - "Cannot create volatile file '%s' in '%s'", - file_path + strlen(directory) + 1 + - LUSTRE_VOLATILE_HDR_LEN, - directory); - return rc; - } - - /* - * Unlink file in case this wasn't a Lustre filesystem and the magic - * volatile filename wasn't handled as intended. The effect is the - * same. If volatile open was supported then we expect unlink() to - * return -ENOENT. - */ - (void)unlink(file_path); - - /* - * Since we are returning successfully we restore errno (and - * mask out possible EEXIST from open() and ENOENT from unlink(). - */ - errno = saved_errno; - - return fd; -} - -/* - * Create a file without any name open it for read/write - * - * - file is created as if it were a standard file in the given \a directory - * - file does not appear in \a directory and mtime does not change because - * the filename is handled specially by the Lustre MDS. - * - file is removed at final close - * - file modes are rw------- since it doesn't make sense to have a read-only - * or write-only file that cannot be opened again. - * - if user wants another mode it must use fchmod() on the open file, no - * security problems arise because it cannot be opened by another process. - * - * \param[in] directory directory from which to inherit layout/MDT idx - * \param[in] idx MDT index on which the file is created, - * \a idx == -1 means no specific MDT is requested - * \param[in] open_flags standard open(2) flags - * - * \retval a file descriptor on success. - * \retval -errno on error. - */ -int llapi_create_volatile_idx(const char *directory, int mdt_idx, - int open_flags) -{ - return llapi_create_volatile_param(directory, mdt_idx, open_flags, - S_IRUSR | S_IWUSR, NULL); -} - -/** - * Swap the layouts between 2 file descriptors - * the 2 files must be open for writing - * first fd received the ioctl, second fd is passed as arg - * this is assymetric but avoid use of root path for ioctl - */ -int llapi_fswap_layouts_grouplock(int fd1, int fd2, __u64 dv1, __u64 dv2, - int gid, __u64 flags) -{ - struct lustre_swap_layouts lsl; - struct stat st1; - struct stat st2; - int rc; - - if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) { - rc = fstat(fd1, &st1); - if (rc < 0) - return -errno; - - rc = fstat(fd2, &st2); - if (rc < 0) - return -errno; - } - lsl.sl_fd = fd2; - lsl.sl_flags = flags; - lsl.sl_gid = gid; - lsl.sl_dv1 = dv1; - lsl.sl_dv2 = dv2; - rc = ioctl(fd1, LL_IOC_LOV_SWAP_LAYOUTS, &lsl); - if (rc < 0) - return -errno; - - if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) { - struct timeval tv1[2]; - struct timeval tv2[2]; - - memset(tv1, 0, sizeof(tv1)); - memset(tv2, 0, sizeof(tv2)); - - if (flags & SWAP_LAYOUTS_KEEP_ATIME) { - tv1[0].tv_sec = st1.st_atime; - tv2[0].tv_sec = st2.st_atime; - } else { - tv1[0].tv_sec = st2.st_atime; - tv2[0].tv_sec = st1.st_atime; - } - - if (flags & SWAP_LAYOUTS_KEEP_MTIME) { - tv1[1].tv_sec = st1.st_mtime; - tv2[1].tv_sec = st2.st_mtime; - } else { - tv1[1].tv_sec = st2.st_mtime; - tv2[1].tv_sec = st1.st_mtime; - } - - rc = futimes(fd1, tv1); - if (rc < 0) - return -errno; - - rc = futimes(fd2, tv2); - if (rc < 0) - return -errno; - } - - return 0; -} - -int llapi_fswap_layouts(int fd1, int fd2, __u64 dv1, __u64 dv2, __u64 flags) -{ - int rc; - int grp_id; - - do - grp_id = random(); - while (grp_id == 0); - - rc = llapi_fswap_layouts_grouplock(fd1, fd2, dv1, dv2, grp_id, flags); - if (rc < 0) - return rc; - - return 0; -} - -/** - * Swap the layouts between 2 files - * the 2 files are open in write - */ -int llapi_swap_layouts(const char *path1, const char *path2, - __u64 dv1, __u64 dv2, __u64 flags) -{ - int fd1, fd2, rc; - - fd1 = open(path1, O_WRONLY | O_LOV_DELAY_CREATE); - if (fd1 < 0) { - rc = -errno; - llapi_error(LLAPI_MSG_ERROR, rc, - "error: cannot open '%s' for write", path1); - goto out; - } - - fd2 = open(path2, O_WRONLY | O_LOV_DELAY_CREATE); - if (fd2 < 0) { - rc = -errno; - llapi_error(LLAPI_MSG_ERROR, rc, - "error: cannot open '%s' for write", path2); - goto out_close; - } - - rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2, flags); - if (rc < 0) - llapi_error(LLAPI_MSG_ERROR, rc, - "error: cannot swap layout between '%s' and '%s'", - path1, path2); - - close(fd2); -out_close: - close(fd1); -out: - return rc; -} - -/** - * Take group lock. - * - * \param fd File to lock. - * \param gid Group Identifier. - * - * \retval 0 on success. - * \retval -errno on failure. - */ -int llapi_group_lock(int fd, int gid) -{ - int rc; - - rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid); - if (rc < 0) { - rc = -errno; - llapi_error(LLAPI_MSG_ERROR, rc, "cannot get group lock"); - } - return rc; -} - -/** - * Put group lock. - * - * \param fd File to unlock. - * \param gid Group Identifier. - * - * \retval 0 on success. - * \retval -errno on failure. - */ -int llapi_group_unlock(int fd, int gid) -{ - int rc; - - rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid); - if (rc < 0) { - rc = -errno; - llapi_error(LLAPI_MSG_ERROR, rc, "cannot put group lock"); - } - return rc; -} diff --git a/lustre/utils/liblustreapi_swap.c b/lustre/utils/liblustreapi_swap.c new file mode 100644 index 0000000..21b4d8d --- /dev/null +++ b/lustre/utils/liblustreapi_swap.c @@ -0,0 +1,399 @@ +/* + * LGPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public License + * (LGPL) version 2.1 or (at your discretion) any later version. + * (LGPL) version 2.1 accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-2.1.html + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * LGPL HEADER END + */ +/* + * Copyright (c) 2012 Commissariat a l'energie atomique et aux energies + * alternatives + * Copyright (c) 2017, 2021, DDN Storage Corporation. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + */ +/* + * lustreapi library for file layout swapping. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Get a 64-bit value representing the version of file data pointed by fd. + * + * Each write or truncate, flushed on OST, will change this value. You can use + * this value to verify if file data was modified. This only checks the file + * data, not metadata. + * + * \param flags 0: no flush pages, usually used it the process has already + * taken locks; + * LL_DV_RD_FLUSH: OSTs will take LCK_PR to flush dirty pages + * from clients; + * LL_DV_WR_FLUSH: OSTs will take LCK_PW to flush all caching + * pages from clients. + * + * \retval 0 on success. + * \retval -errno on error. + */ +int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags) +{ + int rc; + struct ioc_data_version idv; + + idv.idv_flags = (__u32)flags; + + rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv); + if (rc) + rc = -errno; + else + *data_version = idv.idv_version; + + return rc; +} + +/* + * Fetch layout version from OST objects. Layout version on OST objects are + * only set when the file is a mirrored file AND after the file has been + * written at least once. + * + * It actually fetches the least layout version from the objects. + */ +int llapi_get_ost_layout_version(int fd, __u32 *layout_version) +{ + int rc; + struct ioc_data_version idv = { 0 }; + + rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv); + if (rc) + rc = -errno; + else + *layout_version = idv.idv_layout_version; + + return rc; +} + +/* + * Create a file without any name and open it for read/write + * + * - file is created as if it were a standard file in the given \a directory + * - file does not appear in \a directory and mtime does not change because + * the filename is handled specially by the Lustre MDS. + * - file is destroyed at final close + * + * \param[in] directory directory from which to inherit layout/MDT idx + * \param[in] mdt_idx MDT index on which the file is created, + * \a idx == -1 means no specific MDT is requested + * \param[in] mode standard open(2) mode + * \param[in] stripe_param stripe parameters. May be NULL. + * + * \retval a file descriptor on success. + * \retval -errno on error. + */ +int llapi_create_volatile_param(const char *directory, int mdt_idx, + int open_flags, mode_t mode, + const struct llapi_stripe_param *stripe_param) +{ + char file_path[PATH_MAX]; + int saved_errno = errno; + int fd; + unsigned int rnumber; + int rc; + + do { + rnumber = random(); + if (mdt_idx == -1) + rc = snprintf(file_path, sizeof(file_path), + "%s/" LUSTRE_VOLATILE_HDR "::%.4X", + directory, rnumber); + else + rc = snprintf(file_path, sizeof(file_path), + "%s/" LUSTRE_VOLATILE_HDR ":%.4X:%.4X", + directory, mdt_idx, rnumber); + + if (rc < 0 || rc >= sizeof(file_path)) + return -ENAMETOOLONG; + + /* + * Either open O_WRONLY or O_RDWR, creating RDONLY + * is non-sensical here + */ + if ((open_flags & O_ACCMODE) == O_RDONLY) + open_flags = O_RDWR | (open_flags & ~O_ACCMODE); + + open_flags |= O_CREAT | O_EXCL | O_NOFOLLOW; + + if (stripe_param != NULL) { + fd = llapi_file_open_param(file_path, open_flags, + mode, stripe_param); + if (fd < 0) + rc = fd; + } else { + fd = open(file_path, open_flags, mode); + if (fd < 0) + rc = -errno; + } + } while (fd < 0 && rc == -EEXIST); + + if (fd < 0) { + llapi_error(LLAPI_MSG_ERROR, rc, + "Cannot create volatile file '%s' in '%s'", + file_path + strlen(directory) + 1 + + LUSTRE_VOLATILE_HDR_LEN, + directory); + return rc; + } + + /* + * Unlink file in case this wasn't a Lustre filesystem and the magic + * volatile filename wasn't handled as intended. The effect is the + * same. If volatile open was supported then we expect unlink() to + * return -ENOENT. + */ + (void)unlink(file_path); + + /* + * Since we are returning successfully we restore errno (and + * mask out possible EEXIST from open() and ENOENT from unlink(). + */ + errno = saved_errno; + + return fd; +} + +/* + * Create a file without any name open it for read/write + * + * - file is created as if it were a standard file in the given \a directory + * - file does not appear in \a directory and mtime does not change because + * the filename is handled specially by the Lustre MDS. + * - file is removed at final close + * - file modes are rw------- since it doesn't make sense to have a read-only + * or write-only file that cannot be opened again. + * - if user wants another mode it must use fchmod() on the open file, no + * security problems arise because it cannot be opened by another process. + * + * \param[in] directory directory from which to inherit layout/MDT idx + * \param[in] idx MDT index on which the file is created, + * \a idx == -1 means no specific MDT is requested + * \param[in] open_flags standard open(2) flags + * + * \retval a file descriptor on success. + * \retval -errno on error. + */ +int llapi_create_volatile_idx(const char *directory, int mdt_idx, + int open_flags) +{ + return llapi_create_volatile_param(directory, mdt_idx, open_flags, + S_IRUSR | S_IWUSR, NULL); +} + +/** + * Swap the layouts between 2 file descriptors + * the 2 files must be open for writing + * first fd received the ioctl, second fd is passed as arg + * this is assymetric but avoid use of root path for ioctl + */ +int llapi_fswap_layouts_grouplock(int fd1, int fd2, __u64 dv1, __u64 dv2, + int gid, __u64 flags) +{ + struct lustre_swap_layouts lsl; + struct stat st1; + struct stat st2; + int rc; + + if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) { + rc = fstat(fd1, &st1); + if (rc < 0) + return -errno; + + rc = fstat(fd2, &st2); + if (rc < 0) + return -errno; + } + lsl.sl_fd = fd2; + lsl.sl_flags = flags; + lsl.sl_gid = gid; + lsl.sl_dv1 = dv1; + lsl.sl_dv2 = dv2; + rc = ioctl(fd1, LL_IOC_LOV_SWAP_LAYOUTS, &lsl); + if (rc < 0) + return -errno; + + if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) { + struct timeval tv1[2]; + struct timeval tv2[2]; + + memset(tv1, 0, sizeof(tv1)); + memset(tv2, 0, sizeof(tv2)); + + if (flags & SWAP_LAYOUTS_KEEP_ATIME) { + tv1[0].tv_sec = st1.st_atime; + tv2[0].tv_sec = st2.st_atime; + } else { + tv1[0].tv_sec = st2.st_atime; + tv2[0].tv_sec = st1.st_atime; + } + + if (flags & SWAP_LAYOUTS_KEEP_MTIME) { + tv1[1].tv_sec = st1.st_mtime; + tv2[1].tv_sec = st2.st_mtime; + } else { + tv1[1].tv_sec = st2.st_mtime; + tv2[1].tv_sec = st1.st_mtime; + } + + rc = futimes(fd1, tv1); + if (rc < 0) + return -errno; + + rc = futimes(fd2, tv2); + if (rc < 0) + return -errno; + } + + return 0; +} + +int llapi_fswap_layouts(int fd1, int fd2, __u64 dv1, __u64 dv2, __u64 flags) +{ + int rc; + int grp_id; + + do + grp_id = random(); + while (grp_id == 0); + + rc = llapi_fswap_layouts_grouplock(fd1, fd2, dv1, dv2, grp_id, flags); + if (rc < 0) + return rc; + + return 0; +} + +/** + * Swap the layouts between 2 files + * the 2 files are open in write + */ +int llapi_swap_layouts(const char *path1, const char *path2, + __u64 dv1, __u64 dv2, __u64 flags) +{ + int fd1, fd2, rc; + + fd1 = open(path1, O_WRONLY | O_LOV_DELAY_CREATE); + if (fd1 < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "error: cannot open '%s' for write", path1); + goto out; + } + + fd2 = open(path2, O_WRONLY | O_LOV_DELAY_CREATE); + if (fd2 < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "error: cannot open '%s' for write", path2); + goto out_close; + } + + rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2, flags); + if (rc < 0) + llapi_error(LLAPI_MSG_ERROR, rc, + "error: cannot swap layout between '%s' and '%s'", + path1, path2); + + close(fd2); +out_close: + close(fd1); +out: + return rc; +} + +/** + * Take group lock. + * + * \param fd File to lock. + * \param gid Group Identifier. + * + * \retval 0 on success. + * \retval -errno on failure. + */ +int llapi_group_lock(int fd, int gid) +{ + int rc; + + rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid); + if (rc < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "cannot get group lock"); + } + return rc; +} + +int llapi_group_lock64(int fd, __u64 gid) +{ + int rc; + + /* If this is ever compiled on a 32-bit system then a new + * LL_IOC_GROUP_LOCK64 will need to be defined that takes + * __u64 as an argument. That may never happen again. + */ + BUILD_BUG_ON(sizeof(long) != sizeof(__u64)); + rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid); + if (rc < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "cannot get group lock"); + } + return rc; +} + +/** + * Put group lock. + * + * \param fd File to unlock. + * \param gid Group Identifier. + * + * \retval 0 on success. + * \retval -errno on failure. + */ +int llapi_group_unlock(int fd, int gid) +{ + int rc; + + rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid); + if (rc < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "cannot put group lock"); + } + return rc; +} + +int llapi_group_unlock64(int fd, __u64 gid) +{ + int rc; + + rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid); + if (rc < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "cannot put group lock"); + } + return rc; +} diff --git a/lustre/utils/wirehdr.c b/lustre/utils/wirehdr.c index cb26f19..a6c27c2 100644 --- a/lustre/utils/wirehdr.c +++ b/lustre/utils/wirehdr.c @@ -51,17 +51,6 @@ #define LASSERT(cond) if (!(cond)) { printf("failed " #cond "\n"); ret = 1; } #define LASSERTF(cond, fmt, ...) if (!(cond)) { printf("failed '" #cond "'" fmt, ## __VA_ARGS__); ret = 1; } -/* - * BUILD_BUG_ON() is Compile-time check which verifies correctness at - * compile-time rather than runtime. If "cond" is true, then there are two - * identical cases ("0" and "0"), which is an error that causes the compiler to - * complain. If "cond" is false, then there are two different cases - * ("(non-zero)" and "0"). - * - */ -#ifndef BUILD_BUG_ON -#define BUILD_BUG_ON(cond) do {switch (0) {case (cond): case 1: break; } } while (0) -#endif int ret; diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 83e07b6..f04b715 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -48,20 +48,10 @@ #endif /* CONFIG_FS_POSIX_ACL */ #endif /* HAVE_SERVER_SUPPORT */ #include +#include #define LASSERT(cond) if (!(cond)) { printf("failed " #cond "\n"); ret = 1; } #define LASSERTF(cond, fmt, ...) if (!(cond)) { printf("failed '" #cond "'" fmt, ## __VA_ARGS__); ret = 1; } -/* - * BUILD_BUG_ON() is Compile-time check which verifies correctness at - * compile-time rather than runtime. If "cond" is true, then there are two - * identical cases ("0" and "0"), which is an error that causes the compiler to - * complain. If "cond" is false, then there are two different cases - * ("(non-zero)" and "0"). - * - */ -#ifndef BUILD_BUG_ON -#define BUILD_BUG_ON(cond) do {switch (0) {case (cond): case 1: break; } } while (0) -#endif int ret; -- 1.8.3.1