Whamcloud - gitweb
LU-14583 llapi: handle symlinks in llapi_file_get_stripe() 29/43229/4
authorJohn L. Hammond <jhammond@whamcloud.com>
Wed, 7 Apr 2021 19:11:25 +0000 (14:11 -0500)
committerOleg Drokin <green@whamcloud.com>
Wed, 19 May 2021 02:03:28 +0000 (02:03 +0000)
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 <jhammond@whamcloud.com>
Change-Id: Ic046d6ef77d8342d47336144e3066cab3a940a96
Reviewed-on: https://review.whamcloud.com/43229
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/tests/sanity.sh
lustre/utils/liblustreapi.c

index 2bc8ed7..dc731af 100755 (executable)
@@ -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
index 2d29c35..14263ac 100644 (file)
@@ -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 };