Loading fs/xfs/linux-2.6/xfs_ioctl.c +44 −62 Original line number Diff line number Diff line Loading @@ -78,92 +78,74 @@ xfs_find_handle( int hsize; xfs_handle_t handle; struct inode *inode; memset((char *)&handle, 0, sizeof(handle)); switch (cmd) { case XFS_IOC_PATH_TO_FSHANDLE: case XFS_IOC_PATH_TO_HANDLE: { struct file *file = NULL; struct path path; int error = user_lpath((const char __user *)hreq->path, &path); if (error) return error; ASSERT(path.dentry); ASSERT(path.dentry->d_inode); inode = igrab(path.dentry->d_inode); path_put(&path); break; } case XFS_IOC_FD_TO_HANDLE: { struct file *file; int error; struct xfs_inode *ip; if (cmd == XFS_IOC_FD_TO_HANDLE) { file = fget(hreq->fd); if (!file) return -EBADF; ASSERT(file->f_path.dentry); ASSERT(file->f_path.dentry->d_inode); inode = igrab(file->f_path.dentry->d_inode); fput(file); break; inode = file->f_path.dentry->d_inode; } else { error = user_lpath((const char __user *)hreq->path, &path); if (error) return error; inode = path.dentry->d_inode; } ip = XFS_I(inode); default: ASSERT(0); return -XFS_ERROR(EINVAL); } /* * We can only generate handles for inodes residing on a XFS filesystem, * and only for regular files, directories or symbolic links. */ error = -EINVAL; if (inode->i_sb->s_magic != XFS_SB_MAGIC) goto out_put; if (inode->i_sb->s_magic != XFS_SB_MAGIC) { /* we're not in XFS anymore, Toto */ iput(inode); return -XFS_ERROR(EINVAL); } error = -EBADF; if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) && !S_ISLNK(inode->i_mode)) goto out_put; switch (inode->i_mode & S_IFMT) { case S_IFREG: case S_IFDIR: case S_IFLNK: break; default: iput(inode); return -XFS_ERROR(EBADF); } /* now we can grab the fsid */ memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid, sizeof(xfs_fsid_t)); hsize = sizeof(xfs_fsid_t); memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t)); if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { xfs_inode_t *ip = XFS_I(inode); if (cmd == XFS_IOC_PATH_TO_FSHANDLE) { /* * This handle only contains an fsid, zero the rest. */ memset(&handle.ha_fid, 0, sizeof(handle.ha_fid)); hsize = sizeof(xfs_fsid_t); } else { int lock_mode; /* need to get access to the xfs_inode to read the generation */ lock_mode = xfs_ilock_map_shared(ip); /* fill in fid section of handle from inode */ handle.ha_fid.fid_len = sizeof(xfs_fid_t) - sizeof(handle.ha_fid.fid_len); handle.ha_fid.fid_pad = 0; handle.ha_fid.fid_gen = ip->i_d.di_gen; handle.ha_fid.fid_ino = ip->i_ino; xfs_iunlock_map_shared(ip, lock_mode); hsize = XFS_HSIZE(handle); } /* now copy our handle into the user buffer & write out the size */ error = -EFAULT; if (copy_to_user(hreq->ohandle, &handle, hsize) || copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) { iput(inode); return -XFS_ERROR(EFAULT); } copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) goto out_put; iput(inode); return 0; error = 0; out_put: if (cmd == XFS_IOC_FD_TO_HANDLE) fput(file); else path_put(&path); return error; } /* Loading fs/xfs/linux-2.6/xfs_super.c +37 −6 Original line number Diff line number Diff line Loading @@ -990,26 +990,57 @@ xfs_fs_write_inode( int sync) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; int error = 0; int flags = 0; xfs_itrace_entry(ip); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); if (sync) { error = xfs_wait_on_pages(ip, 0, -1); if (error) goto out_error; flags |= FLUSH_SYNC; goto out; } /* * Bypass inodes which have already been cleaned by * the inode flush clustering code inside xfs_iflush */ if (xfs_inode_clean(ip)) goto out; /* * We make this non-blocking if the inode is contended, return * EAGAIN to indicate to the caller that they did not succeed. * This prevents the flush path from blocking on inodes inside * another operation right now, they get caught later by xfs_sync. */ if (sync) { xfs_ilock(ip, XFS_ILOCK_SHARED); xfs_iflock(ip); error = xfs_iflush(ip, XFS_IFLUSH_SYNC); } else { error = EAGAIN; if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) goto out; if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) goto out_unlock; error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK); } error = xfs_inode_flush(ip, flags); out_error: out_unlock: xfs_iunlock(ip, XFS_ILOCK_SHARED); out: /* * if we failed to write out the inode then mark * it dirty again so we'll try again later. */ if (error) xfs_mark_inode_dirty_sync(ip); return -error; } Loading fs/xfs/linux-2.6/xfs_vnode.h +0 −5 Original line number Diff line number Diff line Loading @@ -40,11 +40,6 @@ struct attrlist_cursor_kern; #define IO_ISDIRECT 0x00004 /* bypass page cache */ #define IO_INVIS 0x00020 /* don't update inode timestamps */ /* * Flags for xfs_inode_flush */ #define FLUSH_SYNC 1 /* wait for flush to complete */ /* * Flush/Invalidate options for vop_toss/flush/flushinval_pages. */ Loading fs/xfs/quota/xfs_qm.c +44 −102 Original line number Diff line number Diff line Loading @@ -632,7 +632,6 @@ xfs_qm_dqattach_one( xfs_dqid_t id, uint type, uint doalloc, uint dolock, xfs_dquot_t *udqhint, /* hint */ xfs_dquot_t **IO_idqpp) { Loading @@ -641,16 +640,16 @@ xfs_qm_dqattach_one( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); error = 0; /* * See if we already have it in the inode itself. IO_idqpp is * &i_udquot or &i_gdquot. This made the code look weird, but * made the logic a lot simpler. */ if ((dqp = *IO_idqpp)) { if (dolock) xfs_dqlock(dqp); dqp = *IO_idqpp; if (dqp) { xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); goto done; return 0; } /* Loading @@ -659,38 +658,38 @@ xfs_qm_dqattach_one( * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside * the user dquot. */ ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); if (udqhint && !dolock) if (udqhint) { ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); xfs_dqlock(udqhint); /* * No need to take dqlock to look at the id. * * The ID can't change until it gets reclaimed, and it won't * be reclaimed as long as we have a ref from inode and we hold * the ilock. * be reclaimed as long as we have a ref from inode and we * hold the ilock. */ if (udqhint && (dqp = udqhint->q_gdquot) && (be32_to_cpu(dqp->q_core.d_id) == id)) { ASSERT(XFS_DQ_IS_LOCKED(udqhint)); dqp = udqhint->q_gdquot; if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) { xfs_dqlock(dqp); XFS_DQHOLD(dqp); ASSERT(*IO_idqpp == NULL); *IO_idqpp = dqp; if (!dolock) { xfs_dqunlock(dqp); xfs_dqunlock(udqhint); return 0; } goto done; } /* * We can't hold a dquot lock when we call the dqget code. * We'll deadlock in no time, because of (not conforming to) * lock ordering - the inodelock comes before any dquot lock, * and we may drop and reacquire the ilock in xfs_qm_dqget(). */ if (udqhint) xfs_dqunlock(udqhint); } /* * Find the dquot from somewhere. This bumps the * reference count of dquot and returns it locked. Loading @@ -698,48 +697,19 @@ xfs_qm_dqattach_one( * disk and we didn't ask it to allocate; * ESRCH if quotas got turned off suddenly. */ if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type, doalloc|XFS_QMOPT_DOWARN, &dqp))) { if (udqhint && dolock) xfs_dqlock(udqhint); goto done; } error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp); if (error) return error; xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); /* * dqget may have dropped and re-acquired the ilock, but it guarantees * that the dquot returned is the one that should go in the inode. */ *IO_idqpp = dqp; ASSERT(dqp); ASSERT(XFS_DQ_IS_LOCKED(dqp)); if (! dolock) { xfs_dqunlock(dqp); goto done; } if (! udqhint) goto done; ASSERT(udqhint); ASSERT(dolock); ASSERT(XFS_DQ_IS_LOCKED(dqp)); if (! xfs_qm_dqlock_nowait(udqhint)) { xfs_dqunlock(dqp); xfs_dqlock(udqhint); xfs_dqlock(dqp); } done: #ifdef QUOTADEBUG if (udqhint) { if (dolock) ASSERT(XFS_DQ_IS_LOCKED(udqhint)); } if (! error) { if (dolock) ASSERT(XFS_DQ_IS_LOCKED(dqp)); } #endif return error; return 0; } Loading @@ -754,23 +724,14 @@ xfs_qm_dqattach_one( STATIC void xfs_qm_dqattach_grouphint( xfs_dquot_t *udq, xfs_dquot_t *gdq, uint locked) xfs_dquot_t *gdq) { xfs_dquot_t *tmp; #ifdef QUOTADEBUG if (locked) { ASSERT(XFS_DQ_IS_LOCKED(udq)); ASSERT(XFS_DQ_IS_LOCKED(gdq)); } #endif if (! locked) xfs_dqlock(udq); if ((tmp = udq->q_gdquot)) { if (tmp == gdq) { if (! locked) xfs_dqunlock(udq); return; } Loading @@ -781,8 +742,6 @@ xfs_qm_dqattach_grouphint( * because the freelist lock comes before dqlocks. */ xfs_dqunlock(udq); if (locked) xfs_dqunlock(gdq); /* * we took a hard reference once upon a time in dqget, * so give it back when the udquot no longer points at it Loading @@ -795,10 +754,8 @@ xfs_qm_dqattach_grouphint( } else { ASSERT(XFS_DQ_IS_LOCKED(udq)); if (! locked) { xfs_dqlock(gdq); } } ASSERT(XFS_DQ_IS_LOCKED(udq)); ASSERT(XFS_DQ_IS_LOCKED(gdq)); Loading @@ -810,19 +767,16 @@ xfs_qm_dqattach_grouphint( XFS_DQHOLD(gdq); udq->q_gdquot = gdq; } if (! locked) { xfs_dqunlock(gdq); xfs_dqunlock(udq); } } /* * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON * into account. * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty * much made this code a complete mess, but it has been pretty useful. * If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL. * Inode may get unlocked and relocked in here, and the caller must deal with * the consequences. Loading Loading @@ -851,7 +805,6 @@ xfs_qm_dqattach( if (XFS_IS_UQUOTA_ON(mp)) { error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQLOCK, NULL, &ip->i_udquot); if (error) goto done; Loading @@ -863,11 +816,9 @@ xfs_qm_dqattach( error = XFS_IS_GQUOTA_ON(mp) ? xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQLOCK, ip->i_udquot, &ip->i_gdquot) : xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQLOCK, ip->i_udquot, &ip->i_gdquot); /* * Don't worry about the udquot that we may have Loading Loading @@ -898,22 +849,13 @@ xfs_qm_dqattach( /* * Attach i_gdquot to the gdquot hint inside the i_udquot. */ xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot, flags & XFS_QMOPT_DQLOCK); xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot); } done: #ifdef QUOTADEBUG if (! error) { if (ip->i_udquot) { if (flags & XFS_QMOPT_DQLOCK) ASSERT(XFS_DQ_IS_LOCKED(ip->i_udquot)); } if (ip->i_gdquot) { if (flags & XFS_QMOPT_DQLOCK) ASSERT(XFS_DQ_IS_LOCKED(ip->i_gdquot)); } if (XFS_IS_UQUOTA_ON(mp)) ASSERT(ip->i_udquot); if (XFS_IS_OQUOTA_ON(mp)) Loading fs/xfs/quota/xfs_trans_dquot.c +6 −10 Original line number Diff line number Diff line Loading @@ -624,10 +624,9 @@ xfs_trans_dqresv( xfs_qcnt_t *resbcountp; xfs_quotainfo_t *q = mp->m_quotainfo; if (! (flags & XFS_QMOPT_DQLOCK)) { xfs_dqlock(dqp); } ASSERT(XFS_DQ_IS_LOCKED(dqp)); if (flags & XFS_TRANS_DQ_RES_BLKS) { hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); if (!hardlimit) Loading Loading @@ -740,10 +739,8 @@ xfs_trans_dqresv( ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount)); error_return: if (! (flags & XFS_QMOPT_DQLOCK)) { xfs_dqunlock(dqp); } return (error); return error; } Loading @@ -753,8 +750,7 @@ xfs_trans_dqresv( * grp/prj quotas is important, because this follows a both-or-nothing * approach. * * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked. * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown. * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown. * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota. * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks Loading Loading
fs/xfs/linux-2.6/xfs_ioctl.c +44 −62 Original line number Diff line number Diff line Loading @@ -78,92 +78,74 @@ xfs_find_handle( int hsize; xfs_handle_t handle; struct inode *inode; memset((char *)&handle, 0, sizeof(handle)); switch (cmd) { case XFS_IOC_PATH_TO_FSHANDLE: case XFS_IOC_PATH_TO_HANDLE: { struct file *file = NULL; struct path path; int error = user_lpath((const char __user *)hreq->path, &path); if (error) return error; ASSERT(path.dentry); ASSERT(path.dentry->d_inode); inode = igrab(path.dentry->d_inode); path_put(&path); break; } case XFS_IOC_FD_TO_HANDLE: { struct file *file; int error; struct xfs_inode *ip; if (cmd == XFS_IOC_FD_TO_HANDLE) { file = fget(hreq->fd); if (!file) return -EBADF; ASSERT(file->f_path.dentry); ASSERT(file->f_path.dentry->d_inode); inode = igrab(file->f_path.dentry->d_inode); fput(file); break; inode = file->f_path.dentry->d_inode; } else { error = user_lpath((const char __user *)hreq->path, &path); if (error) return error; inode = path.dentry->d_inode; } ip = XFS_I(inode); default: ASSERT(0); return -XFS_ERROR(EINVAL); } /* * We can only generate handles for inodes residing on a XFS filesystem, * and only for regular files, directories or symbolic links. */ error = -EINVAL; if (inode->i_sb->s_magic != XFS_SB_MAGIC) goto out_put; if (inode->i_sb->s_magic != XFS_SB_MAGIC) { /* we're not in XFS anymore, Toto */ iput(inode); return -XFS_ERROR(EINVAL); } error = -EBADF; if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) && !S_ISLNK(inode->i_mode)) goto out_put; switch (inode->i_mode & S_IFMT) { case S_IFREG: case S_IFDIR: case S_IFLNK: break; default: iput(inode); return -XFS_ERROR(EBADF); } /* now we can grab the fsid */ memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid, sizeof(xfs_fsid_t)); hsize = sizeof(xfs_fsid_t); memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t)); if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { xfs_inode_t *ip = XFS_I(inode); if (cmd == XFS_IOC_PATH_TO_FSHANDLE) { /* * This handle only contains an fsid, zero the rest. */ memset(&handle.ha_fid, 0, sizeof(handle.ha_fid)); hsize = sizeof(xfs_fsid_t); } else { int lock_mode; /* need to get access to the xfs_inode to read the generation */ lock_mode = xfs_ilock_map_shared(ip); /* fill in fid section of handle from inode */ handle.ha_fid.fid_len = sizeof(xfs_fid_t) - sizeof(handle.ha_fid.fid_len); handle.ha_fid.fid_pad = 0; handle.ha_fid.fid_gen = ip->i_d.di_gen; handle.ha_fid.fid_ino = ip->i_ino; xfs_iunlock_map_shared(ip, lock_mode); hsize = XFS_HSIZE(handle); } /* now copy our handle into the user buffer & write out the size */ error = -EFAULT; if (copy_to_user(hreq->ohandle, &handle, hsize) || copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) { iput(inode); return -XFS_ERROR(EFAULT); } copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) goto out_put; iput(inode); return 0; error = 0; out_put: if (cmd == XFS_IOC_FD_TO_HANDLE) fput(file); else path_put(&path); return error; } /* Loading
fs/xfs/linux-2.6/xfs_super.c +37 −6 Original line number Diff line number Diff line Loading @@ -990,26 +990,57 @@ xfs_fs_write_inode( int sync) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; int error = 0; int flags = 0; xfs_itrace_entry(ip); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); if (sync) { error = xfs_wait_on_pages(ip, 0, -1); if (error) goto out_error; flags |= FLUSH_SYNC; goto out; } /* * Bypass inodes which have already been cleaned by * the inode flush clustering code inside xfs_iflush */ if (xfs_inode_clean(ip)) goto out; /* * We make this non-blocking if the inode is contended, return * EAGAIN to indicate to the caller that they did not succeed. * This prevents the flush path from blocking on inodes inside * another operation right now, they get caught later by xfs_sync. */ if (sync) { xfs_ilock(ip, XFS_ILOCK_SHARED); xfs_iflock(ip); error = xfs_iflush(ip, XFS_IFLUSH_SYNC); } else { error = EAGAIN; if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) goto out; if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) goto out_unlock; error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK); } error = xfs_inode_flush(ip, flags); out_error: out_unlock: xfs_iunlock(ip, XFS_ILOCK_SHARED); out: /* * if we failed to write out the inode then mark * it dirty again so we'll try again later. */ if (error) xfs_mark_inode_dirty_sync(ip); return -error; } Loading
fs/xfs/linux-2.6/xfs_vnode.h +0 −5 Original line number Diff line number Diff line Loading @@ -40,11 +40,6 @@ struct attrlist_cursor_kern; #define IO_ISDIRECT 0x00004 /* bypass page cache */ #define IO_INVIS 0x00020 /* don't update inode timestamps */ /* * Flags for xfs_inode_flush */ #define FLUSH_SYNC 1 /* wait for flush to complete */ /* * Flush/Invalidate options for vop_toss/flush/flushinval_pages. */ Loading
fs/xfs/quota/xfs_qm.c +44 −102 Original line number Diff line number Diff line Loading @@ -632,7 +632,6 @@ xfs_qm_dqattach_one( xfs_dqid_t id, uint type, uint doalloc, uint dolock, xfs_dquot_t *udqhint, /* hint */ xfs_dquot_t **IO_idqpp) { Loading @@ -641,16 +640,16 @@ xfs_qm_dqattach_one( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); error = 0; /* * See if we already have it in the inode itself. IO_idqpp is * &i_udquot or &i_gdquot. This made the code look weird, but * made the logic a lot simpler. */ if ((dqp = *IO_idqpp)) { if (dolock) xfs_dqlock(dqp); dqp = *IO_idqpp; if (dqp) { xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); goto done; return 0; } /* Loading @@ -659,38 +658,38 @@ xfs_qm_dqattach_one( * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside * the user dquot. */ ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); if (udqhint && !dolock) if (udqhint) { ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); xfs_dqlock(udqhint); /* * No need to take dqlock to look at the id. * * The ID can't change until it gets reclaimed, and it won't * be reclaimed as long as we have a ref from inode and we hold * the ilock. * be reclaimed as long as we have a ref from inode and we * hold the ilock. */ if (udqhint && (dqp = udqhint->q_gdquot) && (be32_to_cpu(dqp->q_core.d_id) == id)) { ASSERT(XFS_DQ_IS_LOCKED(udqhint)); dqp = udqhint->q_gdquot; if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) { xfs_dqlock(dqp); XFS_DQHOLD(dqp); ASSERT(*IO_idqpp == NULL); *IO_idqpp = dqp; if (!dolock) { xfs_dqunlock(dqp); xfs_dqunlock(udqhint); return 0; } goto done; } /* * We can't hold a dquot lock when we call the dqget code. * We'll deadlock in no time, because of (not conforming to) * lock ordering - the inodelock comes before any dquot lock, * and we may drop and reacquire the ilock in xfs_qm_dqget(). */ if (udqhint) xfs_dqunlock(udqhint); } /* * Find the dquot from somewhere. This bumps the * reference count of dquot and returns it locked. Loading @@ -698,48 +697,19 @@ xfs_qm_dqattach_one( * disk and we didn't ask it to allocate; * ESRCH if quotas got turned off suddenly. */ if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type, doalloc|XFS_QMOPT_DOWARN, &dqp))) { if (udqhint && dolock) xfs_dqlock(udqhint); goto done; } error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp); if (error) return error; xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); /* * dqget may have dropped and re-acquired the ilock, but it guarantees * that the dquot returned is the one that should go in the inode. */ *IO_idqpp = dqp; ASSERT(dqp); ASSERT(XFS_DQ_IS_LOCKED(dqp)); if (! dolock) { xfs_dqunlock(dqp); goto done; } if (! udqhint) goto done; ASSERT(udqhint); ASSERT(dolock); ASSERT(XFS_DQ_IS_LOCKED(dqp)); if (! xfs_qm_dqlock_nowait(udqhint)) { xfs_dqunlock(dqp); xfs_dqlock(udqhint); xfs_dqlock(dqp); } done: #ifdef QUOTADEBUG if (udqhint) { if (dolock) ASSERT(XFS_DQ_IS_LOCKED(udqhint)); } if (! error) { if (dolock) ASSERT(XFS_DQ_IS_LOCKED(dqp)); } #endif return error; return 0; } Loading @@ -754,23 +724,14 @@ xfs_qm_dqattach_one( STATIC void xfs_qm_dqattach_grouphint( xfs_dquot_t *udq, xfs_dquot_t *gdq, uint locked) xfs_dquot_t *gdq) { xfs_dquot_t *tmp; #ifdef QUOTADEBUG if (locked) { ASSERT(XFS_DQ_IS_LOCKED(udq)); ASSERT(XFS_DQ_IS_LOCKED(gdq)); } #endif if (! locked) xfs_dqlock(udq); if ((tmp = udq->q_gdquot)) { if (tmp == gdq) { if (! locked) xfs_dqunlock(udq); return; } Loading @@ -781,8 +742,6 @@ xfs_qm_dqattach_grouphint( * because the freelist lock comes before dqlocks. */ xfs_dqunlock(udq); if (locked) xfs_dqunlock(gdq); /* * we took a hard reference once upon a time in dqget, * so give it back when the udquot no longer points at it Loading @@ -795,10 +754,8 @@ xfs_qm_dqattach_grouphint( } else { ASSERT(XFS_DQ_IS_LOCKED(udq)); if (! locked) { xfs_dqlock(gdq); } } ASSERT(XFS_DQ_IS_LOCKED(udq)); ASSERT(XFS_DQ_IS_LOCKED(gdq)); Loading @@ -810,19 +767,16 @@ xfs_qm_dqattach_grouphint( XFS_DQHOLD(gdq); udq->q_gdquot = gdq; } if (! locked) { xfs_dqunlock(gdq); xfs_dqunlock(udq); } } /* * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON * into account. * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty * much made this code a complete mess, but it has been pretty useful. * If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL. * Inode may get unlocked and relocked in here, and the caller must deal with * the consequences. Loading Loading @@ -851,7 +805,6 @@ xfs_qm_dqattach( if (XFS_IS_UQUOTA_ON(mp)) { error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQLOCK, NULL, &ip->i_udquot); if (error) goto done; Loading @@ -863,11 +816,9 @@ xfs_qm_dqattach( error = XFS_IS_GQUOTA_ON(mp) ? xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQLOCK, ip->i_udquot, &ip->i_gdquot) : xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQLOCK, ip->i_udquot, &ip->i_gdquot); /* * Don't worry about the udquot that we may have Loading Loading @@ -898,22 +849,13 @@ xfs_qm_dqattach( /* * Attach i_gdquot to the gdquot hint inside the i_udquot. */ xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot, flags & XFS_QMOPT_DQLOCK); xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot); } done: #ifdef QUOTADEBUG if (! error) { if (ip->i_udquot) { if (flags & XFS_QMOPT_DQLOCK) ASSERT(XFS_DQ_IS_LOCKED(ip->i_udquot)); } if (ip->i_gdquot) { if (flags & XFS_QMOPT_DQLOCK) ASSERT(XFS_DQ_IS_LOCKED(ip->i_gdquot)); } if (XFS_IS_UQUOTA_ON(mp)) ASSERT(ip->i_udquot); if (XFS_IS_OQUOTA_ON(mp)) Loading
fs/xfs/quota/xfs_trans_dquot.c +6 −10 Original line number Diff line number Diff line Loading @@ -624,10 +624,9 @@ xfs_trans_dqresv( xfs_qcnt_t *resbcountp; xfs_quotainfo_t *q = mp->m_quotainfo; if (! (flags & XFS_QMOPT_DQLOCK)) { xfs_dqlock(dqp); } ASSERT(XFS_DQ_IS_LOCKED(dqp)); if (flags & XFS_TRANS_DQ_RES_BLKS) { hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); if (!hardlimit) Loading Loading @@ -740,10 +739,8 @@ xfs_trans_dqresv( ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount)); error_return: if (! (flags & XFS_QMOPT_DQLOCK)) { xfs_dqunlock(dqp); } return (error); return error; } Loading @@ -753,8 +750,7 @@ xfs_trans_dqresv( * grp/prj quotas is important, because this follows a both-or-nothing * approach. * * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked. * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown. * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown. * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota. * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks Loading