mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 16:41:25 +00:00
[PATCH] f_count may wrap around
make it atomic_long_t; while we are at it, get rid of useless checks in affs, hfs and hpfs - ->open() always has it equal to 1, ->release() - to 0. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
3c333937ee
commit
516e0cc564
11 changed files with 27 additions and 39 deletions
|
@ -581,12 +581,12 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
if (file == ppp->owner)
|
if (file == ppp->owner)
|
||||||
ppp_shutdown_interface(ppp);
|
ppp_shutdown_interface(ppp);
|
||||||
}
|
}
|
||||||
if (atomic_read(&file->f_count) <= 2) {
|
if (atomic_long_read(&file->f_count) <= 2) {
|
||||||
ppp_release(NULL, file);
|
ppp_release(NULL, file);
|
||||||
err = 0;
|
err = 0;
|
||||||
} else
|
} else
|
||||||
printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%d\n",
|
printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%ld\n",
|
||||||
atomic_read(&file->f_count));
|
atomic_long_read(&file->f_count));
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,6 @@ const struct inode_operations affs_file_inode_operations = {
|
||||||
static int
|
static int
|
||||||
affs_file_open(struct inode *inode, struct file *filp)
|
affs_file_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
if (atomic_read(&filp->f_count) != 1)
|
|
||||||
return 0;
|
|
||||||
pr_debug("AFFS: open(%lu,%d)\n",
|
pr_debug("AFFS: open(%lu,%d)\n",
|
||||||
inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
|
inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
|
||||||
atomic_inc(&AFFS_I(inode)->i_opencnt);
|
atomic_inc(&AFFS_I(inode)->i_opencnt);
|
||||||
|
@ -57,8 +55,6 @@ affs_file_open(struct inode *inode, struct file *filp)
|
||||||
static int
|
static int
|
||||||
affs_file_release(struct inode *inode, struct file *filp)
|
affs_file_release(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
if (atomic_read(&filp->f_count) != 0)
|
|
||||||
return 0;
|
|
||||||
pr_debug("AFFS: release(%lu, %d)\n",
|
pr_debug("AFFS: release(%lu, %d)\n",
|
||||||
inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
|
inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
|
||||||
|
|
||||||
|
|
6
fs/aio.c
6
fs/aio.c
|
@ -512,8 +512,8 @@ static void aio_fput_routine(struct work_struct *data)
|
||||||
*/
|
*/
|
||||||
static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
|
static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
|
||||||
{
|
{
|
||||||
dprintk(KERN_DEBUG "aio_put(%p): f_count=%d\n",
|
dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n",
|
||||||
req, atomic_read(&req->ki_filp->f_count));
|
req, atomic_long_read(&req->ki_filp->f_count));
|
||||||
|
|
||||||
assert_spin_locked(&ctx->ctx_lock);
|
assert_spin_locked(&ctx->ctx_lock);
|
||||||
|
|
||||||
|
@ -528,7 +528,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
|
||||||
/* Must be done under the lock to serialise against cancellation.
|
/* Must be done under the lock to serialise against cancellation.
|
||||||
* Call this aio_fput as it duplicates fput via the fput_work.
|
* Call this aio_fput as it duplicates fput via the fput_work.
|
||||||
*/
|
*/
|
||||||
if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) {
|
if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) {
|
||||||
get_ioctx(ctx);
|
get_ioctx(ctx);
|
||||||
spin_lock(&fput_lock);
|
spin_lock(&fput_lock);
|
||||||
list_add(&req->ki_list, &fput_head);
|
list_add(&req->ki_list, &fput_head);
|
||||||
|
|
|
@ -120,7 +120,7 @@ struct file *get_empty_filp(void)
|
||||||
|
|
||||||
tsk = current;
|
tsk = current;
|
||||||
INIT_LIST_HEAD(&f->f_u.fu_list);
|
INIT_LIST_HEAD(&f->f_u.fu_list);
|
||||||
atomic_set(&f->f_count, 1);
|
atomic_long_set(&f->f_count, 1);
|
||||||
rwlock_init(&f->f_owner.lock);
|
rwlock_init(&f->f_owner.lock);
|
||||||
f->f_uid = tsk->fsuid;
|
f->f_uid = tsk->fsuid;
|
||||||
f->f_gid = tsk->fsgid;
|
f->f_gid = tsk->fsgid;
|
||||||
|
@ -219,7 +219,7 @@ EXPORT_SYMBOL(init_file);
|
||||||
|
|
||||||
void fput(struct file *file)
|
void fput(struct file *file)
|
||||||
{
|
{
|
||||||
if (atomic_dec_and_test(&file->f_count))
|
if (atomic_long_dec_and_test(&file->f_count))
|
||||||
__fput(file);
|
__fput(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ struct file *fget(unsigned int fd)
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
file = fcheck_files(files, fd);
|
file = fcheck_files(files, fd);
|
||||||
if (file) {
|
if (file) {
|
||||||
if (!atomic_inc_not_zero(&file->f_count)) {
|
if (!atomic_long_inc_not_zero(&file->f_count)) {
|
||||||
/* File object ref couldn't be taken */
|
/* File object ref couldn't be taken */
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -326,7 +326,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed)
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
file = fcheck_files(files, fd);
|
file = fcheck_files(files, fd);
|
||||||
if (file) {
|
if (file) {
|
||||||
if (atomic_inc_not_zero(&file->f_count))
|
if (atomic_long_inc_not_zero(&file->f_count))
|
||||||
*fput_needed = 1;
|
*fput_needed = 1;
|
||||||
else
|
else
|
||||||
/* Didn't get the reference, someone's freed */
|
/* Didn't get the reference, someone's freed */
|
||||||
|
@ -341,7 +341,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed)
|
||||||
|
|
||||||
void put_filp(struct file *file)
|
void put_filp(struct file *file)
|
||||||
{
|
{
|
||||||
if (atomic_dec_and_test(&file->f_count)) {
|
if (atomic_long_dec_and_test(&file->f_count)) {
|
||||||
security_file_free(file);
|
security_file_free(file);
|
||||||
file_kill(file);
|
file_kill(file);
|
||||||
file_free(file);
|
file_free(file);
|
||||||
|
|
|
@ -522,8 +522,6 @@ static int hfs_file_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
if (HFS_IS_RSRC(inode))
|
if (HFS_IS_RSRC(inode))
|
||||||
inode = HFS_I(inode)->rsrc_inode;
|
inode = HFS_I(inode)->rsrc_inode;
|
||||||
if (atomic_read(&file->f_count) != 1)
|
|
||||||
return 0;
|
|
||||||
atomic_inc(&HFS_I(inode)->opencnt);
|
atomic_inc(&HFS_I(inode)->opencnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -534,8 +532,6 @@ static int hfs_file_release(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
if (HFS_IS_RSRC(inode))
|
if (HFS_IS_RSRC(inode))
|
||||||
inode = HFS_I(inode)->rsrc_inode;
|
inode = HFS_I(inode)->rsrc_inode;
|
||||||
if (atomic_read(&file->f_count) != 0)
|
|
||||||
return 0;
|
|
||||||
if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
|
if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
|
||||||
mutex_lock(&inode->i_mutex);
|
mutex_lock(&inode->i_mutex);
|
||||||
hfs_file_truncate(inode);
|
hfs_file_truncate(inode);
|
||||||
|
|
|
@ -254,8 +254,6 @@ static int hfsplus_file_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
if (HFSPLUS_IS_RSRC(inode))
|
if (HFSPLUS_IS_RSRC(inode))
|
||||||
inode = HFSPLUS_I(inode).rsrc_inode;
|
inode = HFSPLUS_I(inode).rsrc_inode;
|
||||||
if (atomic_read(&file->f_count) != 1)
|
|
||||||
return 0;
|
|
||||||
atomic_inc(&HFSPLUS_I(inode).opencnt);
|
atomic_inc(&HFSPLUS_I(inode).opencnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -266,8 +264,6 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
if (HFSPLUS_IS_RSRC(inode))
|
if (HFSPLUS_IS_RSRC(inode))
|
||||||
inode = HFSPLUS_I(inode).rsrc_inode;
|
inode = HFSPLUS_I(inode).rsrc_inode;
|
||||||
if (atomic_read(&file->f_count) != 0)
|
|
||||||
return 0;
|
|
||||||
if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) {
|
if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) {
|
||||||
mutex_lock(&inode->i_mutex);
|
mutex_lock(&inode->i_mutex);
|
||||||
hfsplus_file_truncate(inode);
|
hfsplus_file_truncate(inode);
|
||||||
|
|
|
@ -795,7 +795,7 @@ struct file {
|
||||||
#define f_dentry f_path.dentry
|
#define f_dentry f_path.dentry
|
||||||
#define f_vfsmnt f_path.mnt
|
#define f_vfsmnt f_path.mnt
|
||||||
const struct file_operations *f_op;
|
const struct file_operations *f_op;
|
||||||
atomic_t f_count;
|
atomic_long_t f_count;
|
||||||
unsigned int f_flags;
|
unsigned int f_flags;
|
||||||
mode_t f_mode;
|
mode_t f_mode;
|
||||||
loff_t f_pos;
|
loff_t f_pos;
|
||||||
|
@ -824,8 +824,8 @@ extern spinlock_t files_lock;
|
||||||
#define file_list_lock() spin_lock(&files_lock);
|
#define file_list_lock() spin_lock(&files_lock);
|
||||||
#define file_list_unlock() spin_unlock(&files_lock);
|
#define file_list_unlock() spin_unlock(&files_lock);
|
||||||
|
|
||||||
#define get_file(x) atomic_inc(&(x)->f_count)
|
#define get_file(x) atomic_long_inc(&(x)->f_count)
|
||||||
#define file_count(x) atomic_read(&(x)->f_count)
|
#define file_count(x) atomic_long_read(&(x)->f_count)
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_WRITECOUNT
|
#ifdef CONFIG_DEBUG_WRITECOUNT
|
||||||
static inline void file_take_write(struct file *f)
|
static inline void file_take_write(struct file *f)
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct unix_sock {
|
||||||
struct sock *peer;
|
struct sock *peer;
|
||||||
struct sock *other;
|
struct sock *other;
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
atomic_t inflight;
|
atomic_long_t inflight;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
unsigned int gc_candidate : 1;
|
unsigned int gc_candidate : 1;
|
||||||
wait_queue_head_t peer_wait;
|
wait_queue_head_t peer_wait;
|
||||||
|
|
|
@ -162,7 +162,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
|
||||||
qdisc_destroy(flow->q);
|
qdisc_destroy(flow->q);
|
||||||
tcf_destroy_chain(&flow->filter_list);
|
tcf_destroy_chain(&flow->filter_list);
|
||||||
if (flow->sock) {
|
if (flow->sock) {
|
||||||
pr_debug("atm_tc_put: f_count %d\n",
|
pr_debug("atm_tc_put: f_count %ld\n",
|
||||||
file_count(flow->sock->file));
|
file_count(flow->sock->file));
|
||||||
flow->vcc->pop = flow->old_pop;
|
flow->vcc->pop = flow->old_pop;
|
||||||
sockfd_put(flow->sock);
|
sockfd_put(flow->sock);
|
||||||
|
@ -259,7 +259,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
|
||||||
sock = sockfd_lookup(fd, &error);
|
sock = sockfd_lookup(fd, &error);
|
||||||
if (!sock)
|
if (!sock)
|
||||||
return error; /* f_count++ */
|
return error; /* f_count++ */
|
||||||
pr_debug("atm_tc_change: f_count %d\n", file_count(sock->file));
|
pr_debug("atm_tc_change: f_count %ld\n", file_count(sock->file));
|
||||||
if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) {
|
if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) {
|
||||||
error = -EPROTOTYPE;
|
error = -EPROTOTYPE;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
|
@ -603,7 +603,7 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
|
||||||
u->dentry = NULL;
|
u->dentry = NULL;
|
||||||
u->mnt = NULL;
|
u->mnt = NULL;
|
||||||
spin_lock_init(&u->lock);
|
spin_lock_init(&u->lock);
|
||||||
atomic_set(&u->inflight, 0);
|
atomic_long_set(&u->inflight, 0);
|
||||||
INIT_LIST_HEAD(&u->link);
|
INIT_LIST_HEAD(&u->link);
|
||||||
mutex_init(&u->readlock); /* single task reading lock */
|
mutex_init(&u->readlock); /* single task reading lock */
|
||||||
init_waitqueue_head(&u->peer_wait);
|
init_waitqueue_head(&u->peer_wait);
|
||||||
|
|
|
@ -127,7 +127,7 @@ void unix_inflight(struct file *fp)
|
||||||
if(s) {
|
if(s) {
|
||||||
struct unix_sock *u = unix_sk(s);
|
struct unix_sock *u = unix_sk(s);
|
||||||
spin_lock(&unix_gc_lock);
|
spin_lock(&unix_gc_lock);
|
||||||
if (atomic_inc_return(&u->inflight) == 1) {
|
if (atomic_long_inc_return(&u->inflight) == 1) {
|
||||||
BUG_ON(!list_empty(&u->link));
|
BUG_ON(!list_empty(&u->link));
|
||||||
list_add_tail(&u->link, &gc_inflight_list);
|
list_add_tail(&u->link, &gc_inflight_list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -145,7 +145,7 @@ void unix_notinflight(struct file *fp)
|
||||||
struct unix_sock *u = unix_sk(s);
|
struct unix_sock *u = unix_sk(s);
|
||||||
spin_lock(&unix_gc_lock);
|
spin_lock(&unix_gc_lock);
|
||||||
BUG_ON(list_empty(&u->link));
|
BUG_ON(list_empty(&u->link));
|
||||||
if (atomic_dec_and_test(&u->inflight))
|
if (atomic_long_dec_and_test(&u->inflight))
|
||||||
list_del_init(&u->link);
|
list_del_init(&u->link);
|
||||||
unix_tot_inflight--;
|
unix_tot_inflight--;
|
||||||
spin_unlock(&unix_gc_lock);
|
spin_unlock(&unix_gc_lock);
|
||||||
|
@ -237,17 +237,17 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *),
|
||||||
|
|
||||||
static void dec_inflight(struct unix_sock *usk)
|
static void dec_inflight(struct unix_sock *usk)
|
||||||
{
|
{
|
||||||
atomic_dec(&usk->inflight);
|
atomic_long_dec(&usk->inflight);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inc_inflight(struct unix_sock *usk)
|
static void inc_inflight(struct unix_sock *usk)
|
||||||
{
|
{
|
||||||
atomic_inc(&usk->inflight);
|
atomic_long_inc(&usk->inflight);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inc_inflight_move_tail(struct unix_sock *u)
|
static void inc_inflight_move_tail(struct unix_sock *u)
|
||||||
{
|
{
|
||||||
atomic_inc(&u->inflight);
|
atomic_long_inc(&u->inflight);
|
||||||
/*
|
/*
|
||||||
* If this is still a candidate, move it to the end of the
|
* If this is still a candidate, move it to the end of the
|
||||||
* list, so that it's checked even if it was already passed
|
* list, so that it's checked even if it was already passed
|
||||||
|
@ -288,11 +288,11 @@ void unix_gc(void)
|
||||||
* before the detach without atomicity guarantees.
|
* before the detach without atomicity guarantees.
|
||||||
*/
|
*/
|
||||||
list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
|
list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
|
||||||
int total_refs;
|
long total_refs;
|
||||||
int inflight_refs;
|
long inflight_refs;
|
||||||
|
|
||||||
total_refs = file_count(u->sk.sk_socket->file);
|
total_refs = file_count(u->sk.sk_socket->file);
|
||||||
inflight_refs = atomic_read(&u->inflight);
|
inflight_refs = atomic_long_read(&u->inflight);
|
||||||
|
|
||||||
BUG_ON(inflight_refs < 1);
|
BUG_ON(inflight_refs < 1);
|
||||||
BUG_ON(total_refs < inflight_refs);
|
BUG_ON(total_refs < inflight_refs);
|
||||||
|
@ -324,7 +324,7 @@ void unix_gc(void)
|
||||||
/* Move cursor to after the current position. */
|
/* Move cursor to after the current position. */
|
||||||
list_move(&cursor, &u->link);
|
list_move(&cursor, &u->link);
|
||||||
|
|
||||||
if (atomic_read(&u->inflight) > 0) {
|
if (atomic_long_read(&u->inflight) > 0) {
|
||||||
list_move_tail(&u->link, &gc_inflight_list);
|
list_move_tail(&u->link, &gc_inflight_list);
|
||||||
u->gc_candidate = 0;
|
u->gc_candidate = 0;
|
||||||
scan_children(&u->sk, inc_inflight_move_tail, NULL);
|
scan_children(&u->sk, inc_inflight_move_tail, NULL);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue