Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e8b45c4

Browse files
committedDec 3, 2024
mfu: copy fsx_projid and FS_XFLAG_PROJINHERIT
When copying files using dcp or dsync, extended attributes such as fsx_projid and FS_XFLAG_PROJINHERIT are also copied. Signed-off-by: Sohei Koyama <[email protected]>
1 parent b65c188 commit e8b45c4

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed
 

‎src/common/mfu_flist_copy.c

+71
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include <time.h> /* asctime / localtime */
1919
#include <regex.h>
2020

21+
#if DCOPY_USE_XATTRS
22+
#include <linux/fs.h>
23+
#endif
24+
2125
#ifdef HAVE_LIBATTR
2226
#include <attr/libattr.h>
2327
#endif /* HAVE_LIBATTR */
@@ -261,6 +265,66 @@ static int mfu_copy_close_file(
261265
return rc;
262266
}
263267

268+
static int mfu_copy_projid(
269+
const char* src_path,
270+
const char* dest_path)
271+
{
272+
int rc = 0;
273+
struct stat st;
274+
/* check whether the src is symlink */
275+
if (lstat(src_path, &st)) {
276+
MFU_LOG(MFU_LOG_ERR, "lstat failed: `%s' errno=%d (%s)", src_path, errno, strerror(errno));
277+
goto xattr_fin;
278+
}
279+
if (S_ISLNK(st.st_mode)) {
280+
goto xattr_fin;
281+
}
282+
/* open the src */
283+
int src_fd = open(src_path, O_RDONLY);
284+
if (src_fd < 0) {
285+
MFU_LOG(MFU_LOG_ERR, "open failed: `%s' errno=%d (%s)", src_path, errno, strerror(errno));
286+
rc = -1;
287+
goto xattr_fin;
288+
}
289+
/* open the dest */
290+
int dest_fd = open(dest_path, O_RDONLY);
291+
if (dest_fd < 0) {
292+
MFU_LOG(MFU_LOG_ERR, "open failed: `%s' errno=%d (%s)", dest_path, errno, strerror(errno));
293+
rc = -1;
294+
goto xattr_close_src;
295+
}
296+
struct fsxattr src_attr;
297+
/* get src's xattr */
298+
rc = ioctl(src_fd, FS_IOC_FSGETXATTR, &src_attr);
299+
if (rc != 0) {
300+
MFU_LOG(MFU_LOG_ERR, "ioctl(FS_IOC_FSGETXATTR) failed: `%s' errno=%d (%s)", src_path, errno, strerror(errno));
301+
goto xattr_close_dest;
302+
}
303+
struct fsxattr dest_attr;
304+
/* get dest's xattr */
305+
rc = ioctl(dest_fd, FS_IOC_FSGETXATTR, &dest_attr);
306+
if (rc != 0) {
307+
MFU_LOG(MFU_LOG_ERR, "ioctl(FS_IOC_FSGETXATTR) failed: `%s' errno=%d (%s)", dest_path, errno, strerror(errno));
308+
goto xattr_close_dest;
309+
}
310+
dest_attr.fsx_projid = src_attr.fsx_projid;
311+
dest_attr.fsx_xflags = (dest_attr.fsx_xflags & ~FS_XFLAG_PROJINHERIT) |
312+
(src_attr.fsx_xflags & FS_XFLAG_PROJINHERIT);
313+
/* set dest's xattr */
314+
rc = ioctl(dest_fd, FS_IOC_FSSETXATTR, &dest_attr);
315+
if (rc != 0) {
316+
MFU_LOG(MFU_LOG_ERR, "ioctl(FS_IOC_FSSETXATTR) failed: `%s' errno=%d (%s)", dest_path, errno, strerror(errno));
317+
}
318+
xattr_close_dest:
319+
/* close dest */
320+
close(dest_fd);
321+
xattr_close_src:
322+
/* close src */
323+
close(src_fd);
324+
xattr_fin:
325+
return rc;
326+
}
327+
264328
/* copy all extended attributes from op->operand to dest_path,
265329
* returns 0 on success and -1 on failure */
266330
static int mfu_copy_xattrs(
@@ -443,6 +507,13 @@ static int mfu_copy_xattrs(
443507
mfu_free(&list);
444508
list_bufsize = 0;
445509

510+
rc = mfu_copy_projid(src_path, dest_path);
511+
if (rc) {
512+
MFU_LOG(MFU_LOG_ERR, "Failed to copy projid from src_path=%s to dest_path=%s (errno=%d %s)",
513+
src_path, dest_path, errno, strerror(errno)
514+
);
515+
}
516+
446517
#endif /* DCOPY_USE_XATTR */
447518

448519
return rc;

0 commit comments

Comments
 (0)
Please sign in to comment.