Merge git://oss.sgi.com:8090/xfs/xfs-2.6
* git://oss.sgi.com:8090/xfs/xfs-2.6: [XFS] Add lockdep support for XFS [XFS] Fix race in xfs_write() b/w dmapi callout and direct I/O checks. [XFS] Get rid of redundant "required" in msg. [XFS] Export via a function xfs_buftarg_list for use by kdb/xfsidbg. [XFS] Remove unused ilen variable and references. [XFS] Fix to prevent the notorious 'NULL files' problem after a crash. [XFS] Fix race condition in xfs_write(). [XFS] Fix uquota and oquota enforcement problems. [XFS] propogate return codes from flush routines [XFS] Fix quotaon syscall failures for group enforcement requests. [XFS] Invalidate quotacheck when mounting without a quota type. [XFS] reducing the number of random number functions. [XFS] remove more misc. unused args [XFS] the "aendp" arg to xfs_dir2_data_freescan is always NULL, remove it. [XFS] The last argument "lsn" of xfs_trans_commit() is always called with
This commit is contained in:
commit
60c9b2746f
@ -43,6 +43,18 @@ static inline void mrupdate(mrlock_t *mrp)
|
||||
mrp->mr_writer = 1;
|
||||
}
|
||||
|
||||
static inline void mraccess_nested(mrlock_t *mrp, int subclass)
|
||||
{
|
||||
down_read_nested(&mrp->mr_lock, subclass);
|
||||
}
|
||||
|
||||
static inline void mrupdate_nested(mrlock_t *mrp, int subclass)
|
||||
{
|
||||
down_write_nested(&mrp->mr_lock, subclass);
|
||||
mrp->mr_writer = 1;
|
||||
}
|
||||
|
||||
|
||||
static inline int mrtryaccess(mrlock_t *mrp)
|
||||
{
|
||||
return down_read_trylock(&mrp->mr_lock);
|
||||
|
@ -140,10 +140,47 @@ xfs_destroy_ioend(
|
||||
mempool_free(ioend, xfs_ioend_pool);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update on-disk file size now that data has been written to disk.
|
||||
* The current in-memory file size is i_size. If a write is beyond
|
||||
* eof io_new_size will be the intended file size until i_size is
|
||||
* updated. If this write does not extend all the way to the valid
|
||||
* file size then restrict this update to the end of the write.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_setfilesize(
|
||||
xfs_ioend_t *ioend)
|
||||
{
|
||||
xfs_inode_t *ip;
|
||||
xfs_fsize_t isize;
|
||||
xfs_fsize_t bsize;
|
||||
|
||||
ip = xfs_vtoi(ioend->io_vnode);
|
||||
|
||||
ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
|
||||
ASSERT(ioend->io_type != IOMAP_READ);
|
||||
|
||||
if (unlikely(ioend->io_error))
|
||||
return;
|
||||
|
||||
bsize = ioend->io_offset + ioend->io_size;
|
||||
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
|
||||
isize = MAX(ip->i_size, ip->i_iocore.io_new_size);
|
||||
isize = MIN(isize, bsize);
|
||||
|
||||
if (ip->i_d.di_size < isize) {
|
||||
ip->i_d.di_size = isize;
|
||||
ip->i_update_core = 1;
|
||||
ip->i_update_size = 1;
|
||||
}
|
||||
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Buffered IO write completion for delayed allocate extents.
|
||||
* TODO: Update ondisk isize now that we know the file data
|
||||
* has been flushed (i.e. the notorious "NULL file" problem).
|
||||
*/
|
||||
STATIC void
|
||||
xfs_end_bio_delalloc(
|
||||
@ -152,6 +189,7 @@ xfs_end_bio_delalloc(
|
||||
xfs_ioend_t *ioend =
|
||||
container_of(work, xfs_ioend_t, io_work);
|
||||
|
||||
xfs_setfilesize(ioend);
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
@ -165,6 +203,7 @@ xfs_end_bio_written(
|
||||
xfs_ioend_t *ioend =
|
||||
container_of(work, xfs_ioend_t, io_work);
|
||||
|
||||
xfs_setfilesize(ioend);
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
@ -184,8 +223,23 @@ xfs_end_bio_unwritten(
|
||||
xfs_off_t offset = ioend->io_offset;
|
||||
size_t size = ioend->io_size;
|
||||
|
||||
if (likely(!ioend->io_error))
|
||||
if (likely(!ioend->io_error)) {
|
||||
bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
|
||||
xfs_setfilesize(ioend);
|
||||
}
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
/*
|
||||
* IO read completion for regular, written extents.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_end_bio_read(
|
||||
struct work_struct *work)
|
||||
{
|
||||
xfs_ioend_t *ioend =
|
||||
container_of(work, xfs_ioend_t, io_work);
|
||||
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
@ -224,6 +278,8 @@ xfs_alloc_ioend(
|
||||
INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten);
|
||||
else if (type == IOMAP_DELAY)
|
||||
INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc);
|
||||
else if (type == IOMAP_READ)
|
||||
INIT_WORK(&ioend->io_work, xfs_end_bio_read);
|
||||
else
|
||||
INIT_WORK(&ioend->io_work, xfs_end_bio_written);
|
||||
|
||||
@ -913,7 +969,7 @@ xfs_page_state_convert(
|
||||
bh = head = page_buffers(page);
|
||||
offset = page_offset(page);
|
||||
flags = -1;
|
||||
type = 0;
|
||||
type = IOMAP_READ;
|
||||
|
||||
/* TODO: cleanup count and page_dirty */
|
||||
|
||||
@ -999,7 +1055,7 @@ xfs_page_state_convert(
|
||||
* That means it must already have extents allocated
|
||||
* underneath it. Map the extent by reading it.
|
||||
*/
|
||||
if (!iomap_valid || type != 0) {
|
||||
if (!iomap_valid || type != IOMAP_READ) {
|
||||
flags = BMAPI_READ;
|
||||
size = xfs_probe_cluster(inode, page, bh,
|
||||
head, 1);
|
||||
@ -1010,7 +1066,7 @@ xfs_page_state_convert(
|
||||
iomap_valid = xfs_iomap_valid(&iomap, offset);
|
||||
}
|
||||
|
||||
type = 0;
|
||||
type = IOMAP_READ;
|
||||
if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
|
||||
ASSERT(buffer_mapped(bh));
|
||||
if (iomap_valid)
|
||||
@ -1356,12 +1412,21 @@ xfs_end_io_direct(
|
||||
* completion handler in the future, in which case all this can
|
||||
* go away.
|
||||
*/
|
||||
if (private && size > 0) {
|
||||
ioend->io_offset = offset;
|
||||
ioend->io_size = size;
|
||||
ioend->io_offset = offset;
|
||||
ioend->io_size = size;
|
||||
if (ioend->io_type == IOMAP_READ) {
|
||||
xfs_finish_ioend(ioend);
|
||||
} else if (private && size > 0) {
|
||||
xfs_finish_ioend(ioend);
|
||||
} else {
|
||||
xfs_destroy_ioend(ioend);
|
||||
/*
|
||||
* A direct I/O write ioend starts it's life in unwritten
|
||||
* state in case they map an unwritten extent. This write
|
||||
* didn't map an unwritten extent so switch it's completion
|
||||
* handler.
|
||||
*/
|
||||
INIT_WORK(&ioend->io_work, xfs_end_bio_written);
|
||||
xfs_finish_ioend(ioend);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1392,15 +1457,15 @@ xfs_vm_direct_IO(
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
|
||||
|
||||
if (rw == WRITE) {
|
||||
iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
|
||||
ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
|
||||
iomap.iomap_target->bt_bdev,
|
||||
iov, offset, nr_segs,
|
||||
xfs_get_blocks_direct,
|
||||
xfs_end_io_direct);
|
||||
} else {
|
||||
iocb->private = xfs_alloc_ioend(inode, IOMAP_READ);
|
||||
ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
|
||||
iomap.iomap_target->bt_bdev,
|
||||
iov, offset, nr_segs,
|
||||
|
@ -1426,7 +1426,7 @@ xfs_free_bufhash(
|
||||
/*
|
||||
* buftarg list for delwrite queue processing
|
||||
*/
|
||||
LIST_HEAD(xfs_buftarg_list);
|
||||
static LIST_HEAD(xfs_buftarg_list);
|
||||
static DEFINE_SPINLOCK(xfs_buftarg_lock);
|
||||
|
||||
STATIC void
|
||||
@ -1867,3 +1867,11 @@ xfs_buf_terminate(void)
|
||||
ktrace_free(xfs_buf_trace_buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KDB_MODULES
|
||||
struct list_head *
|
||||
xfs_get_buftarg_list(void)
|
||||
{
|
||||
return &xfs_buftarg_list;
|
||||
}
|
||||
#endif
|
||||
|
@ -411,6 +411,9 @@ extern void xfs_free_buftarg(xfs_buftarg_t *, int);
|
||||
extern void xfs_wait_buftarg(xfs_buftarg_t *);
|
||||
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
|
||||
extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
|
||||
#ifdef CONFIG_KDB_MODULES
|
||||
extern struct list_head *xfs_get_buftarg_list(void);
|
||||
#endif
|
||||
|
||||
#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)
|
||||
#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
|
||||
|
@ -35,7 +35,7 @@ fs_tosspages(
|
||||
truncate_inode_pages(ip->i_mapping, first);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
fs_flushinval_pages(
|
||||
bhv_desc_t *bdp,
|
||||
xfs_off_t first,
|
||||
@ -44,13 +44,16 @@ fs_flushinval_pages(
|
||||
{
|
||||
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
int ret = 0;
|
||||
|
||||
if (VN_CACHED(vp)) {
|
||||
if (VN_TRUNC(vp))
|
||||
VUNTRUNCATE(vp);
|
||||
filemap_write_and_wait(ip->i_mapping);
|
||||
truncate_inode_pages(ip->i_mapping, first);
|
||||
ret = filemap_write_and_wait(ip->i_mapping);
|
||||
if (!ret)
|
||||
truncate_inode_pages(ip->i_mapping, first);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@ -63,14 +66,18 @@ fs_flush_pages(
|
||||
{
|
||||
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
int ret = 0;
|
||||
int ret2;
|
||||
|
||||
if (VN_DIRTY(vp)) {
|
||||
if (VN_TRUNC(vp))
|
||||
VUNTRUNCATE(vp);
|
||||
filemap_fdatawrite(ip->i_mapping);
|
||||
ret = filemap_fdatawrite(ip->i_mapping);
|
||||
if (flags & XFS_B_ASYNC)
|
||||
return 0;
|
||||
filemap_fdatawait(ip->i_mapping);
|
||||
return ret;
|
||||
ret2 = filemap_fdatawait(ip->i_mapping);
|
||||
if (!ret)
|
||||
ret = ret2;
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ extern int fs_noerr(void);
|
||||
extern int fs_nosys(void);
|
||||
extern void fs_noval(void);
|
||||
extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
extern int fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
|
||||
|
||||
#endif /* __XFS_FS_SUBR_H__ */
|
||||
|
@ -191,7 +191,7 @@ xfs_read(
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
size_t size = 0;
|
||||
ssize_t ret;
|
||||
ssize_t ret = 0;
|
||||
xfs_fsize_t n;
|
||||
xfs_inode_t *ip;
|
||||
xfs_mount_t *mp;
|
||||
@ -224,7 +224,7 @@ xfs_read(
|
||||
mp->m_rtdev_targp : mp->m_ddev_targp;
|
||||
if ((*offset & target->bt_smask) ||
|
||||
(size & target->bt_smask)) {
|
||||
if (*offset == ip->i_d.di_size) {
|
||||
if (*offset == ip->i_size) {
|
||||
return (0);
|
||||
}
|
||||
return -XFS_ERROR(EINVAL);
|
||||
@ -263,9 +263,13 @@ xfs_read(
|
||||
|
||||
if (unlikely(ioflags & IO_ISDIRECT)) {
|
||||
if (VN_CACHED(vp))
|
||||
bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
|
||||
ret = bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (ret) {
|
||||
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
|
||||
@ -383,9 +387,10 @@ xfs_splice_write(
|
||||
{
|
||||
xfs_inode_t *ip = XFS_BHVTOI(bdp);
|
||||
xfs_mount_t *mp = ip->i_mount;
|
||||
xfs_iocore_t *io = &ip->i_iocore;
|
||||
ssize_t ret;
|
||||
struct inode *inode = outfilp->f_mapping->host;
|
||||
xfs_fsize_t isize;
|
||||
xfs_fsize_t isize, new_size;
|
||||
|
||||
XFS_STATS_INC(xs_write_calls);
|
||||
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
|
||||
@ -406,6 +411,14 @@ xfs_splice_write(
|
||||
return -error;
|
||||
}
|
||||
}
|
||||
|
||||
new_size = *ppos + count;
|
||||
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
if (new_size > ip->i_size)
|
||||
io->io_new_size = new_size;
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
|
||||
xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
|
||||
pipe, count, *ppos, ioflags);
|
||||
ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
|
||||
@ -416,14 +429,18 @@ xfs_splice_write(
|
||||
if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
|
||||
*ppos = isize;
|
||||
|
||||
if (*ppos > ip->i_d.di_size) {
|
||||
if (*ppos > ip->i_size) {
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
if (*ppos > ip->i_d.di_size) {
|
||||
ip->i_d.di_size = *ppos;
|
||||
i_size_write(inode, *ppos);
|
||||
ip->i_update_core = 1;
|
||||
ip->i_update_size = 1;
|
||||
}
|
||||
if (*ppos > ip->i_size)
|
||||
ip->i_size = *ppos;
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
|
||||
if (io->io_new_size) {
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
io->io_new_size = 0;
|
||||
if (ip->i_d.di_size > ip->i_size)
|
||||
ip->i_d.di_size = ip->i_size;
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
||||
@ -644,7 +661,7 @@ xfs_write(
|
||||
bhv_vrwlock_t locktype;
|
||||
size_t ocount = 0, count;
|
||||
loff_t pos;
|
||||
int need_i_mutex = 1, need_flush = 0;
|
||||
int need_i_mutex;
|
||||
|
||||
XFS_STATS_INC(xs_write_calls);
|
||||
|
||||
@ -669,39 +686,20 @@ xfs_write(
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return -EIO;
|
||||
|
||||
if (ioflags & IO_ISDIRECT) {
|
||||
xfs_buftarg_t *target =
|
||||
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
|
||||
mp->m_rtdev_targp : mp->m_ddev_targp;
|
||||
|
||||
if ((pos & target->bt_smask) || (count & target->bt_smask))
|
||||
return XFS_ERROR(-EINVAL);
|
||||
|
||||
if (!VN_CACHED(vp) && pos < i_size_read(inode))
|
||||
need_i_mutex = 0;
|
||||
|
||||
if (VN_CACHED(vp))
|
||||
need_flush = 1;
|
||||
}
|
||||
|
||||
relock:
|
||||
if (need_i_mutex) {
|
||||
iolock = XFS_IOLOCK_EXCL;
|
||||
locktype = VRWLOCK_WRITE;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
} else {
|
||||
if (ioflags & IO_ISDIRECT) {
|
||||
iolock = XFS_IOLOCK_SHARED;
|
||||
locktype = VRWLOCK_WRITE_DIRECT;
|
||||
need_i_mutex = 0;
|
||||
} else {
|
||||
iolock = XFS_IOLOCK_EXCL;
|
||||
locktype = VRWLOCK_WRITE;
|
||||
need_i_mutex = 1;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
}
|
||||
|
||||
xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
|
||||
|
||||
isize = i_size_read(inode);
|
||||
|
||||
if (file->f_flags & O_APPEND)
|
||||
*offset = isize;
|
||||
|
||||
start:
|
||||
error = -generic_write_checks(file, &pos, &count,
|
||||
S_ISBLK(inode->i_mode));
|
||||
@ -710,13 +708,8 @@ xfs_write(
|
||||
goto out_unlock_mutex;
|
||||
}
|
||||
|
||||
new_size = pos + count;
|
||||
if (new_size > isize)
|
||||
io->io_new_size = new_size;
|
||||
|
||||
if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
|
||||
!(ioflags & IO_INVIS) && !eventsent)) {
|
||||
loff_t savedsize = pos;
|
||||
int dmflags = FILP_DELAY_FLAG(file);
|
||||
|
||||
if (need_i_mutex)
|
||||
@ -727,8 +720,7 @@ xfs_write(
|
||||
pos, count,
|
||||
dmflags, &locktype);
|
||||
if (error) {
|
||||
xfs_iunlock(xip, iolock);
|
||||
goto out_unlock_mutex;
|
||||
goto out_unlock_internal;
|
||||
}
|
||||
xfs_ilock(xip, XFS_ILOCK_EXCL);
|
||||
eventsent = 1;
|
||||
@ -740,12 +732,35 @@ xfs_write(
|
||||
* event prevents another call to XFS_SEND_DATA, which is
|
||||
* what allows the size to change in the first place.
|
||||
*/
|
||||
if ((file->f_flags & O_APPEND) && savedsize != isize) {
|
||||
pos = isize = xip->i_d.di_size;
|
||||
if ((file->f_flags & O_APPEND) && pos != xip->i_size)
|
||||
goto start;
|
||||
}
|
||||
|
||||
if (ioflags & IO_ISDIRECT) {
|
||||
xfs_buftarg_t *target =
|
||||
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
|
||||
mp->m_rtdev_targp : mp->m_ddev_targp;
|
||||
|
||||
if ((pos & target->bt_smask) || (count & target->bt_smask)) {
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
|
||||
return XFS_ERROR(-EINVAL);
|
||||
}
|
||||
|
||||
if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) {
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
|
||||
iolock = XFS_IOLOCK_EXCL;
|
||||
locktype = VRWLOCK_WRITE;
|
||||
need_i_mutex = 1;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
|
||||
goto start;
|
||||
}
|
||||
}
|
||||
|
||||
new_size = pos + count;
|
||||
if (new_size > xip->i_size)
|
||||
io->io_new_size = new_size;
|
||||
|
||||
if (likely(!(ioflags & IO_INVIS))) {
|
||||
file_update_time(file);
|
||||
xfs_ichgtime_fast(xip, inode,
|
||||
@ -761,11 +776,11 @@ xfs_write(
|
||||
* to zero it out up to the new size.
|
||||
*/
|
||||
|
||||
if (pos > isize) {
|
||||
error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, isize);
|
||||
if (pos > xip->i_size) {
|
||||
error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, xip->i_size);
|
||||
if (error) {
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
|
||||
goto out_unlock_mutex;
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL);
|
||||
goto out_unlock_internal;
|
||||
}
|
||||
}
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL);
|
||||
@ -785,8 +800,7 @@ xfs_write(
|
||||
if (likely(!error))
|
||||
error = -remove_suid(file->f_path.dentry);
|
||||
if (unlikely(error)) {
|
||||
xfs_iunlock(xip, iolock);
|
||||
goto out_unlock_mutex;
|
||||
goto out_unlock_internal;
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,11 +809,14 @@ xfs_write(
|
||||
current->backing_dev_info = mapping->backing_dev_info;
|
||||
|
||||
if ((ioflags & IO_ISDIRECT)) {
|
||||
if (need_flush) {
|
||||
if (VN_CACHED(vp)) {
|
||||
WARN_ON(need_i_mutex == 0);
|
||||
xfs_inval_cached_trace(io, pos, -1,
|
||||
ctooff(offtoct(pos)), -1);
|
||||
bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
|
||||
error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
if (error)
|
||||
goto out_unlock_internal;
|
||||
}
|
||||
|
||||
if (need_i_mutex) {
|
||||
@ -827,7 +844,6 @@ xfs_write(
|
||||
pos += ret;
|
||||
count -= ret;
|
||||
|
||||
need_i_mutex = 1;
|
||||
ioflags &= ~IO_ISDIRECT;
|
||||
xfs_iunlock(xip, iolock);
|
||||
goto relock;
|
||||
@ -854,12 +870,12 @@ xfs_write(
|
||||
error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
|
||||
DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
|
||||
0, 0, 0); /* Delay flag intentionally unused */
|
||||
if (error)
|
||||
goto out_nounlocks;
|
||||
if (need_i_mutex)
|
||||
mutex_lock(&inode->i_mutex);
|
||||
xfs_rwlock(bdp, locktype);
|
||||
pos = xip->i_d.di_size;
|
||||
if (error)
|
||||
goto out_unlock_internal;
|
||||
pos = xip->i_size;
|
||||
ret = 0;
|
||||
goto retry;
|
||||
}
|
||||
@ -868,14 +884,10 @@ xfs_write(
|
||||
if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
|
||||
*offset = isize;
|
||||
|
||||
if (*offset > xip->i_d.di_size) {
|
||||
if (*offset > xip->i_size) {
|
||||
xfs_ilock(xip, XFS_ILOCK_EXCL);
|
||||
if (*offset > xip->i_d.di_size) {
|
||||
xip->i_d.di_size = *offset;
|
||||
i_size_write(inode, *offset);
|
||||
xip->i_update_core = 1;
|
||||
xip->i_update_size = 1;
|
||||
}
|
||||
if (*offset > xip->i_size)
|
||||
xip->i_size = *offset;
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
|
||||
@ -897,16 +909,31 @@ xfs_write(
|
||||
|
||||
error = sync_page_range(inode, mapping, pos, ret);
|
||||
if (!error)
|
||||
error = ret;
|
||||
return error;
|
||||
error = -ret;
|
||||
if (need_i_mutex)
|
||||
mutex_lock(&inode->i_mutex);
|
||||
xfs_rwlock(bdp, locktype);
|
||||
}
|
||||
|
||||
out_unlock_internal:
|
||||
if (io->io_new_size) {
|
||||
xfs_ilock(xip, XFS_ILOCK_EXCL);
|
||||
io->io_new_size = 0;
|
||||
/*
|
||||
* If this was a direct or synchronous I/O that failed (such
|
||||
* as ENOSPC) then part of the I/O may have been written to
|
||||
* disk before the error occured. In this case the on-disk
|
||||
* file size may have been adjusted beyond the in-memory file
|
||||
* size and now needs to be truncated back.
|
||||
*/
|
||||
if (xip->i_d.di_size > xip->i_size)
|
||||
xip->i_d.di_size = xip->i_size;
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
xfs_rwunlock(bdp, locktype);
|
||||
out_unlock_mutex:
|
||||
if (need_i_mutex)
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
out_nounlocks:
|
||||
return -error;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
|
||||
typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
|
||||
typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
|
||||
typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
typedef int (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
|
||||
uint64_t, int);
|
||||
typedef int (*vop_iflush_t)(bhv_desc_t *, int);
|
||||
|
@ -753,8 +753,7 @@ xfs_qm_idtodq(
|
||||
goto error0;
|
||||
}
|
||||
if (tp) {
|
||||
if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL)))
|
||||
if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES)))
|
||||
goto error1;
|
||||
}
|
||||
|
||||
|
@ -388,6 +388,17 @@ xfs_qm_mount_quotas(
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If one type of quotas is off, then it will lose its
|
||||
* quotachecked status, since we won't be doing accounting for
|
||||
* that type anymore.
|
||||
*/
|
||||
if (!XFS_IS_UQUOTA_ON(mp)) {
|
||||
mp->m_qflags &= ~XFS_UQUOTA_CHKD;
|
||||
}
|
||||
if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp))) {
|
||||
mp->m_qflags &= ~XFS_OQUOTA_CHKD;
|
||||
}
|
||||
|
||||
write_changes:
|
||||
/*
|
||||
@ -1453,8 +1464,7 @@ xfs_qm_qino_alloc(
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
xfs_mod_sb(tp, sbfields);
|
||||
|
||||
if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL))) {
|
||||
if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) {
|
||||
xfs_fs_cmn_err(CE_ALERT, mp, "XFS qino_alloc failed!");
|
||||
return error;
|
||||
}
|
||||
@ -2405,7 +2415,7 @@ xfs_qm_write_sb_changes(
|
||||
}
|
||||
|
||||
xfs_mod_sb(tp, flags);
|
||||
(void) xfs_trans_commit(tp, 0, NULL);
|
||||
(void) xfs_trans_commit(tp, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -456,9 +456,7 @@ xfs_qm_scall_quotaon(
|
||||
||
|
||||
((flags & XFS_PQUOTA_ACCT) == 0 &&
|
||||
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_OQUOTA_ENFD))
|
||||
||
|
||||
((flags & XFS_GQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_GQUOTA_ACCT) == 0 &&
|
||||
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_OQUOTA_ENFD))) {
|
||||
qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
|
||||
@ -735,7 +733,7 @@ xfs_qm_scall_setqlim(
|
||||
xfs_trans_log_dquot(tp, dqp);
|
||||
|
||||
xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT");
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_trans_commit(tp, 0);
|
||||
xfs_qm_dqprint(dqp);
|
||||
xfs_qm_dqrele(dqp);
|
||||
mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
|
||||
@ -809,7 +807,7 @@ xfs_qm_log_quotaoff_end(
|
||||
* We don't care about quotoff's performance.
|
||||
*/
|
||||
xfs_trans_set_sync(tp);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -852,7 +850,7 @@ xfs_qm_log_quotaoff(
|
||||
* We don't care about quotoff's performance.
|
||||
*/
|
||||
xfs_trans_set_sync(tp);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
|
||||
error0:
|
||||
if (error) {
|
||||
@ -911,14 +909,19 @@ xfs_qm_export_dquot(
|
||||
* gets turned off. No need to confuse the user level code,
|
||||
* so return zeroes in that case.
|
||||
*/
|
||||
if (! XFS_IS_QUOTA_ENFORCED(mp)) {
|
||||
if ((!XFS_IS_UQUOTA_ENFORCED(mp) && src->d_flags == XFS_DQ_USER) ||
|
||||
(!XFS_IS_OQUOTA_ENFORCED(mp) &&
|
||||
(src->d_flags & (XFS_DQ_PROJ | XFS_DQ_GROUP)))) {
|
||||
dst->d_btimer = 0;
|
||||
dst->d_itimer = 0;
|
||||
dst->d_rtbtimer = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (XFS_IS_QUOTA_ENFORCED(mp) && dst->d_id != 0) {
|
||||
if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == XFS_USER_QUOTA) ||
|
||||
(XFS_IS_OQUOTA_ENFORCED(mp) &&
|
||||
(dst->d_flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)))) &&
|
||||
dst->d_id != 0) {
|
||||
if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
|
||||
(dst->d_blk_softlimit > 0)) {
|
||||
ASSERT(dst->d_btimer != 0);
|
||||
|
@ -656,7 +656,9 @@ xfs_trans_dqresv(
|
||||
|
||||
if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
|
||||
dqp->q_core.d_id &&
|
||||
XFS_IS_QUOTA_ENFORCED(dqp->q_mount)) {
|
||||
((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
|
||||
(XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
|
||||
(XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
|
||||
#ifdef QUOTADEBUG
|
||||
cmn_err(CE_DEBUG, "BLK Res: nblks=%ld + resbcount=%Ld"
|
||||
" > hardlimit=%Ld?", nblks, *resbcountp, hardlimit);
|
||||
|
@ -81,20 +81,3 @@ assfail(char *expr, char *file, int line)
|
||||
printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line);
|
||||
BUG();
|
||||
}
|
||||
|
||||
#if ((defined(DEBUG) || defined(INDUCE_IO_ERRROR)) && !defined(NO_WANT_RANDOM))
|
||||
unsigned long random(void)
|
||||
{
|
||||
static unsigned long RandomValue = 1;
|
||||
/* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */
|
||||
register long rv = RandomValue;
|
||||
register long lo;
|
||||
register long hi;
|
||||
|
||||
hi = rv / 127773;
|
||||
lo = rv % 127773;
|
||||
rv = 16807 * lo - 2836 * hi;
|
||||
if (rv <= 0) rv += 2147483647;
|
||||
return RandomValue = rv;
|
||||
}
|
||||
#endif /* DEBUG || INDUCE_IO_ERRROR || !NO_WANT_RANDOM */
|
||||
|
@ -50,7 +50,7 @@ extern void assfail(char *expr, char *f, int l);
|
||||
#else /* DEBUG */
|
||||
|
||||
# define ASSERT(expr) ASSERT_ALWAYS(expr)
|
||||
extern unsigned long random(void);
|
||||
# include <linux/random.h>
|
||||
|
||||
#ifndef STATIC
|
||||
# define STATIC noinline
|
||||
|
@ -764,7 +764,7 @@ xfs_alloc_ag_vextent_near(
|
||||
*/
|
||||
int dofirst; /* set to do first algorithm */
|
||||
|
||||
dofirst = random() & 1;
|
||||
dofirst = random32() & 1;
|
||||
#endif
|
||||
/*
|
||||
* Get a cursor for the by-size btree.
|
||||
|
@ -328,8 +328,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
|
||||
xfs_trans_set_sync(args.trans);
|
||||
}
|
||||
err2 = xfs_trans_commit(args.trans,
|
||||
XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL);
|
||||
XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
||||
|
||||
/*
|
||||
@ -397,8 +396,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
|
||||
* Commit the last in the sequence of transactions.
|
||||
*/
|
||||
xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
|
||||
error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL);
|
||||
error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
||||
|
||||
/*
|
||||
@ -544,8 +542,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
|
||||
* Commit the last in the sequence of transactions.
|
||||
*/
|
||||
xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
|
||||
error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL);
|
||||
error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
||||
|
||||
/*
|
||||
@ -859,8 +856,7 @@ xfs_attr_inactive(xfs_inode_t *dp)
|
||||
* Commit the last in the sequence of transactions.
|
||||
*/
|
||||
xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
|
||||
error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL);
|
||||
error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
||||
|
||||
return(error);
|
||||
|
@ -3053,7 +3053,7 @@ xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp)
|
||||
* is in progress. The caller takes the responsibility to cancel
|
||||
* the duplicate transaction that gets returned.
|
||||
*/
|
||||
if ((error = xfs_trans_commit(trans, 0, NULL)))
|
||||
if ((error = xfs_trans_commit(trans, 0)))
|
||||
return (error);
|
||||
|
||||
trans = *transp;
|
||||
|
@ -130,7 +130,6 @@ STATIC int /* error */
|
||||
xfs_bmap_add_extent_hole_delay(
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp,/* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
@ -399,7 +398,6 @@ xfs_bmap_count_leaves(
|
||||
|
||||
STATIC int
|
||||
xfs_bmap_disk_count_leaves(
|
||||
xfs_ifork_t *ifp,
|
||||
xfs_extnum_t idx,
|
||||
xfs_bmbt_block_t *block,
|
||||
int numrecs,
|
||||
@ -580,7 +578,7 @@ xfs_bmap_add_extent(
|
||||
if (cur)
|
||||
ASSERT((cur->bc_private.b.flags &
|
||||
XFS_BTCUR_BPRV_WASDEL) == 0);
|
||||
if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
|
||||
if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new,
|
||||
&logflags, delta, rsvd)))
|
||||
goto done;
|
||||
}
|
||||
@ -1841,7 +1839,6 @@ STATIC int /* error */
|
||||
xfs_bmap_add_extent_hole_delay(
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
@ -4071,7 +4068,7 @@ xfs_bmap_add_attrfork(
|
||||
}
|
||||
if ((error = xfs_bmap_finish(&tp, &flist, &committed)))
|
||||
goto error2;
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES);
|
||||
ASSERT(ip->i_df.if_ext_max ==
|
||||
XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
|
||||
return error;
|
||||
@ -4227,7 +4224,7 @@ xfs_bmap_finish(
|
||||
logres = ntp->t_log_res;
|
||||
logcount = ntp->t_log_count;
|
||||
ntp = xfs_trans_dup(*tp);
|
||||
error = xfs_trans_commit(*tp, 0, NULL);
|
||||
error = xfs_trans_commit(*tp, 0);
|
||||
*tp = ntp;
|
||||
*committed = 1;
|
||||
/*
|
||||
@ -4447,8 +4444,11 @@ xfs_bmap_one_block(
|
||||
xfs_bmbt_irec_t s; /* internal version of extent */
|
||||
|
||||
#ifndef DEBUG
|
||||
if (whichfork == XFS_DATA_FORK)
|
||||
return ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize;
|
||||
if (whichfork == XFS_DATA_FORK) {
|
||||
return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ?
|
||||
(ip->i_size == ip->i_mount->m_sb.sb_blocksize) :
|
||||
(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
|
||||
}
|
||||
#endif /* !DEBUG */
|
||||
if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
|
||||
return 0;
|
||||
@ -4460,7 +4460,7 @@ xfs_bmap_one_block(
|
||||
xfs_bmbt_get_all(ep, &s);
|
||||
rval = s.br_startoff == 0 && s.br_blockcount == 1;
|
||||
if (rval && whichfork == XFS_DATA_FORK)
|
||||
ASSERT(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
|
||||
ASSERT(ip->i_size == ip->i_mount->m_sb.sb_blocksize);
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -5820,7 +5820,7 @@ xfs_getbmap(
|
||||
fixlen = XFS_MAXIOFFSET(mp);
|
||||
} else {
|
||||
prealloced = 0;
|
||||
fixlen = ip->i_d.di_size;
|
||||
fixlen = ip->i_size;
|
||||
}
|
||||
} else {
|
||||
prealloced = 0;
|
||||
@ -5844,7 +5844,8 @@ xfs_getbmap(
|
||||
|
||||
xfs_ilock(ip, XFS_IOLOCK_SHARED);
|
||||
|
||||
if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
|
||||
if (whichfork == XFS_DATA_FORK &&
|
||||
(ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
|
||||
/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
|
||||
error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
|
||||
}
|
||||
@ -6425,8 +6426,8 @@ xfs_bmap_count_tree(
|
||||
for (;;) {
|
||||
nextbno = be64_to_cpu(block->bb_rightsib);
|
||||
numrecs = be16_to_cpu(block->bb_numrecs);
|
||||
if (unlikely(xfs_bmap_disk_count_leaves(ifp,
|
||||
0, block, numrecs, count) < 0)) {
|
||||
if (unlikely(xfs_bmap_disk_count_leaves(0,
|
||||
block, numrecs, count) < 0)) {
|
||||
xfs_trans_brelse(tp, bp);
|
||||
XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
@ -6472,7 +6473,6 @@ xfs_bmap_count_leaves(
|
||||
*/
|
||||
int
|
||||
xfs_bmap_disk_count_leaves(
|
||||
xfs_ifork_t *ifp,
|
||||
xfs_extnum_t idx,
|
||||
xfs_bmbt_block_t *block,
|
||||
int numrecs,
|
||||
|
@ -199,7 +199,9 @@ xfs_swap_extents(
|
||||
|
||||
if (VN_CACHED(tvp) != 0) {
|
||||
xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
|
||||
bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
|
||||
error = bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
|
||||
if (error)
|
||||
goto error0;
|
||||
}
|
||||
|
||||
/* Verify O_DIRECT for ftmp */
|
||||
@ -382,7 +384,7 @@ xfs_swap_extents(
|
||||
xfs_trans_set_sync(tp);
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
|
||||
locked = 0;
|
||||
|
||||
error0:
|
||||
|
@ -282,8 +282,7 @@ xfs_dir2_block_addname(
|
||||
* This needs to happen before the next call to use_free.
|
||||
*/
|
||||
if (needscan) {
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
|
||||
&needlog, NULL);
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
|
||||
needscan = 0;
|
||||
}
|
||||
}
|
||||
@ -333,7 +332,7 @@ xfs_dir2_block_addname(
|
||||
*/
|
||||
if (needscan) {
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
|
||||
&needlog, NULL);
|
||||
&needlog);
|
||||
needscan = 0;
|
||||
}
|
||||
/*
|
||||
@ -418,8 +417,7 @@ xfs_dir2_block_addname(
|
||||
* Clean up the bestfree array and log the header, tail, and entry.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
|
||||
NULL);
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, bp);
|
||||
xfs_dir2_block_log_tail(tp, bp);
|
||||
@ -798,8 +796,7 @@ xfs_dir2_block_removename(
|
||||
* Fix up bestfree, log the header if necessary.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
|
||||
NULL);
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, bp);
|
||||
xfs_dir2_data_check(dp, bp);
|
||||
@ -996,8 +993,7 @@ xfs_dir2_leaf_to_block(
|
||||
* Scan the bestfree if we need it and log the data block header.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
|
||||
NULL);
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dbp);
|
||||
/*
|
||||
|
@ -324,8 +324,7 @@ void
|
||||
xfs_dir2_data_freescan(
|
||||
xfs_mount_t *mp, /* filesystem mount point */
|
||||
xfs_dir2_data_t *d, /* data block pointer */
|
||||
int *loghead, /* out: log data header */
|
||||
char *aendp) /* in: caller's endp */
|
||||
int *loghead) /* out: log data header */
|
||||
{
|
||||
xfs_dir2_block_tail_t *btp; /* block tail */
|
||||
xfs_dir2_data_entry_t *dep; /* active data entry */
|
||||
@ -346,9 +345,7 @@ xfs_dir2_data_freescan(
|
||||
* Set up pointers.
|
||||
*/
|
||||
p = (char *)d->u;
|
||||
if (aendp)
|
||||
endp = aendp;
|
||||
else if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
|
||||
endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
|
||||
} else
|
||||
|
@ -166,7 +166,7 @@ extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d,
|
||||
extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
|
||||
xfs_dir2_data_unused_t *dup, int *loghead);
|
||||
extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
|
||||
int *loghead, char *aendp);
|
||||
int *loghead);
|
||||
extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
|
||||
struct xfs_dabuf **bpp);
|
||||
extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
|
||||
|
@ -133,8 +133,7 @@ xfs_dir2_block_to_leaf(
|
||||
*/
|
||||
block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
|
||||
NULL);
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
|
||||
/*
|
||||
* Set up leaf tail and bests table.
|
||||
*/
|
||||
@ -414,7 +413,7 @@ xfs_dir2_leaf_addname(
|
||||
* Need to scan fix up the bestfree table.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, data, &needlog, NULL);
|
||||
xfs_dir2_data_freescan(mp, data, &needlog);
|
||||
/*
|
||||
* Need to log the data block's header.
|
||||
*/
|
||||
@ -1496,7 +1495,7 @@ xfs_dir2_leaf_removename(
|
||||
* log the data block header if necessary.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, data, &needlog, NULL);
|
||||
xfs_dir2_data_freescan(mp, data, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dbp);
|
||||
/*
|
||||
|
@ -904,7 +904,7 @@ xfs_dir2_leafn_remove(
|
||||
* Log the data block header if needed.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, data, &needlog, NULL);
|
||||
xfs_dir2_data_freescan(mp, data, &needlog);
|
||||
if (needlog)
|
||||
xfs_dir2_data_log_header(tp, dbp);
|
||||
xfs_dir2_data_check(dp, dbp);
|
||||
@ -1705,7 +1705,7 @@ xfs_dir2_node_addname_int(
|
||||
* Rescan the block for bestfree if needed.
|
||||
*/
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, data, &needlog, NULL);
|
||||
xfs_dir2_data_freescan(mp, data, &needlog);
|
||||
/*
|
||||
* Log the data block header if needed.
|
||||
*/
|
||||
|
@ -80,7 +80,7 @@ xfs_error_test(int error_tag, int *fsidp, char *expression,
|
||||
int i;
|
||||
int64_t fsid;
|
||||
|
||||
if (random() % randfactor)
|
||||
if (random32() % randfactor)
|
||||
return 0;
|
||||
|
||||
memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
|
||||
|
@ -346,7 +346,7 @@ xfs_growfs_data_private(
|
||||
xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree);
|
||||
if (dpct)
|
||||
xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
@ -605,7 +605,7 @@ xfs_fs_log_dummy(
|
||||
xfs_trans_ihold(tp, ip);
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
xfs_trans_set_sync(tp);
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_trans_commit(tp, 0);
|
||||
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
|
@ -879,17 +879,17 @@ xfs_ilock(xfs_inode_t *ip,
|
||||
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
||||
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
||||
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
||||
ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
|
||||
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
|
||||
|
||||
if (lock_flags & XFS_IOLOCK_EXCL) {
|
||||
mrupdate(&ip->i_iolock);
|
||||
mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
|
||||
} else if (lock_flags & XFS_IOLOCK_SHARED) {
|
||||
mraccess(&ip->i_iolock);
|
||||
mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
|
||||
}
|
||||
if (lock_flags & XFS_ILOCK_EXCL) {
|
||||
mrupdate(&ip->i_lock);
|
||||
mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
|
||||
} else if (lock_flags & XFS_ILOCK_SHARED) {
|
||||
mraccess(&ip->i_lock);
|
||||
mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
|
||||
}
|
||||
xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
|
||||
}
|
||||
@ -923,7 +923,7 @@ xfs_ilock_nowait(xfs_inode_t *ip,
|
||||
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
||||
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
||||
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
||||
ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
|
||||
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
|
||||
|
||||
iolocked = 0;
|
||||
if (lock_flags & XFS_IOLOCK_EXCL) {
|
||||
@ -983,7 +983,8 @@ xfs_iunlock(xfs_inode_t *ip,
|
||||
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
||||
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
||||
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
||||
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY)) == 0);
|
||||
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY |
|
||||
XFS_LOCK_DEP_MASK)) == 0);
|
||||
ASSERT(lock_flags != 0);
|
||||
|
||||
if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
|
||||
|
@ -442,6 +442,7 @@ xfs_iformat(
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
ip->i_d.di_size = 0;
|
||||
ip->i_size = 0;
|
||||
ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
|
||||
break;
|
||||
|
||||
@ -980,6 +981,7 @@ xfs_iread(
|
||||
}
|
||||
|
||||
ip->i_delayed_blks = 0;
|
||||
ip->i_size = ip->i_d.di_size;
|
||||
|
||||
/*
|
||||
* Mark the buffer containing the inode as something to keep
|
||||
@ -1170,6 +1172,7 @@ xfs_ialloc(
|
||||
}
|
||||
|
||||
ip->i_d.di_size = 0;
|
||||
ip->i_size = 0;
|
||||
ip->i_d.di_nextents = 0;
|
||||
ASSERT(ip->i_d.di_nblocks == 0);
|
||||
xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD);
|
||||
@ -1340,7 +1343,7 @@ xfs_file_last_byte(
|
||||
} else {
|
||||
last_block = 0;
|
||||
}
|
||||
size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_d.di_size);
|
||||
size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_size);
|
||||
last_block = XFS_FILEOFF_MAX(last_block, size_last_block);
|
||||
|
||||
last_byte = XFS_FSB_TO_B(mp, last_block);
|
||||
@ -1421,7 +1424,7 @@ xfs_itrunc_trace(
|
||||
* must be called again with all the same restrictions as the initial
|
||||
* call.
|
||||
*/
|
||||
void
|
||||
int
|
||||
xfs_itruncate_start(
|
||||
xfs_inode_t *ip,
|
||||
uint flags,
|
||||
@ -1431,9 +1434,10 @@ xfs_itruncate_start(
|
||||
xfs_off_t toss_start;
|
||||
xfs_mount_t *mp;
|
||||
bhv_vnode_t *vp;
|
||||
int error = 0;
|
||||
|
||||
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
|
||||
ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
|
||||
ASSERT((new_size == 0) || (new_size <= ip->i_size));
|
||||
ASSERT((flags == XFS_ITRUNC_DEFINITE) ||
|
||||
(flags == XFS_ITRUNC_MAYBE));
|
||||
|
||||
@ -1468,7 +1472,7 @@ xfs_itruncate_start(
|
||||
* file size, so there is no way that the data extended
|
||||
* out there.
|
||||
*/
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
last_byte = xfs_file_last_byte(ip);
|
||||
xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start,
|
||||
@ -1477,7 +1481,7 @@ xfs_itruncate_start(
|
||||
if (flags & XFS_ITRUNC_DEFINITE) {
|
||||
bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
|
||||
} else {
|
||||
bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
|
||||
error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1486,6 +1490,7 @@ xfs_itruncate_start(
|
||||
ASSERT(VN_CACHED(vp) == 0);
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1556,7 +1561,7 @@ xfs_itruncate_finish(
|
||||
|
||||
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
|
||||
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
|
||||
ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
|
||||
ASSERT((new_size == 0) || (new_size <= ip->i_size));
|
||||
ASSERT(*tp != NULL);
|
||||
ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
|
||||
ASSERT(ip->i_transp == *tp);
|
||||
@ -1630,8 +1635,20 @@ xfs_itruncate_finish(
|
||||
*/
|
||||
if (fork == XFS_DATA_FORK) {
|
||||
if (ip->i_d.di_nextents > 0) {
|
||||
ip->i_d.di_size = new_size;
|
||||
xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
|
||||
/*
|
||||
* If we are not changing the file size then do
|
||||
* not update the on-disk file size - we may be
|
||||
* called from xfs_inactive_free_eofblocks(). If we
|
||||
* update the on-disk file size and then the system
|
||||
* crashes before the contents of the file are
|
||||
* flushed to disk then the files may be full of
|
||||
* holes (ie NULL files bug).
|
||||
*/
|
||||
if (ip->i_size != new_size) {
|
||||
ip->i_d.di_size = new_size;
|
||||
ip->i_size = new_size;
|
||||
xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
|
||||
}
|
||||
}
|
||||
} else if (sync) {
|
||||
ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC));
|
||||
@ -1746,7 +1763,7 @@ xfs_itruncate_finish(
|
||||
xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
|
||||
}
|
||||
ntp = xfs_trans_dup(ntp);
|
||||
(void) xfs_trans_commit(*tp, 0, NULL);
|
||||
(void) xfs_trans_commit(*tp, 0);
|
||||
*tp = ntp;
|
||||
error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
|
||||
XFS_TRANS_PERM_LOG_RES,
|
||||
@ -1767,7 +1784,19 @@ xfs_itruncate_finish(
|
||||
*/
|
||||
if (fork == XFS_DATA_FORK) {
|
||||
xfs_isize_check(mp, ip, new_size);
|
||||
ip->i_d.di_size = new_size;
|
||||
/*
|
||||
* If we are not changing the file size then do
|
||||
* not update the on-disk file size - we may be
|
||||
* called from xfs_inactive_free_eofblocks(). If we
|
||||
* update the on-disk file size and then the system
|
||||
* crashes before the contents of the file are
|
||||
* flushed to disk then the files may be full of
|
||||
* holes (ie NULL files bug).
|
||||
*/
|
||||
if (ip->i_size != new_size) {
|
||||
ip->i_d.di_size = new_size;
|
||||
ip->i_size = new_size;
|
||||
}
|
||||
}
|
||||
xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
|
||||
ASSERT((new_size != 0) ||
|
||||
@ -1800,7 +1829,7 @@ xfs_igrow_start(
|
||||
|
||||
ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
|
||||
ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
|
||||
ASSERT(new_size > ip->i_d.di_size);
|
||||
ASSERT(new_size > ip->i_size);
|
||||
|
||||
/*
|
||||
* Zero any pages that may have been created by
|
||||
@ -1808,7 +1837,7 @@ xfs_igrow_start(
|
||||
* and any blocks between the old and new file sizes.
|
||||
*/
|
||||
error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size,
|
||||
ip->i_d.di_size);
|
||||
ip->i_size);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1832,13 +1861,14 @@ xfs_igrow_finish(
|
||||
ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
|
||||
ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
|
||||
ASSERT(ip->i_transp == tp);
|
||||
ASSERT(new_size > ip->i_d.di_size);
|
||||
ASSERT(new_size > ip->i_size);
|
||||
|
||||
/*
|
||||
* Update the file size. Update the inode change timestamp
|
||||
* if change_flag set.
|
||||
*/
|
||||
ip->i_d.di_size = new_size;
|
||||
ip->i_size = new_size;
|
||||
if (change_flag)
|
||||
xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
@ -2321,7 +2351,7 @@ xfs_ifree(
|
||||
ASSERT(ip->i_d.di_nlink == 0);
|
||||
ASSERT(ip->i_d.di_nextents == 0);
|
||||
ASSERT(ip->i_d.di_anextents == 0);
|
||||
ASSERT((ip->i_d.di_size == 0) ||
|
||||
ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) ||
|
||||
((ip->i_d.di_mode & S_IFMT) != S_IFREG));
|
||||
ASSERT(ip->i_d.di_nblocks == 0);
|
||||
|
||||
|
@ -287,6 +287,7 @@ typedef struct xfs_inode {
|
||||
struct xfs_inode *i_cnext; /* cluster hash link forward */
|
||||
struct xfs_inode *i_cprev; /* cluster hash link backward */
|
||||
|
||||
xfs_fsize_t i_size; /* in-memory size */
|
||||
/* Trace buffers per inode. */
|
||||
#ifdef XFS_BMAP_TRACE
|
||||
struct ktrace *i_xtrace; /* inode extent list trace */
|
||||
@ -305,6 +306,8 @@ typedef struct xfs_inode {
|
||||
#endif
|
||||
} xfs_inode_t;
|
||||
|
||||
#define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \
|
||||
(ip)->i_size : (ip)->i_d.di_size;
|
||||
|
||||
/*
|
||||
* i_flags helper functions
|
||||
@ -379,26 +382,58 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
|
||||
|
||||
/*
|
||||
* Flags for inode locking.
|
||||
* Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
|
||||
* 1<<16 - 1<<32-1 -- lockdep annotation (integers)
|
||||
*/
|
||||
#define XFS_IOLOCK_EXCL 0x001
|
||||
#define XFS_IOLOCK_SHARED 0x002
|
||||
#define XFS_ILOCK_EXCL 0x004
|
||||
#define XFS_ILOCK_SHARED 0x008
|
||||
#define XFS_IUNLOCK_NONOTIFY 0x010
|
||||
/* XFS_IOLOCK_NESTED 0x020 */
|
||||
#define XFS_EXTENT_TOKEN_RD 0x040
|
||||
#define XFS_SIZE_TOKEN_RD 0x080
|
||||
#define XFS_IOLOCK_EXCL (1<<0)
|
||||
#define XFS_IOLOCK_SHARED (1<<1)
|
||||
#define XFS_ILOCK_EXCL (1<<2)
|
||||
#define XFS_ILOCK_SHARED (1<<3)
|
||||
#define XFS_IUNLOCK_NONOTIFY (1<<4)
|
||||
/* #define XFS_IOLOCK_NESTED (1<<5) */
|
||||
#define XFS_EXTENT_TOKEN_RD (1<<6)
|
||||
#define XFS_SIZE_TOKEN_RD (1<<7)
|
||||
#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD)
|
||||
#define XFS_WILLLEND 0x100 /* Always acquire tokens for lending */
|
||||
#define XFS_WILLLEND (1<<8) /* Always acquire tokens for lending */
|
||||
#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND)
|
||||
#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND)
|
||||
#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND)
|
||||
/* XFS_SIZE_TOKEN_WANT 0x200 */
|
||||
/* TODO:XFS_SIZE_TOKEN_WANT (1<<9) */
|
||||
|
||||
#define XFS_LOCK_MASK \
|
||||
(XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \
|
||||
XFS_ILOCK_SHARED | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD | \
|
||||
XFS_WILLLEND)
|
||||
#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
|
||||
| XFS_ILOCK_EXCL | XFS_ILOCK_SHARED \
|
||||
| XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD \
|
||||
| XFS_WILLLEND)
|
||||
|
||||
/*
|
||||
* Flags for lockdep annotations.
|
||||
*
|
||||
* XFS_I[O]LOCK_PARENT - for operations that require locking two inodes
|
||||
* (ie directory operations that require locking a directory inode and
|
||||
* an entry inode). The first inode gets locked with this flag so it
|
||||
* gets a lockdep subclass of 1 and the second lock will have a lockdep
|
||||
* subclass of 0.
|
||||
*
|
||||
* XFS_I[O]LOCK_INUMORDER - for locking several inodes at the some time
|
||||
* with xfs_lock_inodes(). This flag is used as the starting subclass
|
||||
* and each subsequent lock acquired will increment the subclass by one.
|
||||
* So the first lock acquired will have a lockdep subclass of 2, the
|
||||
* second lock will have a lockdep subclass of 3, and so on.
|
||||
*/
|
||||
#define XFS_IOLOCK_SHIFT 16
|
||||
#define XFS_IOLOCK_PARENT (1 << XFS_IOLOCK_SHIFT)
|
||||
#define XFS_IOLOCK_INUMORDER (2 << XFS_IOLOCK_SHIFT)
|
||||
|
||||
#define XFS_ILOCK_SHIFT 24
|
||||
#define XFS_ILOCK_PARENT (1 << XFS_ILOCK_SHIFT)
|
||||
#define XFS_ILOCK_INUMORDER (2 << XFS_ILOCK_SHIFT)
|
||||
|
||||
#define XFS_IOLOCK_DEP_MASK 0x00ff0000
|
||||
#define XFS_ILOCK_DEP_MASK 0xff000000
|
||||
#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK)
|
||||
|
||||
#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
|
||||
#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
|
||||
|
||||
/*
|
||||
* Flags for xfs_iflush()
|
||||
@ -481,7 +516,7 @@ uint xfs_ip2xflags(struct xfs_inode *);
|
||||
uint xfs_dic2xflags(struct xfs_dinode_core *);
|
||||
int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
|
||||
struct xfs_bmap_free *);
|
||||
void xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
|
||||
int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
|
||||
int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
|
||||
xfs_fsize_t, int, int);
|
||||
int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
|
||||
|
@ -52,7 +52,7 @@ STATIC xfs_fsize_t
|
||||
xfs_size_fn(
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
return (ip->i_d.di_size);
|
||||
return XFS_ISIZE(ip);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -458,7 +458,7 @@ xfs_iomap_write_direct(
|
||||
extsz = ip->i_d.di_extsize;
|
||||
}
|
||||
|
||||
isize = ip->i_d.di_size;
|
||||
isize = ip->i_size;
|
||||
if (io->io_new_size > isize)
|
||||
isize = io->io_new_size;
|
||||
|
||||
@ -524,7 +524,7 @@ xfs_iomap_write_direct(
|
||||
xfs_trans_ihold(tp, ip);
|
||||
|
||||
bmapi_flag = XFS_BMAPI_WRITE;
|
||||
if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz))
|
||||
if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz))
|
||||
bmapi_flag |= XFS_BMAPI_PREALLOC;
|
||||
|
||||
/*
|
||||
@ -543,7 +543,7 @@ xfs_iomap_write_direct(
|
||||
error = xfs_bmap_finish(&tp, &free_list, &committed);
|
||||
if (error)
|
||||
goto error0;
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (error)
|
||||
goto error_out;
|
||||
|
||||
@ -676,7 +676,7 @@ xfs_iomap_write_delay(
|
||||
offset_fsb = XFS_B_TO_FSBT(mp, offset);
|
||||
|
||||
retry:
|
||||
isize = ip->i_d.di_size;
|
||||
isize = ip->i_size;
|
||||
if (io->io_new_size > isize)
|
||||
isize = io->io_new_size;
|
||||
|
||||
@ -817,7 +817,7 @@ xfs_iomap_write_allocate(
|
||||
* we dropped the ilock in the interim.
|
||||
*/
|
||||
|
||||
end_fsb = XFS_B_TO_FSB(mp, ip->i_d.di_size);
|
||||
end_fsb = XFS_B_TO_FSB(mp, ip->i_size);
|
||||
xfs_bmap_last_offset(NULL, ip, &last_block,
|
||||
XFS_DATA_FORK);
|
||||
last_block = XFS_FILEOFF_MAX(last_block, end_fsb);
|
||||
@ -840,8 +840,7 @@ xfs_iomap_write_allocate(
|
||||
if (error)
|
||||
goto trans_cancel;
|
||||
|
||||
error = xfs_trans_commit(tp,
|
||||
XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (error)
|
||||
goto error0;
|
||||
|
||||
@ -948,7 +947,7 @@ xfs_iomap_write_unwritten(
|
||||
if (error)
|
||||
goto error_on_bmapi_transaction;
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
if (error)
|
||||
return XFS_ERROR(error);
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
|
||||
typedef enum { /* iomap_flags values */
|
||||
IOMAP_READ = 0, /* mapping for a read */
|
||||
IOMAP_EOF = 0x01, /* mapping contains EOF */
|
||||
IOMAP_HOLE = 0x02, /* mapping covers a hole */
|
||||
IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
|
||||
|
@ -1509,7 +1509,6 @@ xlog_recover_insert_item_frontq(
|
||||
|
||||
STATIC int
|
||||
xlog_recover_reorder_trans(
|
||||
xlog_t *log,
|
||||
xlog_recover_t *trans)
|
||||
{
|
||||
xlog_recover_item_t *first_item, *itemq, *itemq_next;
|
||||
@ -1867,7 +1866,6 @@ xlog_recover_do_inode_buffer(
|
||||
/*ARGSUSED*/
|
||||
STATIC void
|
||||
xlog_recover_do_reg_buffer(
|
||||
xfs_mount_t *mp,
|
||||
xlog_recover_item_t *item,
|
||||
xfs_buf_t *bp,
|
||||
xfs_buf_log_format_t *buf_f)
|
||||
@ -2083,7 +2081,7 @@ xlog_recover_do_dquot_buffer(
|
||||
if (log->l_quotaoffs_flag & type)
|
||||
return;
|
||||
|
||||
xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
|
||||
xlog_recover_do_reg_buffer(item, bp, buf_f);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2184,7 +2182,7 @@ xlog_recover_do_buffer_trans(
|
||||
(XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
|
||||
xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
|
||||
} else {
|
||||
xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
|
||||
xlog_recover_do_reg_buffer(item, bp, buf_f);
|
||||
}
|
||||
if (error)
|
||||
return XFS_ERROR(error);
|
||||
@ -2765,7 +2763,7 @@ xlog_recover_do_trans(
|
||||
int error = 0;
|
||||
xlog_recover_item_t *item, *first_item;
|
||||
|
||||
if ((error = xlog_recover_reorder_trans(log, trans)))
|
||||
if ((error = xlog_recover_reorder_trans(trans)))
|
||||
return error;
|
||||
first_item = item = trans->r_itemq;
|
||||
do {
|
||||
@ -3016,7 +3014,7 @@ xlog_recover_process_efi(
|
||||
}
|
||||
|
||||
efip->efi_flags |= XFS_EFI_RECOVERED;
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_trans_commit(tp, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3143,7 +3141,7 @@ xlog_recover_clear_agi_bucket(
|
||||
xfs_trans_log_buf(tp, agibp, offset,
|
||||
(offset + sizeof(xfs_agino_t) - 1));
|
||||
|
||||
(void) xfs_trans_commit(tp, 0, NULL);
|
||||
(void) xfs_trans_commit(tp, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3886,8 +3884,7 @@ xlog_recover(
|
||||
* under the vfs layer, so we can get away with it unless
|
||||
* the device itself is read-only, in which case we fail.
|
||||
*/
|
||||
if ((error = xfs_dev_is_read_only(log->l_mp,
|
||||
"recovery required"))) {
|
||||
if ((error = xfs_dev_is_read_only(log->l_mp, "recovery"))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1653,7 +1653,7 @@ xfs_mount_log_sbunit(
|
||||
return;
|
||||
}
|
||||
xfs_mod_sb(tp, fields);
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_trans_commit(tp, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,7 +78,7 @@ xfs_mount_reset_sbqflags(xfs_mount_t *mp)
|
||||
return error;
|
||||
}
|
||||
xfs_mod_sb(tp, XFS_SB_QFLAGS);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -154,10 +154,11 @@ typedef struct xfs_qoff_logformat {
|
||||
#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
|
||||
|
||||
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
|
||||
#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
|
||||
#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
|
||||
#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
|
||||
#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
|
||||
#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
|
||||
#define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD)
|
||||
|
||||
/*
|
||||
* Incore only flags for quotaoff - these bits get cleared when quota(s)
|
||||
|
@ -584,7 +584,7 @@ xfs_rename(
|
||||
* trans_commit will unlock src_ip, target_ip & decrement
|
||||
* the vnode references.
|
||||
*/
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (target_ip != NULL) {
|
||||
xfs_refcache_purge_ip(target_ip);
|
||||
IRELE(target_ip);
|
||||
|
@ -150,7 +150,7 @@ xfs_growfs_rt_alloc(
|
||||
error = xfs_bmap_finish(&tp, &flist, &committed);
|
||||
if (error)
|
||||
goto error_exit;
|
||||
xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
/*
|
||||
* Now we need to clear the allocated blocks.
|
||||
* Do this one block per transaction, to keep it simple.
|
||||
@ -187,7 +187,7 @@ xfs_growfs_rt_alloc(
|
||||
/*
|
||||
* Commit the transaction.
|
||||
*/
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_trans_commit(tp, 0);
|
||||
}
|
||||
/*
|
||||
* Go on to the next extent, if any.
|
||||
@ -2042,7 +2042,7 @@ xfs_growfs_rt(
|
||||
/*
|
||||
* Commit the transaction.
|
||||
*/
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_trans_commit(tp, 0);
|
||||
}
|
||||
|
||||
if (error)
|
||||
|
@ -83,7 +83,7 @@ xfs_write_clear_setuid(
|
||||
}
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
xfs_trans_set_sync(tp);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
return 0;
|
||||
}
|
||||
@ -164,7 +164,7 @@ xfs_write_sync_logforce(
|
||||
xfs_trans_ihold(tp, ip);
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
xfs_trans_set_sync(tp);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
}
|
||||
|
@ -753,7 +753,6 @@ int
|
||||
_xfs_trans_commit(
|
||||
xfs_trans_t *tp,
|
||||
uint flags,
|
||||
xfs_lsn_t *commit_lsn_p,
|
||||
int *log_flushed)
|
||||
{
|
||||
xfs_log_iovec_t *log_vector;
|
||||
@ -812,8 +811,6 @@ _xfs_trans_commit(
|
||||
xfs_trans_free_busy(tp);
|
||||
xfs_trans_free(tp);
|
||||
XFS_STATS_INC(xs_trans_empty);
|
||||
if (commit_lsn_p)
|
||||
*commit_lsn_p = commit_lsn;
|
||||
return (shutdown);
|
||||
}
|
||||
ASSERT(tp->t_ticket != NULL);
|
||||
@ -864,9 +861,6 @@ _xfs_trans_commit(
|
||||
kmem_free(log_vector, nvec * sizeof(xfs_log_iovec_t));
|
||||
}
|
||||
|
||||
if (commit_lsn_p)
|
||||
*commit_lsn_p = commit_lsn;
|
||||
|
||||
/*
|
||||
* If we got a log write error. Unpin the logitems that we
|
||||
* had pinned, clean up, free trans structure, and return error.
|
||||
|
@ -988,10 +988,8 @@ void xfs_trans_log_efd_extent(xfs_trans_t *,
|
||||
xfs_extlen_t);
|
||||
int _xfs_trans_commit(xfs_trans_t *,
|
||||
uint flags,
|
||||
xfs_lsn_t *,
|
||||
int *);
|
||||
#define xfs_trans_commit(tp, flags, lsn) \
|
||||
_xfs_trans_commit(tp, flags, lsn, NULL)
|
||||
#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL)
|
||||
void xfs_trans_cancel(xfs_trans_t *, int);
|
||||
void xfs_trans_ail_init(struct xfs_mount *);
|
||||
xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
|
||||
|
@ -222,7 +222,7 @@ xfs_dir_ialloc(
|
||||
}
|
||||
|
||||
ntp = xfs_trans_dup(tp);
|
||||
code = xfs_trans_commit(tp, 0, NULL);
|
||||
code = xfs_trans_commit(tp, 0);
|
||||
tp = ntp;
|
||||
if (committed != NULL) {
|
||||
*committed = 1;
|
||||
@ -420,7 +420,11 @@ xfs_truncate_file(
|
||||
* in a transaction.
|
||||
*/
|
||||
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
||||
xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
|
||||
error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
|
||||
if (error) {
|
||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
||||
return error;
|
||||
}
|
||||
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
|
||||
if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
|
||||
@ -460,8 +464,7 @@ xfs_truncate_file(
|
||||
XFS_TRANS_ABORT);
|
||||
} else {
|
||||
xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
}
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
|
||||
|
||||
|
@ -696,7 +696,7 @@ xfs_unmount_flush(
|
||||
bhv_vnode_t *rvp = XFS_ITOV(rip);
|
||||
int error;
|
||||
|
||||
xfs_ilock(rip, XFS_ILOCK_EXCL);
|
||||
xfs_ilock(rip, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||
xfs_iflock(rip);
|
||||
|
||||
/*
|
||||
@ -1147,7 +1147,7 @@ xfs_sync_inodes(
|
||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||
bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
|
||||
} else {
|
||||
bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
|
||||
error = bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
|
||||
}
|
||||
|
||||
xfs_ilock(ip, XFS_ILOCK_SHARED);
|
||||
@ -1539,7 +1539,7 @@ xfs_syncsub(
|
||||
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ihold(tp, ip);
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ xfs_getattr(
|
||||
if (!(flags & ATTR_LAZY))
|
||||
xfs_ilock(ip, XFS_ILOCK_SHARED);
|
||||
|
||||
vap->va_size = ip->i_d.di_size;
|
||||
vap->va_size = XFS_ISIZE(ip);
|
||||
if (vap->va_mask == XFS_AT_SIZE)
|
||||
goto all_done;
|
||||
|
||||
@ -496,7 +496,7 @@ xfs_setattr(
|
||||
if (mask & XFS_AT_SIZE) {
|
||||
/* Short circuit the truncate case for zero length files */
|
||||
if ((vap->va_size == 0) &&
|
||||
(ip->i_d.di_size == 0) && (ip->i_d.di_nextents == 0)) {
|
||||
(ip->i_size == 0) && (ip->i_d.di_nextents == 0)) {
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
lock_flags &= ~XFS_ILOCK_EXCL;
|
||||
if (mask & XFS_AT_CTIME)
|
||||
@ -614,7 +614,7 @@ xfs_setattr(
|
||||
*/
|
||||
if (mask & XFS_AT_SIZE) {
|
||||
code = 0;
|
||||
if ((vap->va_size > ip->i_d.di_size) &&
|
||||
if ((vap->va_size > ip->i_size) &&
|
||||
(flags & ATTR_NOSIZETOK) == 0) {
|
||||
code = xfs_igrow_start(ip, vap->va_size, credp);
|
||||
}
|
||||
@ -654,10 +654,10 @@ xfs_setattr(
|
||||
* Truncate file. Must have write permission and not be a directory.
|
||||
*/
|
||||
if (mask & XFS_AT_SIZE) {
|
||||
if (vap->va_size > ip->i_d.di_size) {
|
||||
if (vap->va_size > ip->i_size) {
|
||||
xfs_igrow_finish(tp, ip, vap->va_size,
|
||||
!(flags & ATTR_DMI));
|
||||
} else if ((vap->va_size <= ip->i_d.di_size) ||
|
||||
} else if ((vap->va_size <= ip->i_size) ||
|
||||
((vap->va_size == 0) && ip->i_d.di_nextents)) {
|
||||
/*
|
||||
* signal a sync transaction unless
|
||||
@ -873,7 +873,7 @@ xfs_setattr(
|
||||
if (mp->m_flags & XFS_MOUNT_WSYNC)
|
||||
xfs_trans_set_sync(tp);
|
||||
|
||||
code = xfs_trans_commit(tp, commit_flags, NULL);
|
||||
code = xfs_trans_commit(tp, commit_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1176,7 +1176,7 @@ xfs_fsync(
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
if (flag & FSYNC_WAIT)
|
||||
xfs_trans_set_sync(tp);
|
||||
error = _xfs_trans_commit(tp, 0, NULL, &log_flushed);
|
||||
error = _xfs_trans_commit(tp, 0, &log_flushed);
|
||||
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
@ -1221,7 +1221,7 @@ xfs_inactive_free_eofblocks(
|
||||
* Figure out if there are any blocks beyond the end
|
||||
* of the file. If not, then there is nothing to do.
|
||||
*/
|
||||
end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_d.di_size));
|
||||
end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_size));
|
||||
last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
|
||||
map_len = last_fsb - end_fsb;
|
||||
if (map_len <= 0)
|
||||
@ -1257,8 +1257,12 @@ xfs_inactive_free_eofblocks(
|
||||
* do that within a transaction.
|
||||
*/
|
||||
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
||||
xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
|
||||
ip->i_d.di_size);
|
||||
error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
|
||||
ip->i_size);
|
||||
if (error) {
|
||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = xfs_trans_reserve(tp, 0,
|
||||
XFS_ITRUNCATE_LOG_RES(mp),
|
||||
@ -1278,7 +1282,7 @@ xfs_inactive_free_eofblocks(
|
||||
xfs_trans_ihold(tp, ip);
|
||||
|
||||
error = xfs_itruncate_finish(&tp, ip,
|
||||
ip->i_d.di_size,
|
||||
ip->i_size,
|
||||
XFS_DATA_FORK,
|
||||
0);
|
||||
/*
|
||||
@ -1291,8 +1295,7 @@ xfs_inactive_free_eofblocks(
|
||||
XFS_TRANS_ABORT));
|
||||
} else {
|
||||
error = xfs_trans_commit(tp,
|
||||
XFS_TRANS_RELEASE_LOG_RES,
|
||||
NULL);
|
||||
XFS_TRANS_RELEASE_LOG_RES);
|
||||
}
|
||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
|
||||
}
|
||||
@ -1406,7 +1409,7 @@ xfs_inactive_symlink_rmt(
|
||||
* we need to unlock the inode since the new transaction doesn't
|
||||
* have the inode attached.
|
||||
*/
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
tp = ntp;
|
||||
if (error) {
|
||||
ASSERT(XFS_FORCED_SHUTDOWN(mp));
|
||||
@ -1503,7 +1506,7 @@ xfs_inactive_attrs(
|
||||
tp = *tpp;
|
||||
mp = ip->i_mount;
|
||||
ASSERT(ip->i_d.di_forkoff != 0);
|
||||
xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
|
||||
error = xfs_attr_inactive(ip);
|
||||
@ -1565,7 +1568,7 @@ xfs_release(
|
||||
|
||||
if (ip->i_d.di_nlink != 0) {
|
||||
if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
|
||||
((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
|
||||
((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
|
||||
ip->i_delayed_blks > 0)) &&
|
||||
(ip->i_df.if_flags & XFS_IFEXTENTS)) &&
|
||||
(!(ip->i_d.di_flags &
|
||||
@ -1626,8 +1629,8 @@ xfs_inactive(
|
||||
* only one with a reference to the inode.
|
||||
*/
|
||||
truncate = ((ip->i_d.di_nlink == 0) &&
|
||||
((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0) ||
|
||||
(ip->i_delayed_blks > 0)) &&
|
||||
((ip->i_d.di_size != 0) || (ip->i_size != 0) ||
|
||||
(ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) &&
|
||||
((ip->i_d.di_mode & S_IFMT) == S_IFREG));
|
||||
|
||||
mp = ip->i_mount;
|
||||
@ -1645,7 +1648,7 @@ xfs_inactive(
|
||||
|
||||
if (ip->i_d.di_nlink != 0) {
|
||||
if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
|
||||
((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
|
||||
((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
|
||||
ip->i_delayed_blks > 0)) &&
|
||||
(ip->i_df.if_flags & XFS_IFEXTENTS) &&
|
||||
(!(ip->i_d.di_flags &
|
||||
@ -1675,7 +1678,11 @@ xfs_inactive(
|
||||
*/
|
||||
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
||||
|
||||
xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
|
||||
error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
|
||||
if (error) {
|
||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
||||
return VN_INACTIVE_CACHE;
|
||||
}
|
||||
|
||||
error = xfs_trans_reserve(tp, 0,
|
||||
XFS_ITRUNCATE_LOG_RES(mp),
|
||||
@ -1790,7 +1797,7 @@ xfs_inactive(
|
||||
* nothing we can do except to try to keep going.
|
||||
*/
|
||||
(void) xfs_bmap_finish(&tp, &free_list, &committed);
|
||||
(void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
(void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
}
|
||||
/*
|
||||
* Release the dquots held by inode, if any.
|
||||
@ -1940,7 +1947,7 @@ xfs_create(
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||
|
||||
XFS_BMAP_INIT(&free_list, &first_block);
|
||||
|
||||
@ -2026,7 +2033,7 @@ xfs_create(
|
||||
goto abort_rele;
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (error) {
|
||||
IRELE(ip);
|
||||
tp = NULL;
|
||||
@ -2121,7 +2128,6 @@ int xfs_rm_attempts;
|
||||
STATIC int
|
||||
xfs_lock_dir_and_entry(
|
||||
xfs_inode_t *dp,
|
||||
bhv_vname_t *dentry,
|
||||
xfs_inode_t *ip) /* inode of entry 'name' */
|
||||
{
|
||||
int attempts;
|
||||
@ -2135,7 +2141,7 @@ xfs_lock_dir_and_entry(
|
||||
attempts = 0;
|
||||
|
||||
again:
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||
|
||||
e_inum = ip->i_ino;
|
||||
|
||||
@ -2203,6 +2209,21 @@ int xfs_lots_retries;
|
||||
int xfs_lock_delays;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bump the subclass so xfs_lock_inodes() acquires each lock with
|
||||
* a different value
|
||||
*/
|
||||
static inline int
|
||||
xfs_lock_inumorder(int lock_mode, int subclass)
|
||||
{
|
||||
if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
|
||||
lock_mode |= (subclass + XFS_IOLOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
|
||||
if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))
|
||||
lock_mode |= (subclass + XFS_ILOCK_INUMORDER) << XFS_ILOCK_SHIFT;
|
||||
|
||||
return lock_mode;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following routine will lock n inodes in exclusive mode.
|
||||
* We assume the caller calls us with the inodes in i_ino order.
|
||||
@ -2270,7 +2291,7 @@ xfs_lock_inodes(
|
||||
* that is in the AIL.
|
||||
*/
|
||||
ASSERT(i != 0);
|
||||
if (!xfs_ilock_nowait(ips[i], lock_mode)) {
|
||||
if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
|
||||
attempts++;
|
||||
|
||||
/*
|
||||
@ -2305,7 +2326,7 @@ xfs_lock_inodes(
|
||||
goto again;
|
||||
}
|
||||
} else {
|
||||
xfs_ilock(ips[i], lock_mode);
|
||||
xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2440,7 +2461,7 @@ xfs_remove(
|
||||
return error;
|
||||
}
|
||||
|
||||
error = xfs_lock_dir_and_entry(dp, dentry, ip);
|
||||
error = xfs_lock_dir_and_entry(dp, ip);
|
||||
if (error) {
|
||||
REMOVE_DEBUG_TRACE(__LINE__);
|
||||
xfs_trans_cancel(tp, cancel_flags);
|
||||
@ -2511,7 +2532,7 @@ xfs_remove(
|
||||
goto error_rele;
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (error) {
|
||||
IRELE(ip);
|
||||
goto std_return;
|
||||
@ -2719,7 +2740,7 @@ xfs_link(
|
||||
goto abort_return;
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (error)
|
||||
goto std_return;
|
||||
|
||||
@ -2839,7 +2860,7 @@ xfs_mkdir(
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||
|
||||
/*
|
||||
* Check for directory link count overflow.
|
||||
@ -2936,7 +2957,7 @@ xfs_mkdir(
|
||||
goto error2;
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
XFS_QM_DQRELE(mp, udqp);
|
||||
XFS_QM_DQRELE(mp, gdqp);
|
||||
if (error) {
|
||||
@ -3096,7 +3117,7 @@ xfs_rmdir(
|
||||
* that the directory entry for the child directory inode has
|
||||
* not changed while we were obtaining a log reservation.
|
||||
*/
|
||||
error = xfs_lock_dir_and_entry(dp, dentry, cdp);
|
||||
error = xfs_lock_dir_and_entry(dp, cdp);
|
||||
if (error) {
|
||||
xfs_trans_cancel(tp, cancel_flags);
|
||||
IRELE(cdp);
|
||||
@ -3190,7 +3211,7 @@ xfs_rmdir(
|
||||
goto std_return;
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (error) {
|
||||
IRELE(cdp);
|
||||
goto std_return;
|
||||
@ -3393,7 +3414,7 @@ xfs_symlink(
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
||||
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||
|
||||
/*
|
||||
* Check whether the directory allows new symlinks or not.
|
||||
@ -3535,7 +3556,7 @@ xfs_symlink(
|
||||
if (error) {
|
||||
goto error2;
|
||||
}
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
XFS_QM_DQRELE(mp, udqp);
|
||||
XFS_QM_DQRELE(mp, gdqp);
|
||||
|
||||
@ -3790,7 +3811,7 @@ xfs_set_dmattrs (
|
||||
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
IHOLD(ip);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -4049,14 +4070,14 @@ xfs_alloc_file_space(
|
||||
allocatesize_fsb = XFS_B_TO_FSB(mp, count);
|
||||
|
||||
/* Generate a DMAPI event if needed. */
|
||||
if (alloc_type != 0 && offset < ip->i_d.di_size &&
|
||||
if (alloc_type != 0 && offset < ip->i_size &&
|
||||
(attr_flags&ATTR_DMI) == 0 &&
|
||||
DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
|
||||
xfs_off_t end_dmi_offset;
|
||||
|
||||
end_dmi_offset = offset+len;
|
||||
if (end_dmi_offset > ip->i_d.di_size)
|
||||
end_dmi_offset = ip->i_d.di_size;
|
||||
if (end_dmi_offset > ip->i_size)
|
||||
end_dmi_offset = ip->i_size;
|
||||
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
|
||||
offset, end_dmi_offset - offset,
|
||||
0, NULL);
|
||||
@ -4148,7 +4169,7 @@ xfs_alloc_file_space(
|
||||
goto error0;
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
if (error) {
|
||||
break;
|
||||
@ -4283,7 +4304,6 @@ xfs_free_file_space(
|
||||
int error;
|
||||
xfs_fsblock_t firstfsb;
|
||||
xfs_bmap_free_t free_list;
|
||||
xfs_off_t ilen;
|
||||
xfs_bmbt_irec_t imap;
|
||||
xfs_off_t ioffset;
|
||||
xfs_extlen_t mod=0;
|
||||
@ -4312,11 +4332,11 @@ xfs_free_file_space(
|
||||
end_dmi_offset = offset + len;
|
||||
endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
|
||||
|
||||
if (offset < ip->i_d.di_size &&
|
||||
if (offset < ip->i_size &&
|
||||
(attr_flags & ATTR_DMI) == 0 &&
|
||||
DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
|
||||
if (end_dmi_offset > ip->i_d.di_size)
|
||||
end_dmi_offset = ip->i_d.di_size;
|
||||
if (end_dmi_offset > ip->i_size)
|
||||
end_dmi_offset = ip->i_size;
|
||||
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
|
||||
offset, end_dmi_offset - offset,
|
||||
AT_DELAY_FLAG(attr_flags), NULL);
|
||||
@ -4332,16 +4352,15 @@ xfs_free_file_space(
|
||||
}
|
||||
|
||||
rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
|
||||
ilen = len + (offset & (rounding - 1));
|
||||
ioffset = offset & ~(rounding - 1);
|
||||
if (ilen & (rounding - 1))
|
||||
ilen = (ilen + rounding) & ~(rounding - 1);
|
||||
|
||||
if (VN_CACHED(vp) != 0) {
|
||||
xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
|
||||
ctooff(offtoct(ioffset)), -1);
|
||||
bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
|
||||
error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
if (error)
|
||||
goto out_unlock_iolock;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4455,7 +4474,7 @@ xfs_free_file_space(
|
||||
goto error0;
|
||||
}
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
|
||||
@ -4533,7 +4552,7 @@ xfs_change_file_space(
|
||||
bf->l_start += offset;
|
||||
break;
|
||||
case 2: /*SEEK_END*/
|
||||
bf->l_start += ip->i_d.di_size;
|
||||
bf->l_start += ip->i_size;
|
||||
break;
|
||||
default:
|
||||
return XFS_ERROR(EINVAL);
|
||||
@ -4550,7 +4569,7 @@ xfs_change_file_space(
|
||||
bf->l_whence = 0;
|
||||
|
||||
startoffset = bf->l_start;
|
||||
fsize = ip->i_d.di_size;
|
||||
fsize = ip->i_size;
|
||||
|
||||
/*
|
||||
* XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve
|
||||
@ -4649,7 +4668,7 @@ xfs_change_file_space(
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
xfs_trans_set_sync(tp);
|
||||
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
error = xfs_trans_commit(tp, 0);
|
||||
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user