From cd4caef54f63b6a0d26a90d879f378b7fe3d4862 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 7 Apr 2021 14:11:25 -0500 Subject: [PATCH] LU-14583 llapi: handle symlinks in llapi_file_get_stripe() In llapi_file_get_stripe(), if the IOC_MDC_GETFILESTRIPE ioctl handler returns -ENOTTY or -ENODATA then try to resolve any symlinks in the path and try again. Signed-off-by: John L. Hammond Change-Id: Ic046d6ef77d8342d47336144e3066cab3a940a96 Reviewed-on: https://review.whamcloud.com/43229 Reviewed-by: Bobi Jam Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/tests/sanity.sh | 31 +++++++++++++++++++++++++++++++ lustre/utils/liblustreapi.c | 27 ++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 2bc8ed7..dc731af 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -3319,6 +3319,37 @@ test_27P() { } run_test 27P "basic ops on foreign dir of foreign_symlink type" +test_27Q() { + rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken + + test_mkdir $DIR/$tdir-1 + test_mkdir $DIR/$tdir-2 + + echo 'It is what it is' > $DIR/$tdir-1/$tfile + lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?" + + ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile + lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?" + + ln -s $DIR/$tdir-1/$tfile $TMP/$tfile + lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?" + + # Create some bad symlinks and ensure that we don't loop + # forever or something. These should return ELOOP (40) and + # ENOENT (2) but I don't want to test for that because there's + # always some weirdo architecture that needs to ruin + # everything by defining these error numbers differently. + + ln -s $TMP/$tfile.loop $TMP/$tfile.loop + lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?" + + ln -s $TMP/$tfile.none $TMP/$tfile.broken + lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?" + + return 0 +} +run_test 27Q "llapi_file_get_stripe() works on symlinks" + # createtest also checks that device nodes are created and # then visible correctly (#2091) test_28() { # bug 2091 diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 2d29c35..14263ac 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -4051,7 +4051,7 @@ static void llapi_lov_dump_user_lmm(struct find_param *param, char *path, } } -int llapi_file_get_stripe(const char *path, struct lov_user_md *lum) +static int llapi_file_get_stripe1(const char *path, struct lov_user_md *lum) { const char *fname; char *dname; @@ -4093,6 +4093,31 @@ out_free: return rc; } +int llapi_file_get_stripe(const char *path, struct lov_user_md *lum) +{ + char *canon_path = NULL; + int rc, rc2; + + rc = llapi_file_get_stripe1(path, lum); + if (!(rc == -ENOTTY || rc == -ENODATA)) + goto out; + + /* Handle failure due to symlinks by dereferencing path manually. */ + canon_path = canonicalize_file_name(path); + if (canon_path == NULL) + goto out; /* Keep original rc. */ + + rc2 = llapi_file_get_stripe1(canon_path, lum); + if (rc2 < 0) + goto out; /* Keep original rc. */ + + rc = 0; +out: + free(canon_path); + + return rc; +} + int llapi_file_lookup(int dirfd, const char *name) { struct obd_ioctl_data data = { 0 }; -- 1.8.3.1