cmogstored 1.8.1 - use default system stack size
[cmogstored.git] / file.c
blob855ed69395f15c596b88ffb99063262880d031ba
1 /*
2 * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
3 * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
4 */
5 #include "cmogstored.h"
6 #include "digest.h"
8 bool mog_open_expire_retry(struct mog_svc *svc)
10 switch (errno) {
11 case ENFILE:
12 case EMFILE:
13 case ENOMEM:
14 if (mog_fdmap_expire(svc->idle_timeout) > 0)
15 return true;
17 return false;
20 static struct mog_fd *mog_file_init_common(int fd, struct mog_svc *svc)
22 struct mog_fd *mfd = mog_fd_init(fd, MOG_FD_TYPE_FILE);
23 struct mog_file *file;
25 file = &mfd->as.file;
26 memset(file, 0, sizeof(struct mog_file));
27 file->svc = svc;
28 file->ioq = mog_ioq_current;
30 return mfd;
33 /* path must be a free()-able pointer */
34 struct mog_fd *
35 mog_file_open_read(struct mog_svc *svc, char *path)
37 struct mog_fd *mfd;
38 int fd = mog_open_read(svc, path);
40 if (fd < 0 && mog_open_expire_retry(svc))
41 fd = mog_open_read(svc, path);
43 if (fd < 0) return NULL;
45 mfd = mog_file_init_common(fd, svc);
46 mfd->as.file.fsize = -1;
48 return mfd;
51 static int mkpath_open_put(struct mog_svc *svc, char *path, int flags)
53 int fd = mog_open_put(svc, path, flags);
55 if (fd < 0 && errno == ENOENT) {
56 /* directory does not exist, create it and retry open */
57 if (mog_mkpath_for(svc, path) == 0)
58 return mog_open_put(svc, path, flags);
60 syslog(LOG_ERR, "failed to create directory for path=%s (%m)",
61 path);
62 errno = ENOENT; /* restore open() errno */
65 return fd;
68 /* path must be a free()-able pointer */
69 struct mog_fd *
70 mog_file_open_put(struct mog_svc *svc, char *path, int flags)
72 int fd = mkpath_open_put(svc, path, flags);
74 if (fd < 0 && mog_open_expire_retry(svc))
75 fd = mkpath_open_put(svc, path, flags);
77 if (fd < 0) return NULL;
79 return mog_file_init_common(fd, svc);
82 void mog_file_close(struct mog_fd *mfd)
84 struct mog_file *mfile = &mfd->as.file;
85 struct mog_ioq *ioq;
87 assert(mfd->fd_type == MOG_FD_TYPE_FILE && "mog_fd is not a file");
89 /* all of these may already be NULL */
90 free(mfile->path);
91 free(mfile->tmppath);
92 mog_digest_destroy(&mfile->digest);
94 ioq = mfile->ioq;
95 mog_fd_put(mfd);
96 mog_ioq_next(ioq);