}
run_test 56y "lfs find -L raid0|released"
+test_56z() { # LU-4824
+ # This checks to make sure 'lfs find' continues after errors
+ # There are two classes of errors that should be caught:
+ # - If multiple paths are provided, all should be searched even if one
+ # errors out
+ # - If errors are encountered during the search, it should not terminate
+ # early
+ local i
+ test_mkdir $DIR/$tdir
+ for i in d{0..9}; do
+ test_mkdir $DIR/$tdir/$i
+ done
+ touch $DIR/$tdir/d{0..9}/$tfile
+ $LFS find $DIR/non_existent_dir $DIR/$tdir &&
+ error "$LFS find did not return an error"
+ # Make a directory unsearchable. This should NOT be the last entry in
+ # directory order. Arbitrarily pick the 6th entry
+ chmod 700 $(lfs find $DIR/$tdir -type d | sed '6!d')
+ local count=$($RUNAS $LFS find $DIR/non_existent $DIR/$tdir | wc -l)
+ # The user should be able to see 10 directories and 9 files
+ [ $count == 19 ] || error "$LFS find did not continue after error"
+}
+run_test 56z "lfs find should continue after an error"
+
test_57a() {
[ $PARALLEL == "yes" ] && skip "skip parallel run" && return
# note test will not do anything if MDS is not local
#define FIND_POOL_OPT 3
static int lfs_find(int argc, char **argv)
{
- int c, ret;
+ int c, rc;
+ int ret = 0;
time_t t;
struct find_param param = { .maxdepth = -1, .quiet = 1 };
struct option long_opts[] = {
param.exclude_ctime = !!neg_opt;
}
/* no break, this falls through to 'M' for mtime */
- case 'M':
- if (c == 'M') {
- xtime = ¶m.mtime;
- xsign = ¶m.msign;
- param.exclude_mtime = !!neg_opt;
- }
- ret = set_time(&t, xtime, optarg);
- if (ret == INT_MAX) {
- ret = -1;
- goto err;
- }
- if (ret)
- *xsign = ret;
- break;
+ case 'M':
+ if (c == 'M') {
+ xtime = ¶m.mtime;
+ xsign = ¶m.msign;
+ param.exclude_mtime = !!neg_opt;
+ }
+ rc = set_time(&t, xtime, optarg);
+ if (rc == INT_MAX) {
+ ret = -1;
+ goto err;
+ }
+ if (rc)
+ *xsign = rc;
+ break;
case 'c':
if (optarg[0] == '+') {
param.stripecount_sign = -1;
param.maxdepth = strtol(optarg, 0, 0);
break;
case 'g':
- case 'G':
- ret = name2id(¶m.gid, optarg, GROUP);
- if (ret) {
- param.gid = strtoul(optarg, &endptr, 10);
+ case 'G':
+ rc = name2id(¶m.gid, optarg, GROUP);
+ if (rc) {
+ param.gid = strtoul(optarg, &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "Group/GID: %s cannot "
"be found.\n", optarg);
param.exclude_layout = !!neg_opt;
param.check_layout = 1;
break;
- case 'u':
- case 'U':
- ret = name2id(¶m.uid, optarg, USER);
- if (ret) {
- param.uid = strtoul(optarg, &endptr, 10);
+ case 'u':
+ case 'U':
+ rc = name2id(¶m.uid, optarg, USER);
+ if (rc) {
+ param.uid = strtoul(optarg, &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "User/UID: %s cannot "
"be found.\n", optarg);
pathend = argc;
}
- do {
- ret = llapi_find(argv[pathstart], ¶m);
- } while (++pathstart < pathend && !ret);
+ do {
+ rc = llapi_find(argv[pathstart], ¶m);
+ if (rc != 0 && ret == 0)
+ ret = rc;
+ } while (++pathstart < pathend);
if (ret)
fprintf(stderr, "error: %s failed for %s.\n",
int len, ret;
DIR *d, *p = NULL;
- ret = 0;
- len = strlen(path);
+ ret = 0;
+ len = strlen(path);
d = opendir(path);
if (!d && errno != ENOTDIR) {
if (sem_init && (ret = sem_init(path, parent ?: p, d, data, de)))
goto err;
- if (!d || (param->get_lmv && !param->recursive)) {
- ret = 0;
+ if (!d || (param->get_lmv && !param->recursive))
goto out;
- }
while ((dent = readdir64(d)) != NULL) {
+ int rc;
+
param->have_fileinfo = 0;
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
if (dent->d_type == DT_UNKNOWN) {
lstat_t *st = ¶m->lmd->lmd_st;
- ret = get_lmd_info(path, d, NULL, param->lmd,
- param->lumlen);
- if (ret == 0) {
+ rc = get_lmd_info(path, d, NULL, param->lmd,
+ param->lumlen);
+ if (rc == 0)
dent->d_type =
llapi_filetype_dir_table[st->st_mode &
S_IFMT];
- }
- if (ret == -ENOENT)
- continue;
+ else if (ret == 0)
+ ret = rc;
+
+ if (rc == -ENOENT)
+ continue;
}
switch (dent->d_type) {
case DT_UNKNOWN:
"error: %s: '%s' is UNKNOWN type %d",
__func__, dent->d_name, dent->d_type);
break;
- case DT_DIR:
- ret = llapi_semantic_traverse(path, size, d, sem_init,
- sem_fini, data, dent);
- if (ret < 0)
- goto out;
- break;
- default:
- ret = 0;
- if (sem_init) {
- ret = sem_init(path, d, NULL, data, dent);
- if (ret < 0)
- goto out;
- }
- if (sem_fini && ret == 0)
- sem_fini(path, d, NULL, data, dent);
+ case DT_DIR:
+ rc = llapi_semantic_traverse(path, size, d, sem_init,
+ sem_fini, data, dent);
+ if (rc != 0 && ret == 0)
+ ret = rc;
+ break;
+ default:
+ rc = 0;
+ if (sem_init) {
+ rc = sem_init(path, d, NULL, data, dent);
+ if (rc < 0 && ret == 0)
+ ret = rc;
+ }
+ if (sem_fini && rc == 0)
+ sem_fini(path, d, NULL, data, dent);
}
}
closedir(d);
if (p)
closedir(p);
- return ret;
+ return ret;
}
static int param_callback(char *path, semantic_func_t sem_init,