Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 223588
b: refs/heads/master
c: 39c99f1
h: refs/heads/master
v: v3
  • Loading branch information
Tristan Ye authored and Joel Becker committed Dec 9, 2010
1 parent a0a981d commit a71ea9a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 388c4bcb4e63e88fb1f312a2f5f9eb2623afcf5b
refs/heads/master: 39c99f12f15c8bf8257985d9b2a2548a03d18c00
7 changes: 5 additions & 2 deletions trunk/fs/ocfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,11 +573,14 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
/* this io's submitter should not have unlocked this before we could */
BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));

if (ocfs2_iocb_is_sem_locked(iocb)) {
up_read(&inode->i_alloc_sem);
ocfs2_iocb_clear_sem_locked(iocb);
}

ocfs2_iocb_clear_rw_locked(iocb);

level = ocfs2_iocb_rw_locked_level(iocb);
if (!level)
up_read(&inode->i_alloc_sem);
ocfs2_rw_unlock(inode, level);

if (is_async)
Expand Down
23 changes: 21 additions & 2 deletions trunk/fs/ocfs2/aops.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,27 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level)
else
clear_bit(1, (unsigned long *)&iocb->private);
}

/*
* Using a named enum representing lock types in terms of #N bit stored in
* iocb->private, which is going to be used for communication bewteen
* ocfs2_dio_end_io() and ocfs2_file_aio_write/read().
*/
enum ocfs2_iocb_lock_bits {
OCFS2_IOCB_RW_LOCK = 0,
OCFS2_IOCB_RW_LOCK_LEVEL,
OCFS2_IOCB_SEM,
OCFS2_IOCB_NUM_LOCKS
};

#define ocfs2_iocb_clear_rw_locked(iocb) \
clear_bit(0, (unsigned long *)&iocb->private)
clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)
#define ocfs2_iocb_rw_locked_level(iocb) \
test_bit(1, (unsigned long *)&iocb->private)
test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private)
#define ocfs2_iocb_set_sem_locked(iocb) \
set_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
#define ocfs2_iocb_clear_sem_locked(iocb) \
clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
#define ocfs2_iocb_is_sem_locked(iocb) \
test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
#endif /* OCFS2_FILE_H */
15 changes: 13 additions & 2 deletions trunk/fs/ocfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2241,11 +2241,15 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,

mutex_lock(&inode->i_mutex);

ocfs2_iocb_clear_sem_locked(iocb);

relock:
/* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */
if (direct_io) {
down_read(&inode->i_alloc_sem);
have_alloc_sem = 1;
/* communicate with ocfs2_dio_end_io */
ocfs2_iocb_set_sem_locked(iocb);
}

/*
Expand Down Expand Up @@ -2382,8 +2386,10 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
ocfs2_rw_unlock(inode, rw_level);

out_sems:
if (have_alloc_sem)
if (have_alloc_sem) {
up_read(&inode->i_alloc_sem);
ocfs2_iocb_clear_sem_locked(iocb);
}

mutex_unlock(&inode->i_mutex);

Expand Down Expand Up @@ -2527,13 +2533,16 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
goto bail;
}

ocfs2_iocb_clear_sem_locked(iocb);

/*
* buffered reads protect themselves in ->readpage(). O_DIRECT reads
* need locks to protect pending reads from racing with truncate.
*/
if (filp->f_flags & O_DIRECT) {
down_read(&inode->i_alloc_sem);
have_alloc_sem = 1;
ocfs2_iocb_set_sem_locked(iocb);

ret = ocfs2_rw_lock(inode, 0);
if (ret < 0) {
Expand Down Expand Up @@ -2575,8 +2584,10 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
}

bail:
if (have_alloc_sem)
if (have_alloc_sem) {
up_read(&inode->i_alloc_sem);
ocfs2_iocb_clear_sem_locked(iocb);
}
if (rw_level != -1)
ocfs2_rw_unlock(inode, rw_level);
mlog_exit(ret);
Expand Down

0 comments on commit a71ea9a

Please sign in to comment.