void cfs_walk_dir_generic(struct ceph_mount_info* _fs, const char* _entry_point, cfs_dentry_handler_t _handler, cfs_dentry_comparator_t _comparator, void* _data, unsigned int _level) { int ceph_opendir_res = -1; int ceph_readdirplus_r_res = 0; int sb_mask = 0; char path[PATH_MAX]; struct ceph_dir_result* cfs_dir = NULL; struct dirent entry; struct stat sb; pfcq_zero(&entry, sizeof(struct dirent)); pfcq_zero(&sb, sizeof(struct stat)); pfcq_zero(path, PATH_MAX); debug("Walking into %s entry...\n", _entry_point); ceph_opendir_res = ceph_opendir(_fs, _entry_point, &cfs_dir); if (unlikely(ceph_opendir_res != 0)) { warning("ceph_opendir"); goto out; } while (likely((ceph_readdirplus_r_res = ceph_readdirplus_r(_fs, cfs_dir, &entry, &sb, &sb_mask)) == 1)) { if (unlikely(strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0)) continue; if (likely(_comparator)) if (unlikely(!_comparator(_entry_point, &entry, &sb, _level))) continue; if (likely(strcmp(_entry_point, "/") == 0)) { if (unlikely(snprintf(path, PATH_MAX, "/%s", entry.d_name) < 0)) continue; } else { if (unlikely(snprintf(path, PATH_MAX, "%s/%s", _entry_point, entry.d_name) < 0)) continue; } if (likely(_handler)) _handler(_fs, path, &entry, &sb, _data, _level); } if (unlikely(ceph_closedir(_fs, cfs_dir) != 0)) warning("ceph_closedir"); out: debug("Walking out of %s entry...\n", _entry_point); return; }
static DIR *cephwrap_fdopendir(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *mask, uint32_t attributes) { int ret = 0; struct ceph_dir_result *result; DBG_DEBUG("[CEPH] fdopendir(%p, %p)\n", handle, fsp); ret = ceph_opendir(handle->data, fsp->fsp_name->base_name, &result); if (ret < 0) { result = NULL; errno = -ret; /* We return result which is NULL in this case */ } DBG_DEBUG("[CEPH] fdopendir(...) = %d\n", ret); return (DIR *) result; }
static DIR *cephwrap_opendir(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, const char *mask, uint32_t attr) { int ret = 0; struct ceph_dir_result *result; DBG_DEBUG("[CEPH] opendir(%p, %s)\n", handle, smb_fname->base_name); /* Returns NULL if it does not exist or there are problems ? */ ret = ceph_opendir(handle->data, smb_fname->base_name, &result); if (ret < 0) { result = NULL; errno = -ret; /* We return result which is NULL in this case */ } DBG_DEBUG("[CEPH] opendir(...) = %d\n", ret); return (DIR *) result; }
int cfs_mkdir_safe(struct ceph_mount_info* _fs, const char* _path, mode_t _mode) { int ret = 0; int ceph_opendir_res = -1; struct ceph_dir_result* cfs_dir = NULL; if (unlikely(pthread_mutex_lock(&cfs_mkdir_safe_lock))) panic("pthread_mutex_lock"); ceph_opendir_res = ceph_opendir(_fs, _path, &cfs_dir); if (unlikely(ceph_opendir_res != 0)) ret = ceph_mkdir(_fs, _path, _mode); else ceph_closedir(_fs, cfs_dir); if (unlikely(pthread_mutex_unlock(&cfs_mkdir_safe_lock))) panic("pthread_mutex_unlock"); return ret; }
/* * Start the backup of a specific file */ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp) { int status; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; /* * Save the current flags used to save the next file. */ copy_bits(FO_MAX, sp->flags, p_ctx->flags); /* * See if we start processing a new directory if so open it so the can recurse * into it if wanted. */ switch (p_ctx->type) { case FT_DIRBEGIN: /* * See if we are recursing if so we open the directory and process it. * We also open the directory when it the toplevel e.g. when p_ctx->cdir == NULL. */ if (!p_ctx->cdir || !bit_is_set(FO_NO_RECURSION, p_ctx->flags)) { /* * Change into the directory and process all entries in it. */ status = ceph_chdir(p_ctx->cmount, p_ctx->next_filename); if (status < 0) { berrno be; Jmsg(ctx, M_ERROR, "ceph_chdir(%s) failed: %s\n", p_ctx->next_filename, be.bstrerror(-status)); p_ctx->type = FT_NOOPEN; } else { /* * Push the current directory onto the directory stack so we can * continue processing it later on. */ if (p_ctx->cdir) { struct dir_stack_entry *new_entry; new_entry = (struct dir_stack_entry *)malloc(sizeof(struct dir_stack_entry)); memcpy(&new_entry->statp, &p_ctx->statp, sizeof(new_entry->statp)); new_entry->cdir = p_ctx->cdir; p_ctx->dir_stack->push(new_entry); } /* * Open this directory for processing. */ status = ceph_opendir(p_ctx->cmount, ".", &p_ctx->cdir); if (status < 0) { berrno be; Jmsg(ctx, M_ERROR, "ceph_opendir(%s) failed: %s\n", p_ctx->next_filename, be.bstrerror(-status)); p_ctx->type = FT_NOOPEN; /* * Pop the previous directory handle and continue processing that. */ if (!p_ctx->dir_stack->empty()) { struct dir_stack_entry *entry; entry = (struct dir_stack_entry *)p_ctx->dir_stack->pop(); memcpy(&p_ctx->statp, &entry->statp, sizeof(p_ctx->statp)); p_ctx->cdir = entry->cdir; free(entry); status = ceph_chdir(p_ctx->cmount, ".."); if (status < 0) { berrno be; Jmsg(ctx, M_ERROR, "ceph_chdir(..) failed: %s\n", p_ctx->next_filename, be.bstrerror(-status)); return bRC_Error; } } } else { const char *cwd; cwd = ceph_getcwd(p_ctx->cmount); pm_strcpy(p_ctx->cwd, cwd); } } } /* * No link target and read the actual content. */ sp->link = NULL; sp->no_read = true; break; case FT_DIREND: /* * For a directory, link is the same as fname, but with trailing slash * and don't read the actual content. */ Mmsg(p_ctx->link_target, "%s/", p_ctx->next_filename); sp->link = p_ctx->link_target; sp->no_read = true; break; case FT_LNK: /* * Link target and don't read the actual content. */ sp->link = p_ctx->link_target; sp->no_read = true; break; case FT_REGE: case FT_REG: case FT_SPEC: case FT_RAW: case FT_FIFO: /* * No link target and read the actual content. */ sp->link = NULL; sp->no_read = false; break; default: /* * No link target and don't read the actual content. */ sp->link = NULL; sp->no_read = true; break; } sp->fname = p_ctx->next_filename; sp->type = p_ctx->type; memcpy(&sp->statp, &p_ctx->statp, sizeof(sp->statp)); sp->save_time = p_ctx->since; /* * For Incremental and Differential backups use checkChanges method to * see if we need to backup this file. */ switch (p_ctx->backup_level) { case L_INCREMENTAL: case L_DIFFERENTIAL: switch (bfuncs->checkChanges(ctx, sp)) { case bRC_Seen: Dmsg(ctx, dbglvl, "cephfs-fd: skipping %s checkChanges returns bRC_Seen\n", p_ctx->next_filename); switch (sp->type) { case FT_DIRBEGIN: case FT_DIREND: sp->type = FT_DIRNOCHG; break; default: sp->type = FT_NOCHG; break; } break; default: break; } } return bRC_OK; }