]> err.no Git - linux-2.6/blobdiff - fs/xfs/xfs_inode.c
[PATCH] vt: fix possible memory corruption in complement_pos
[linux-2.6] / fs / xfs / xfs_inode.c
index 99421638e860c87d76659939dd0284cf5748a158..34bdf5909687b30d0619e3e9f6d42feee4de4098 100644 (file)
@@ -1202,26 +1202,32 @@ xfs_ialloc(
        case S_IFREG:
        case S_IFDIR:
                if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
-                       if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
-                               if ((mode & S_IFMT) == S_IFDIR) {
-                                       ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT;
-                               } else {
-                                       ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
+                       uint    di_flags = 0;
+
+                       if ((mode & S_IFMT) == S_IFDIR) {
+                               if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
+                                       di_flags |= XFS_DIFLAG_RTINHERIT;
+                       } else {
+                               if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
+                                       di_flags |= XFS_DIFLAG_REALTIME;
                                        ip->i_iocore.io_flags |= XFS_IOCORE_RT;
                                }
                        }
                        if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
                            xfs_inherit_noatime)
-                               ip->i_d.di_flags |= XFS_DIFLAG_NOATIME;
+                               di_flags |= XFS_DIFLAG_NOATIME;
                        if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
                            xfs_inherit_nodump)
-                               ip->i_d.di_flags |= XFS_DIFLAG_NODUMP;
+                               di_flags |= XFS_DIFLAG_NODUMP;
                        if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
                            xfs_inherit_sync)
-                               ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
+                               di_flags |= XFS_DIFLAG_SYNC;
                        if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
                            xfs_inherit_nosymlinks)
-                               ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS;
+                               di_flags |= XFS_DIFLAG_NOSYMLINKS;
+                       if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+                               di_flags |= XFS_DIFLAG_PROJINHERIT;
+                       ip->i_d.di_flags |= di_flags;
                }
                /* FALLTHROUGH */
        case S_IFLNK:
@@ -3556,107 +3562,43 @@ corrupt_out:
 
 
 /*
- * Flush all inactive inodes in mp.  Return true if no user references
- * were found, false otherwise.
+ * Flush all inactive inodes in mp.
  */
-int
+void
 xfs_iflush_all(
-       xfs_mount_t     *mp,
-       int             flag)
+       xfs_mount_t     *mp)
 {
-       int             busy;
-       int             done;
-       int             purged;
        xfs_inode_t     *ip;
-       vmap_t          vmap;
        vnode_t         *vp;
 
-       busy = done = 0;
-       while (!done) {
-               purged = 0;
-               XFS_MOUNT_ILOCK(mp);
-               ip = mp->m_inodes;
-               if (ip == NULL) {
-                       break;
-               }
-               do {
-                       /* Make sure we skip markers inserted by sync */
-                       if (ip->i_mount == NULL) {
-                               ip = ip->i_mnext;
-                               continue;
-                       }
-
-                       /*
-                        * It's up to our caller to purge the root
-                        * and quota vnodes later.
-                        */
-                       vp = XFS_ITOV_NULL(ip);
+ again:
+       XFS_MOUNT_ILOCK(mp);
+       ip = mp->m_inodes;
+       if (ip == NULL)
+               goto out;
 
-                       if (!vp) {
-                               XFS_MOUNT_IUNLOCK(mp);
-                               xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
-                               purged = 1;
-                               break;
-                       }
-
-                       if (vn_count(vp) != 0) {
-                               if (vn_count(vp) == 1 &&
-                                   (ip == mp->m_rootip ||
-                                    (mp->m_quotainfo &&
-                                     (ip->i_ino == mp->m_sb.sb_uquotino ||
-                                      ip->i_ino == mp->m_sb.sb_gquotino)))) {
+       do {
+               /* Make sure we skip markers inserted by sync */
+               if (ip->i_mount == NULL) {
+                       ip = ip->i_mnext;
+                       continue;
+               }
 
-                                       ip = ip->i_mnext;
-                                       continue;
-                               }
-                               if (!(flag & XFS_FLUSH_ALL)) {
-                                       busy = 1;
-                                       done = 1;
-                                       break;
-                               }
-                               /*
-                                * Ignore busy inodes but continue flushing
-                                * others.
-                                */
-                               ip = ip->i_mnext;
-                               continue;
-                       }
-                       /*
-                        * Sample vp mapping while holding mp locked on MP
-                        * systems, so we don't purge a reclaimed or
-                        * nonexistent vnode.  We break from the loop
-                        * since we know that we modify
-                        * it by pulling ourselves from it in xfs_reclaim()
-                        * called via vn_purge() below.  Set ip to the next
-                        * entry in the list anyway so we'll know below
-                        * whether we reached the end or not.
-                        */
-                       VMAP(vp, vmap);
+               vp = XFS_ITOV_NULL(ip);
+               if (!vp) {
                        XFS_MOUNT_IUNLOCK(mp);
+                       xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
+                       goto again;
+               }
 
-                       vn_purge(vp, &vmap);
+               ASSERT(vn_count(vp) == 0);
 
-                       purged = 1;
-                       break;
-               } while (ip != mp->m_inodes);
-               /*
-                * We need to distinguish between when we exit the loop
-                * after a purge and when we simply hit the end of the
-                * list.  We can't use the (ip == mp->m_inodes) test,
-                * because when we purge an inode at the start of the list
-                * the next inode on the list becomes mp->m_inodes.  That
-                * would cause such a test to bail out early.  The purged
-                * variable tells us how we got out of the loop.
-                */
-               if (!purged) {
-                       done = 1;
-               }
-       }
+               ip = ip->i_mnext;
+       } while (ip != mp->m_inodes);
+ out:
        XFS_MOUNT_IUNLOCK(mp);
-       return !busy;
 }
 
-
 /*
  * xfs_iaccess: check accessibility of inode for mode.
  */