diff options
-rw-r--r-- | booster/src/booster-fd.c | 47 | ||||
-rw-r--r-- | booster/src/booster-fd.h | 17 | ||||
-rw-r--r-- | booster/src/booster.c | 26 |
3 files changed, 85 insertions, 5 deletions
diff --git a/booster/src/booster-fd.c b/booster/src/booster-fd.c index ef6f728aa4c..8df9fd51c66 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 a8708523398..dd6d00d5c97 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 450f24c6bfe..d767465985d 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: |