X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=libsysio%2Fsrc%2Ffile.c;h=9ed054ed27f19343603c5baff7fe675da8a84c09;hb=0c7b880305305499dd75524bd2a45765029ddf43;hp=8d2c3a8880d4c3821e1e9faae24c75cb7ca9e621;hpb=b8292c00324fbe9a25910ce53d03569186ea3e2c;p=fs%2Flustre-release.git diff --git a/libsysio/src/file.c b/libsysio/src/file.c index 8d2c3a8..9ed054e 100644 --- a/libsysio/src/file.c +++ b/libsysio/src/file.c @@ -45,12 +45,12 @@ #include #include #include +#include #include #include "sysio.h" #include "file.h" #include "inode.h" -#include "xtio.h" /* * Support for file IO. @@ -75,7 +75,8 @@ _sysio_fnew(struct inode *ino, int flags) return NULL; _SYSIO_FINIT(fil, ino, flags); - I_REF(ino); + F_REF(fil); + I_REF(fil->f_ino); return fil; } @@ -92,6 +93,7 @@ _sysio_fgone(struct file *fil) assert(fil->f_ino); err = (*fil->f_ino->i_ops.inop_close)(fil->f_ino); assert(!err); + I_RELE(fil->f_ino); free(fil); } @@ -119,29 +121,27 @@ _sysio_fcompletio(struct ioctx *ioctx, struct file *fil) static int fd_grow(size_t n) { - int fd; size_t count; struct file **noftab, **filp; /* * Sanity check the new size. */ - fd = (int )n; - if ((size_t )fd != n) + if ((int )n < 0) return -EMFILE; - if (n < 8) - n = 8; - if (n >= _sysio_oftab_size && n - _sysio_oftab_size < _sysio_oftab_size) - n = (n + 1) * 2; + /* + * We never shrink the table. + */ + if (n <= _sysio_oftab_size) + return 0; + noftab = realloc(_sysio_oftab, n * sizeof(struct file *)); if (!noftab) return -ENOMEM; _sysio_oftab = noftab; count = _sysio_oftab_size; _sysio_oftab_size = n; - if (n < count) - return 0; filp = _sysio_oftab + count; n -= count; while (n--) @@ -149,7 +149,7 @@ fd_grow(size_t n) return 0; } -#if ZERO_SUM_MEMORY +#ifdef ZERO_SUM_MEMORY void _sysio_fd_shutdown() { @@ -160,21 +160,24 @@ _sysio_fd_shutdown() #endif /* - * Find a free slot in the open files table. + * Find a free slot in the open files table greater than or equal to the + * argument. */ static int -find_free_fildes() +find_free_fildes(int low) { - size_t n; + int n; int err; struct file **filp; - for (n = 0, filp = _sysio_oftab; - n < _sysio_oftab_size && *filp; + for (n = low, filp = _sysio_oftab + low; + n >= 0 && (unsigned )n < _sysio_oftab_size && *filp; n++, filp++) ; - if (n >= _sysio_oftab_size) { - err = fd_grow(n); + if (n < 0) + return -ENFILE; + if ((unsigned )n >= _sysio_oftab_size) { + err = fd_grow((unsigned )n + 1); if (err) return err; filp = &_sysio_oftab[n]; @@ -216,26 +219,29 @@ _sysio_fd_close(int fd) } /* - * Associate open file record with given file descriptor or any available - * file descriptor if less than zero. + * Associate open file record with given file descriptor (if forced), or any + * available file descriptor if less than zero, or any available descriptor + * greater than or equal to the given one if not forced. */ int -_sysio_fd_set(struct file *fil, int fd) +_sysio_fd_set(struct file *fil, int fd, int force) { int err; struct file *ofil; /* - * New fd < 0 => any available descriptor. + * Search for a free descriptor if needed. */ - if (fd < 0) { - fd = find_free_fildes(); + if (fd < 0 || !force) { + if (fd < 0) + fd = 0; + fd = find_free_fildes(fd); if (fd < 0) return fd; } if ((unsigned )fd >= _sysio_oftab_size) { - err = fd_grow(fd); + err = fd_grow((unsigned )fd + 1); if (err) return err; } @@ -258,22 +264,24 @@ _sysio_fd_set(struct file *fil, int fd) * Duplicate old file descriptor. * * If the new file descriptor is less than zero, the new file descriptor - * is chosen freely. + * is chosen freely. Otherwise, choose an available descriptor greater + * than or equal to the new, if not forced. Otherwise, if forced, (re)use + * the new. */ int -_sysio_fd_dup2(int oldfd, int newfd) +_sysio_fd_dup(int oldfd, int newfd, int force) { struct file *fil; int fd; - if (oldfd == newfd) - return 0; + if (oldfd == newfd && oldfd >= 0) + return newfd; fil = _sysio_fd_find(oldfd); if (!fil) return -EBADF; - fd = _sysio_fd_set(fil, newfd); + fd = _sysio_fd_set(fil, newfd, force); if (fd >= 0) F_REF(fil); return fd;