summaryrefslogtreecommitdiffstats
path: root/booster
diff options
context:
space:
mode:
Diffstat (limited to 'booster')
-rw-r--r--booster/src/booster-fd.c47
-rw-r--r--booster/src/booster-fd.h17
-rw-r--r--booster/src/booster.c26
3 files changed, 85 insertions, 5 deletions
diff --git a/booster/src/booster-fd.c b/booster/src/booster-fd.c
index ef6f728aa4..8df9fd51c6 100644
--- a/booster/src/booster-fd.c
+++ b/booster/src/booster-fd.c
@@ -54,13 +54,34 @@ gf_roundup_power_of_two (uint nr)
return result;
}
+#define BOOSTER_NFDBITS (sizeof (unsigned long))
+
+#define BOOSTER_FDMASK(d) (1UL << ((d) % BOOSTER_NFDBITS))
+#define BOOSTER_FDELT(d) (d / BOOSTER_NFDBITS)
+#define BOOSTER_FD_SET(set, d) (set->fd_bits[BOOSTER_FDELT(d)] |= BOOSTER_FDMASK(d))
+#define BOOSTER_FD_CLR(set, d) (set->fd_bits[BOOSTER_FDELT(d)] &= ~BOOSTER_FDMASK(d))
+#define BOOSTER_FD_ISSET(set, d) (set->fd_bits[BOOSTER_FDELT(d)] & BOOSTER_FDMASK(d))
+
+inline int
+booster_get_close_on_exec (booster_fdtable_t *fdtable, int fd)
+{
+ return BOOSTER_FD_ISSET(fdtable->close_on_exec, fd);
+}
+
+inline void
+booster_set_close_on_exec (booster_fdtable_t *fdtable, int fd)
+{
+ BOOSTER_FD_SET(fdtable->close_on_exec, fd);
+}
+
int
booster_fdtable_expand (booster_fdtable_t *fdtable, uint nr)
{
- fd_t **oldfds = NULL;
+ fd_t **oldfds = NULL, **tmp = NULL;
uint oldmax_fds = -1;
uint cpy = 0;
- int32_t ret = -1;
+ int32_t ret = -1, bytes = 0;
+ booster_fd_set_t *oldclose_on_exec = NULL;
if (fdtable == NULL || nr < 0) {
gf_log ("booster-fd", GF_LOG_ERROR, "Invalid argument");
@@ -75,6 +96,7 @@ booster_fdtable_expand (booster_fdtable_t *fdtable, uint nr)
oldfds = fdtable->fds;
oldmax_fds = fdtable->max_fds;
+ oldclose_on_exec = fdtable->close_on_exec;
fdtable->fds = CALLOC (nr, sizeof (fd_t *));
if (fdtable->fds == NULL) {
@@ -92,11 +114,32 @@ booster_fdtable_expand (booster_fdtable_t *fdtable, uint nr)
memcpy (fdtable->fds, oldfds, cpy);
}
+ /* nr will be either less than 8 or a multiple of 8 */
+ bytes = nr/8;
+ bytes = bytes ? bytes : 1;
+ fdtable->close_on_exec = CALLOC (bytes, 1);
+ if (fdtable->close_on_exec == NULL) {
+ gf_log ("booster-fd", GF_LOG_ERROR, "Memory allocation "
+ "failed");
+ tmp = fdtable->fds;
+ fdtable->fds = oldfds;
+ oldfds = tmp;
+ ret = -1;
+ goto out;
+ }
+
+ if (oldclose_on_exec != NULL) {
+ bytes = oldmax_fds/8;
+ cpy = bytes ? bytes : 1;
+ memcpy (fdtable->close_on_exec, oldclose_on_exec, cpy);
+ }
gf_log ("booster-fd", GF_LOG_TRACE, "FD-table expanded: Old: %d,New: %d"
, oldmax_fds, nr);
ret = 0;
+
out:
FREE (oldfds);
+ FREE (oldclose_on_exec);
return ret;
}
diff --git a/booster/src/booster-fd.h b/booster/src/booster-fd.h
index a870852339..dd6d00d5c9 100644
--- a/booster/src/booster-fd.h
+++ b/booster/src/booster-fd.h
@@ -43,15 +43,26 @@ struct _fd {
};
typedef struct _fd fd_t;
+struct _booster_fd_set {
+ unsigned long fd_bits[0];
+};
+typedef struct _booster_fd_set booster_fd_set_t;
struct _booster_fdtable {
- int refcount;
- unsigned int max_fds;
- gf_lock_t lock;
+ booster_fd_set_t *close_on_exec;
+ int refcount;
+ unsigned int max_fds;
+ gf_lock_t lock;
fd_t **fds;
};
typedef struct _booster_fdtable booster_fdtable_t;
+void
+booster_set_close_on_exec (booster_fdtable_t *fdtable, int fd);
+
+int
+booster_get_close_on_exec (booster_fdtable_t *fdtable, int fd);
+
extern int
booster_fd_unused_get (booster_fdtable_t *fdtable, fd_t *fdptr, int fd);
diff --git a/booster/src/booster.c b/booster/src/booster.c
index 450f24c6bf..d767465985 100644
--- a/booster/src/booster.c
+++ b/booster/src/booster.c
@@ -2692,6 +2692,19 @@ fcntl (int fd, int cmd, ...)
*/
/* case F_DUPFD_CLOEXEC: */
case F_GETFD:
+ if (glfs_fd != NULL) {
+ ret = booster_get_close_on_exec (booster_fdtable, fd)
+ ? FD_CLOEXEC : 0;
+ } else {
+ if (real_fcntl == NULL) {
+ ret = -1;
+ errno = ENOSYS;
+ } else {
+ ret = real_fcntl (fd, cmd);
+ }
+ }
+ break;
+
case F_GETFL:
case F_GETOWN:
case F_GETSIG:
@@ -2711,6 +2724,19 @@ fcntl (int fd, int cmd, ...)
break;
case F_SETFD:
+ if (glfs_fd != NULL) {
+ booster_set_close_on_exec (booster_fdtable, fd);
+ ret = 0;
+ } else {
+ if (real_fcntl == NULL) {
+ ret = -1;
+ errno = ENOSYS;
+ } else {
+ ret = real_fcntl (fd, cmd);
+ }
+ }
+ break;
+
case F_SETFL:
case F_SETOWN:
case F_SETSIG: