]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://oss.sgi.com:8090/xfs/xfs-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 8 May 2007 18:59:33 +0000 (11:59 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 8 May 2007 18:59:33 +0000 (11:59 -0700)
* 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

44 files changed:
fs/xfs/linux-2.6/mrlock.h
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_buf.h
fs/xfs/linux-2.6/xfs_fs_subr.c
fs/xfs/linux-2.6/xfs_fs_subr.h
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_vnode.h
fs/xfs/quota/xfs_dquot.c
fs/xfs/quota/xfs_qm.c
fs/xfs/quota/xfs_qm_syscalls.c
fs/xfs/quota/xfs_trans_dquot.c
fs/xfs/support/debug.c
fs/xfs/support/debug.h
fs/xfs/xfs_alloc.c
fs/xfs/xfs_attr.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_dir2_block.c
fs/xfs/xfs_dir2_data.c
fs/xfs/xfs_dir2_data.h
fs/xfs/xfs_dir2_leaf.c
fs/xfs/xfs_dir2_node.c
fs/xfs/xfs_error.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_iget.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_iocore.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_iomap.h
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_qmops.c
fs/xfs/xfs_quota.h
fs/xfs/xfs_rename.c
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_rw.c
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans.h
fs/xfs/xfs_utils.c
fs/xfs/xfs_vfsops.c
fs/xfs/xfs_vnodeops.c

index af168a1a98c1bf5ad6a56e1f2f513bca584f632d..c110bb002665af5dce7d73d17cbb47943826d71d 100644 (file)
@@ -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);
index 143ffc851c9d21376b1c928394544d59443b87e9..4475588e973a4aa922144c80b39df5948b5199ef 100644 (file)
@@ -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,
index 69e9e80735d2c5e4861dfe0545e657b9376bee46..fe4f66a5af145a31a61afac29b440c4ce1f2d5d6 100644 (file)
@@ -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
index 9e8ef8fef39fff7f5c58d00209b42bdd0d60569e..b6241f6201a5e89803bc5e63dad2e336850765a2 100644 (file)
@@ -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)
index dc0562828e760958b22242153111e928f317dbd5..2eb87cd082af5592bc354b8d1698a7f3f7b60910 100644 (file)
@@ -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;
 }
index aee9ccdd18f76facd65e8a0b6d92033f5b91c5d0..c1b53118a3030d0343cc3408aae53ddb267ef922 100644 (file)
@@ -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__ */
index 558076dd07522af6566d8e9468566a31c55bdd44..86fb671a8bccf80ba0eba43d98e3fb4bee4ad41b 100644 (file)
@@ -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) {
+       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);
-       } else {
-               iolock = XFS_IOLOCK_SHARED;
-               locktype = VRWLOCK_WRITE_DIRECT;
        }
 
        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 @@ start:
                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 @@ start:
                                      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 @@ start:
                 * 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 @@ start:
         * 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 @@ start:
                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 @@ retry:
        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 @@ retry:
                        pos += ret;
                        count -= ret;
 
-                       need_i_mutex = 1;
                        ioflags &= ~IO_ISDIRECT;
                        xfs_iunlock(xip, iolock);
                        goto relock;
@@ -854,12 +870,12 @@ retry:
                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 @@ retry:
        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 @@ retry:
 
                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;
 }
 
index b76118cf48978b72f28368f54f080da6623b8e45..d1b2d01843d177d2f75b8bed5f0c07d3061ba519 100644 (file)
@@ -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);
index 4adaf13aac6f783fa67aa8071e2cf934473d7bd4..cfdd35ee9f7a1e192aa797abe8659c870e789967 100644 (file)
@@ -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;
        }
 
index 1de2acdc7f70eab902b24c403b54962bb6b95d74..3e4a8ad8a34c3180eff417f732f11d5df320b722 100644 (file)
@@ -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;
 }
index 716f562aa8b2f036c46c7dd1951b0185ae04d5d0..2df67fd913e5f9c3f5efa5ad64c436cf5b920cb8 100644 (file)
@@ -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);
index d7491e7b1f3bca3c1a29d13585b9f914f9cf761f..7de6874bf1b8871c7823354494b6e8adb3c00580 100644 (file)
@@ -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);
index 08bbd3cb87aefb055088902550405c49a92be228..f45a49ffd3a34907f6b1ca2aceaea7dce40e2133 100644 (file)
@@ -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 */
index 2a70cc605ae34b5298ed8e4ebd0a912d9153fd37..a27a7c8c05264c1e651e0c0651d9caa4eec64c7f 100644 (file)
@@ -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
index e80dda3437d196345b0d19cded4cac518b4e0eda..8e9a40aa0cd3fec9c14ffa158730ef801d6f598a 100644 (file)
@@ -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.
index 9d358ffce4e5101d999570b3af021be3705d797b..7ce44a7b88a246de3effe15bd9ab8f0aa680b095 100644 (file)
@@ -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);
index 8eab73e8340ac223c00d617750845d1cee7c8fbd..81f45dae1c57f668c09786b405b2b805862bb556 100644 (file)
@@ -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;
index 87795188cedf31dd4d7edaa3a27848b5bf1330df..b1ea26e40aaf217815cca6a6a8f3ef9340750bab 100644 (file)
@@ -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,
index b847e6a7a3f03ba3a5e0f8e200414e97347e0609..de35d18cc002c5eefcf7c631143bdfacef753bf9 100644 (file)
@@ -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:
index 9d7438bba30d73b0c16ddb8686db9fd0fd6d5f70..3accc1dcd6c9919658545237699ace1d0302a028 100644 (file)
@@ -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);
        /*
index f7c799217072066518a560965c907cc8f428ef35..c211c37ef67cb307fa70a1a60b66635c8c39947a 100644 (file)
@@ -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
index a6ae2d21c40abf9d3ca6f7fa0402b084a114898a..c94c9099cfb13c7c271857f2c518e39aaf9ebc52 100644 (file)
@@ -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,
index b1cf1fbf423d346aa1064d412337b1c05d4dd962..db14ea71459f0c8086e00e0d26c40498cf845da8 100644 (file)
@@ -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);
        /*
index 9ca71719b683b041ff67795d316f55c2b96008d7..d083c38199343e0eacf91007c8e41180e79fcb54 100644 (file)
@@ -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.
         */
index b1af54464f0078006146cc790d664a6989f68350..8c433163133734d5905741bf1226c128319e82ab 100644 (file)
@@ -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));
index 32c37c1c47ab341fed758b6e5fb8bea04742906d..b599e6be9ec18f146f8527c7e361c5dc94f45c30 100644 (file)
@@ -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);
 }
index c1c89dac19cceceed3aff020651b9eac349cf98e..114433a22baafcfba0f51c73d15eeab21f7afe29 100644 (file)
@@ -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)) {
index 3da9829c19d5e80af53be627dc8b5b1a0b594ee0..3ca5d43b83456ccdf8ca4c61f13b363d13c9e76c 100644 (file)
@@ -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);
 
index bc823720d88f4116bff4eccc42fb07b6d1ab971d..f75afecef8e7b02d78ebb2c4d45a1e381af2ac8c 100644 (file)
@@ -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 *);
index 06d710c9ce4b5dec4c9f4b72cadde1d5aa39c07a..81548ec72ba6073b2b910b79d74e8d763ce06fae 100644 (file)
@@ -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
index cc6a7b5a99129226e91c123429f83e78bd42ab66..3f2b9f2a7b949d01e0f01f74b21e9b42fd76ae35 100644 (file)
@@ -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);
index 3ce204a524b0665df59272cdc4425d0772f95619..df441ee936b2f183a8706877245fd802f50178dc 100644 (file)
@@ -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  */
index ca74d3f5910e75cd4810a083651c7073b71ddb3b..080fabf61c92d0e23ffe07dd0069a12eee5f8a88 100644 (file)
@@ -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;
                }
 
index 3bed0cf0d8afa2eaa87a98b00be0a10034c701b7..f5aa3ef855fbb5e793d4d7f8eeecb507a5dc99fa 100644 (file)
@@ -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);
 }
 
 
index 320d63ff9ca2ed97ca60cf0b93caad1d989faae6..0d594ed7efef1d61a3ac4d8e7ac5ddc59b671fe7 100644 (file)
@@ -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;
 }
 
index 9dcb32aa4e2ea2a25eac703996bedfc8bb219421..6f14df976f73c71e274a537406b4d1234cfbdc30 100644 (file)
@@ -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)
index 4c6573d784cd4bfd48cb0887c0ae664fcb11b965..7679d7a7022d36ea491616d4aa6cca83bc0e3165 100644 (file)
@@ -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);
index 6fff19dc3cf96e8cb6d00fabe3dd88d176847f46..b3a5f07bd0734cf189ccf00e076931906dae771d 100644 (file)
@@ -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)
index 1ea7c0ca6ae0f8d5ec63d8ab6aca7706b13e1626..905d1c008be73056458534b58636de0c1247946a 100644 (file)
@@ -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);
                }
        }
index 301ff9445b6f84cb570833ec1990df768fbed779..cc2d60951e21e0a3b5655db08c03e1eb83e0d305 100644 (file)
@@ -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 @@ shut_us_down:
                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 @@ shut_us_down:
                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.
index f1d7ab236726ce20ec98160cdb3541d6f5da50ed..7dfcc450366f79338c3cc796268d8de26ef6af16 100644 (file)
@@ -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);
index 9014d7e444885faa447c2a7a987c1f4bdcd1bf8e..20ffec308e1e906cd09d661c3a9d409f97b5a8c3 100644 (file)
@@ -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);
 
index 29f72f613782a6a1a2d09bc6570e880d65af313a..65c561201cb879da8a83d1df3c40fe2af7927d96 100644 (file)
@@ -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);
        }
index 52c41714ec54c5a76cb5dbfe16a51233e44bf85f..de17aed578f04878d7942cd113103fc19ef5619f 100644 (file)
@@ -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 @@ again:
                         * 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 @@ again:
                                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 @@ retry:
                        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);