Changeset View
Changeset View
Standalone View
Standalone View
stand/libsa/close.c
Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "stand.h" | #include "stand.h" | ||||
int | int | ||||
close(int fd) | close(int fd) | ||||
{ | { | ||||
struct open_file *f = &files[fd]; | struct open_file *f, *last; | ||||
int err1 = 0, err2 = 0; | int err1 = 0, err2 = 0; | ||||
if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) { | f = fd2open_file(fd); | ||||
if (f == NULL) { | |||||
imp: This should be a function fd2open_file(fd) or something. It's repeated a lot.
| |||||
errno = EBADF; | errno = EBADF; | ||||
return (-1); | return (-1); | ||||
} | } | ||||
free(f->f_rabuf); | free(f->f_rabuf); | ||||
f->f_rabuf = NULL; | f->f_rabuf = NULL; | ||||
if (f->f_flags != 0) { | |||||
if (!(f->f_flags & F_RAW) && f->f_ops) | if (!(f->f_flags & F_RAW) && f->f_ops) | ||||
err1 = (f->f_ops->fo_close)(f); | err1 = (f->f_ops->fo_close)(f); | ||||
if (!(f->f_flags & F_NODEV) && f->f_dev) | if (!(f->f_flags & F_NODEV) && f->f_dev) | ||||
err2 = (f->f_dev->dv_close)(f); | err2 = (f->f_dev->dv_close)(f); | ||||
if (f->f_devdata != NULL) | if (f->f_devdata != NULL) | ||||
devclose(f); | devclose(f); | ||||
f->f_flags = 0; | f->f_flags = 0; | ||||
} else { | |||||
/* Attempt to close already closed file. */ | |||||
err1 = EBADF; | |||||
} | |||||
/* free unused entries from tail. */ | |||||
Done Inline Actionswhy do you free them only from the tail? imp: why do you free them only from the tail? | |||||
Done Inline ActionsThe reason is actually pretty simple. We do need unique ID for files (and sockets). If we switch to use list, we have three alternates:
I did pick first option because in most cases, the fd is really short lived and with one exception, we practically do not keep multiple files open. This one exception is zfs pools - pools are discovered, and "imported", with disk devices kept open and practically never closed... tsoome: The reason is actually pretty simple. We do need unique ID for files (and sockets). If we… | |||||
Done Inline Actionscomment added to open.c tsoome: comment added to open.c | |||||
TAILQ_FOREACH_REVERSE_SAFE(last, &files, file_list, f_link, f) { | |||||
if (last->f_flags != 0) | |||||
break; | |||||
TAILQ_REMOVE(&files, last, f_link); | |||||
free(last); | |||||
} | |||||
if (err1) { | if (err1) { | ||||
errno = err1; | errno = err1; | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (err2) { | if (err2) { | ||||
errno = err2; | errno = err2; | ||||
return (-1); | return (-1); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } |
This should be a function fd2open_file(fd) or something. It's repeated a lot.