|
|
|
@ -353,6 +353,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
|
|
|
|
|
stat_cache_entry *sce = NULL;
|
|
|
|
|
stat_cache *sc;
|
|
|
|
|
struct stat st;
|
|
|
|
|
size_t k;
|
|
|
|
|
#ifdef DEBUG_STAT_CACHE
|
|
|
|
|
size_t i;
|
|
|
|
|
#endif
|
|
|
|
@ -456,125 +457,121 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) {
|
|
|
|
|
size_t k;
|
|
|
|
|
|
|
|
|
|
if (S_ISREG(st.st_mode)) {
|
|
|
|
|
int fd;
|
|
|
|
|
/* see if we can open the file for reading */
|
|
|
|
|
if (-1 == (fd = open(name->ptr, O_RDONLY))) {
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
close(fd);
|
|
|
|
|
if (S_ISREG(st.st_mode)) {
|
|
|
|
|
int fd;
|
|
|
|
|
/* see if we can open the file for reading */
|
|
|
|
|
if (-1 == (fd = open(name->ptr, O_RDONLY))) {
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL == sce) {
|
|
|
|
|
int osize = 0;
|
|
|
|
|
if (NULL == sce) {
|
|
|
|
|
int osize = 0;
|
|
|
|
|
|
|
|
|
|
if (sc->files) {
|
|
|
|
|
osize = sc->files->size;
|
|
|
|
|
}
|
|
|
|
|
if (sc->files) {
|
|
|
|
|
osize = sc->files->size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sce = stat_cache_entry_init();
|
|
|
|
|
buffer_copy_string_buffer(sce->name, name);
|
|
|
|
|
|
|
|
|
|
sc->files = splaytree_insert(sc->files, file_ndx, sce);
|
|
|
|
|
sce = stat_cache_entry_init();
|
|
|
|
|
buffer_copy_string_buffer(sce->name, name);
|
|
|
|
|
|
|
|
|
|
sc->files = splaytree_insert(sc->files, file_ndx, sce);
|
|
|
|
|
#ifdef DEBUG_STAT_CACHE
|
|
|
|
|
if (ctrl.size == 0) {
|
|
|
|
|
ctrl.size = 16;
|
|
|
|
|
ctrl.used = 0;
|
|
|
|
|
ctrl.ptr = malloc(ctrl.size * sizeof(*ctrl.ptr));
|
|
|
|
|
} else if (ctrl.size == ctrl.used) {
|
|
|
|
|
ctrl.size += 16;
|
|
|
|
|
ctrl.ptr = realloc(ctrl.ptr, ctrl.size * sizeof(*ctrl.ptr));
|
|
|
|
|
}
|
|
|
|
|
if (ctrl.size == 0) {
|
|
|
|
|
ctrl.size = 16;
|
|
|
|
|
ctrl.used = 0;
|
|
|
|
|
ctrl.ptr = malloc(ctrl.size * sizeof(*ctrl.ptr));
|
|
|
|
|
} else if (ctrl.size == ctrl.used) {
|
|
|
|
|
ctrl.size += 16;
|
|
|
|
|
ctrl.ptr = realloc(ctrl.ptr, ctrl.size * sizeof(*ctrl.ptr));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctrl.ptr[ctrl.used++] = file_ndx;
|
|
|
|
|
ctrl.ptr[ctrl.used++] = file_ndx;
|
|
|
|
|
|
|
|
|
|
assert(sc->files);
|
|
|
|
|
assert(sc->files->data == sce);
|
|
|
|
|
assert(osize + 1 == splaytree_size(sc->files));
|
|
|
|
|
assert(sc->files);
|
|
|
|
|
assert(sc->files->data == sce);
|
|
|
|
|
assert(osize + 1 == splaytree_size(sc->files));
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sce->st = st;
|
|
|
|
|
sce->stat_ts = srv->cur_ts;
|
|
|
|
|
sce->st = st;
|
|
|
|
|
sce->stat_ts = srv->cur_ts;
|
|
|
|
|
|
|
|
|
|
if (S_ISREG(st.st_mode)) {
|
|
|
|
|
/* determine mimetype */
|
|
|
|
|
buffer_reset(sce->content_type);
|
|
|
|
|
if (S_ISREG(st.st_mode)) {
|
|
|
|
|
/* determine mimetype */
|
|
|
|
|
buffer_reset(sce->content_type);
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < con->conf.mimetypes->used; k++) {
|
|
|
|
|
data_string *ds = (data_string *)con->conf.mimetypes->data[k];
|
|
|
|
|
buffer *type = ds->key;
|
|
|
|
|
|
|
|
|
|
if (type->used == 0) continue;
|
|
|
|
|
for (k = 0; k < con->conf.mimetypes->used; k++) {
|
|
|
|
|
data_string *ds = (data_string *)con->conf.mimetypes->data[k];
|
|
|
|
|
buffer *type = ds->key;
|
|
|
|
|
|
|
|
|
|
if (type->used == 0) continue;
|
|
|
|
|
|
|
|
|
|
/* check if the right side is the same */
|
|
|
|
|
if (type->used > name->used) continue;
|
|
|
|
|
/* check if the right side is the same */
|
|
|
|
|
if (type->used > name->used) continue;
|
|
|
|
|
|
|
|
|
|
if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
|
|
|
|
|
buffer_copy_string_buffer(sce->content_type, ds->value);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
|
|
|
|
|
buffer_copy_string_buffer(sce->content_type, ds->value);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
etag_create(sce->etag, &(sce->st));
|
|
|
|
|
}
|
|
|
|
|
etag_create(sce->etag, &(sce->st));
|
|
|
|
|
#ifdef HAVE_XATTR
|
|
|
|
|
if (buffer_is_empty(sce->content_type)) {
|
|
|
|
|
stat_cache_attr_get(sce->content_type, name->ptr);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (buffer_is_empty(sce->content_type)) {
|
|
|
|
|
stat_cache_attr_get(sce->content_type, name->ptr);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_FAM_H
|
|
|
|
|
if (sc->fam &&
|
|
|
|
|
(srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) {
|
|
|
|
|
/* is this directory already registered ? */
|
|
|
|
|
if (!dir_node) {
|
|
|
|
|
fam_dir = fam_dir_entry_init();
|
|
|
|
|
fam_dir->fc = sc->fam;
|
|
|
|
|
|
|
|
|
|
buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
|
|
|
|
|
|
|
|
|
|
fam_dir->version = 1;
|
|
|
|
|
if (sc->fam &&
|
|
|
|
|
(srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) {
|
|
|
|
|
/* is this directory already registered ? */
|
|
|
|
|
if (!dir_node) {
|
|
|
|
|
fam_dir = fam_dir_entry_init();
|
|
|
|
|
fam_dir->fc = sc->fam;
|
|
|
|
|
|
|
|
|
|
buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
|
|
|
|
|
|
|
|
|
|
fam_dir->version = 1;
|
|
|
|
|
|
|
|
|
|
fam_dir->req = calloc(1, sizeof(FAMRequest));
|
|
|
|
|
|
|
|
|
|
if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr,
|
|
|
|
|
fam_dir->req, fam_dir)) {
|
|
|
|
|
|
|
|
|
|
fam_dir->req = calloc(1, sizeof(FAMRequest));
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbs",
|
|
|
|
|
"monitoring dir failed:",
|
|
|
|
|
fam_dir->name,
|
|
|
|
|
FamErrlist[FAMErrno]);
|
|
|
|
|
|
|
|
|
|
if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr,
|
|
|
|
|
fam_dir->req, fam_dir)) {
|
|
|
|
|
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbs",
|
|
|
|
|
"monitoring dir failed:",
|
|
|
|
|
fam_dir->name,
|
|
|
|
|
FamErrlist[FAMErrno]);
|
|
|
|
|
|
|
|
|
|
fam_dir_entry_free(fam_dir);
|
|
|
|
|
} else {
|
|
|
|
|
int osize = 0;
|
|
|
|
|
|
|
|
|
|
if (sc->dirs) {
|
|
|
|
|
osize = sc->dirs->size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir);
|
|
|
|
|
assert(sc->dirs);
|
|
|
|
|
assert(sc->dirs->data == fam_dir);
|
|
|
|
|
assert(osize == (sc->dirs->size - 1));
|
|
|
|
|
}
|
|
|
|
|
fam_dir_entry_free(fam_dir);
|
|
|
|
|
} else {
|
|
|
|
|
fam_dir = dir_node->data;
|
|
|
|
|
int osize = 0;
|
|
|
|
|
|
|
|
|
|
if (sc->dirs) {
|
|
|
|
|
osize = sc->dirs->size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir);
|
|
|
|
|
assert(sc->dirs);
|
|
|
|
|
assert(sc->dirs->data == fam_dir);
|
|
|
|
|
assert(osize == (sc->dirs->size - 1));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
fam_dir = dir_node->data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* bind the fam_fc to the stat() cache entry */
|
|
|
|
|
|
|
|
|
|
/* bind the fam_fc to the stat() cache entry */
|
|
|
|
|
|
|
|
|
|
if (fam_dir) {
|
|
|
|
|
sce->dir_version = fam_dir->version;
|
|
|
|
|
sce->dir_ndx = dir_ndx;
|
|
|
|
|
}
|
|
|
|
|
if (fam_dir) {
|
|
|
|
|
sce->dir_version = fam_dir->version;
|
|
|
|
|
sce->dir_ndx = dir_ndx;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
*ret_sce = sce;
|
|
|
|
|
|
|
|
|
|
return HANDLER_GO_ON;
|
|
|
|
|