From 258f4727f17d184968106445cf521025a6a2f5fb Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Sun, 25 May 2008 14:57:43 +0000 Subject: [PATCH] Replace direct atomic operation for the file refcount witht the refcount interface. It also introduces the correct usage of memory barriers, as sometimes fdrop() and fhold() are used with shared locks, which don't use any release barrier. --- sys/kern/kern_descrip.c | 4 ++-- sys/sys/file.h | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index cbb76538893b..201d7ca4e02e 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1449,9 +1449,9 @@ falloc(struct thread *td, struct file **resultfp, int *resultfd) * descriptor to the list of open files at that point, otherwise * put it at the front of the list of open files. */ - fp->f_count = 1; + refcount_init(&fp->f_count, 1); if (resultfp) - fp->f_count++; + fhold(fp); fp->f_cred = crhold(td->td_ucred); fp->f_ops = &badfileops; fp->f_data = NULL; diff --git a/sys/sys/file.h b/sys/sys/file.h index e3fdd6027bcb..3b054404d6ac 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -39,6 +39,7 @@ #include #else #include +#include #include #include @@ -116,7 +117,7 @@ struct file { short f_type; /* descriptor type */ short f_vnread_flags; /* (f) Sleep lock for f_offset */ volatile u_int f_flag; /* see fcntl.h */ - volatile int f_count; /* reference count */ + volatile u_int f_count; /* reference count */ /* * DTYPE_VNODE specific fields. */ @@ -196,9 +197,10 @@ int fgetvp_write(struct thread *td, int fd, struct vnode **vpp); int fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp); void fputsock(struct socket *sp); -#define fhold(fp) atomic_add_int(&(fp)->f_count, 1) +#define fhold(fp) \ + (refcount_acquire(&(fp)->f_count)) #define fdrop(fp, td) \ - (atomic_fetchadd_int(&(fp)->f_count, -1) <= 1 ? _fdrop((fp), (td)) : 0) + (refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : 0) static __inline fo_rdwr_t fo_read; static __inline fo_rdwr_t fo_write;