提交 9483c89e 编写于 作者: F Felix Blyakher

Merge branch 'master' of git://git.kernel.org/pub/scm/fs/xfs/xfs

...@@ -78,92 +78,74 @@ xfs_find_handle( ...@@ -78,92 +78,74 @@ xfs_find_handle(
int hsize; int hsize;
xfs_handle_t handle; xfs_handle_t handle;
struct inode *inode; struct inode *inode;
struct file *file = NULL;
struct path path;
int error;
struct xfs_inode *ip;
memset((char *)&handle, 0, sizeof(handle)); if (cmd == XFS_IOC_FD_TO_HANDLE) {
file = fget(hreq->fd);
switch (cmd) { if (!file)
case XFS_IOC_PATH_TO_FSHANDLE: return -EBADF;
case XFS_IOC_PATH_TO_HANDLE: { inode = file->f_path.dentry->d_inode;
struct path path; } else {
int error = user_lpath((const char __user *)hreq->path, &path); error = user_lpath((const char __user *)hreq->path, &path);
if (error) if (error)
return error; return error;
inode = path.dentry->d_inode;
ASSERT(path.dentry);
ASSERT(path.dentry->d_inode);
inode = igrab(path.dentry->d_inode);
path_put(&path);
break;
} }
ip = XFS_I(inode);
case XFS_IOC_FD_TO_HANDLE: { /*
struct file *file; * We can only generate handles for inodes residing on a XFS filesystem,
* and only for regular files, directories or symbolic links.
file = fget(hreq->fd); */
if (!file) error = -EINVAL;
return -EBADF; if (inode->i_sb->s_magic != XFS_SB_MAGIC)
goto out_put;
ASSERT(file->f_path.dentry); error = -EBADF;
ASSERT(file->f_path.dentry->d_inode); if (!S_ISREG(inode->i_mode) &&
inode = igrab(file->f_path.dentry->d_inode); !S_ISDIR(inode->i_mode) &&
fput(file); !S_ISLNK(inode->i_mode))
break; goto out_put;
}
default:
ASSERT(0);
return -XFS_ERROR(EINVAL);
}
if (inode->i_sb->s_magic != XFS_SB_MAGIC) { memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
/* we're not in XFS anymore, Toto */
iput(inode);
return -XFS_ERROR(EINVAL);
}
switch (inode->i_mode & S_IFMT) { if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
case S_IFREG: /*
case S_IFDIR: * This handle only contains an fsid, zero the rest.
case S_IFLNK: */
break; memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
default: hsize = sizeof(xfs_fsid_t);
iput(inode); } else {
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);
if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
xfs_inode_t *ip = XFS_I(inode);
int lock_mode; int lock_mode;
/* need to get access to the xfs_inode to read the generation */
lock_mode = xfs_ilock_map_shared(ip); lock_mode = xfs_ilock_map_shared(ip);
/* fill in fid section of handle from inode */
handle.ha_fid.fid_len = sizeof(xfs_fid_t) - handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
sizeof(handle.ha_fid.fid_len); sizeof(handle.ha_fid.fid_len);
handle.ha_fid.fid_pad = 0; handle.ha_fid.fid_pad = 0;
handle.ha_fid.fid_gen = ip->i_d.di_gen; handle.ha_fid.fid_gen = ip->i_d.di_gen;
handle.ha_fid.fid_ino = ip->i_ino; handle.ha_fid.fid_ino = ip->i_ino;
xfs_iunlock_map_shared(ip, lock_mode); xfs_iunlock_map_shared(ip, lock_mode);
hsize = XFS_HSIZE(handle); 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) || if (copy_to_user(hreq->ohandle, &handle, hsize) ||
copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) { copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
iput(inode); goto out_put;
return -XFS_ERROR(EFAULT);
}
iput(inode); error = 0;
return 0;
out_put:
if (cmd == XFS_IOC_FD_TO_HANDLE)
fput(file);
else
path_put(&path);
return error;
} }
/* /*
......
...@@ -990,26 +990,57 @@ xfs_fs_write_inode( ...@@ -990,26 +990,57 @@ xfs_fs_write_inode(
int sync) int sync)
{ {
struct xfs_inode *ip = XFS_I(inode); struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
int error = 0; int error = 0;
int flags = 0;
xfs_itrace_entry(ip); xfs_itrace_entry(ip);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
if (sync) { if (sync) {
error = xfs_wait_on_pages(ip, 0, -1); error = xfs_wait_on_pages(ip, 0, -1);
if (error) if (error)
goto out_error; goto out;
flags |= FLUSH_SYNC; }
/*
* 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 * if we failed to write out the inode then mark
* it dirty again so we'll try again later. * it dirty again so we'll try again later.
*/ */
if (error) if (error)
xfs_mark_inode_dirty_sync(ip); xfs_mark_inode_dirty_sync(ip);
return -error; return -error;
} }
......
...@@ -40,11 +40,6 @@ struct attrlist_cursor_kern; ...@@ -40,11 +40,6 @@ struct attrlist_cursor_kern;
#define IO_ISDIRECT 0x00004 /* bypass page cache */ #define IO_ISDIRECT 0x00004 /* bypass page cache */
#define IO_INVIS 0x00020 /* don't update inode timestamps */ #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. * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
*/ */
......
...@@ -632,7 +632,6 @@ xfs_qm_dqattach_one( ...@@ -632,7 +632,6 @@ xfs_qm_dqattach_one(
xfs_dqid_t id, xfs_dqid_t id,
uint type, uint type,
uint doalloc, uint doalloc,
uint dolock,
xfs_dquot_t *udqhint, /* hint */ xfs_dquot_t *udqhint, /* hint */
xfs_dquot_t **IO_idqpp) xfs_dquot_t **IO_idqpp)
{ {
...@@ -641,16 +640,16 @@ xfs_qm_dqattach_one( ...@@ -641,16 +640,16 @@ xfs_qm_dqattach_one(
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
error = 0; error = 0;
/* /*
* See if we already have it in the inode itself. IO_idqpp is * 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 * &i_udquot or &i_gdquot. This made the code look weird, but
* made the logic a lot simpler. * made the logic a lot simpler.
*/ */
if ((dqp = *IO_idqpp)) { dqp = *IO_idqpp;
if (dolock) if (dqp) {
xfs_dqlock(dqp);
xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); xfs_dqtrace_entry(dqp, "DQATTACH: found in ip");
goto done; return 0;
} }
/* /*
...@@ -659,38 +658,38 @@ xfs_qm_dqattach_one( ...@@ -659,38 +658,38 @@ xfs_qm_dqattach_one(
* lookup by dqid (xfs_qm_dqget) by caching a group dquot inside * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
* the user dquot. * the user dquot.
*/ */
ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); if (udqhint) {
if (udqhint && !dolock) ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
xfs_dqlock(udqhint); xfs_dqlock(udqhint);
/* /*
* No need to take dqlock to look at the id. * 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 ID can't change until it gets reclaimed, and it won't
* the ilock. * be reclaimed as long as we have a ref from inode and we
*/ * hold the ilock.
if (udqhint && */
(dqp = udqhint->q_gdquot) && dqp = udqhint->q_gdquot;
(be32_to_cpu(dqp->q_core.d_id) == id)) { if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
ASSERT(XFS_DQ_IS_LOCKED(udqhint)); xfs_dqlock(dqp);
xfs_dqlock(dqp); XFS_DQHOLD(dqp);
XFS_DQHOLD(dqp); ASSERT(*IO_idqpp == NULL);
ASSERT(*IO_idqpp == NULL); *IO_idqpp = dqp;
*IO_idqpp = dqp;
if (!dolock) {
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
xfs_dqunlock(udqhint); xfs_dqunlock(udqhint);
return 0;
} }
goto done;
} /*
/* * We can't hold a dquot lock when we call the dqget code.
* We can't hold a dquot lock when we call the dqget code. * We'll deadlock in no time, because of (not conforming to)
* We'll deadlock in no time, because of (not conforming to) * lock ordering - the inodelock comes before any dquot lock,
* lock ordering - the inodelock comes before any dquot lock, * and we may drop and reacquire the ilock in xfs_qm_dqget().
* and we may drop and reacquire the ilock in xfs_qm_dqget(). */
*/
if (udqhint)
xfs_dqunlock(udqhint); xfs_dqunlock(udqhint);
}
/* /*
* Find the dquot from somewhere. This bumps the * Find the dquot from somewhere. This bumps the
* reference count of dquot and returns it locked. * reference count of dquot and returns it locked.
...@@ -698,48 +697,19 @@ xfs_qm_dqattach_one( ...@@ -698,48 +697,19 @@ xfs_qm_dqattach_one(
* disk and we didn't ask it to allocate; * disk and we didn't ask it to allocate;
* ESRCH if quotas got turned off suddenly. * ESRCH if quotas got turned off suddenly.
*/ */
if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type, error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp);
doalloc|XFS_QMOPT_DOWARN, &dqp))) { if (error)
if (udqhint && dolock) return error;
xfs_dqlock(udqhint);
goto done;
}
xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget");
/* /*
* dqget may have dropped and re-acquired the ilock, but it guarantees * 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. * that the dquot returned is the one that should go in the inode.
*/ */
*IO_idqpp = dqp; *IO_idqpp = dqp;
ASSERT(dqp); xfs_dqunlock(dqp);
ASSERT(XFS_DQ_IS_LOCKED(dqp)); return 0;
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;
} }
...@@ -754,24 +724,15 @@ xfs_qm_dqattach_one( ...@@ -754,24 +724,15 @@ xfs_qm_dqattach_one(
STATIC void STATIC void
xfs_qm_dqattach_grouphint( xfs_qm_dqattach_grouphint(
xfs_dquot_t *udq, xfs_dquot_t *udq,
xfs_dquot_t *gdq, xfs_dquot_t *gdq)
uint locked)
{ {
xfs_dquot_t *tmp; xfs_dquot_t *tmp;
#ifdef QUOTADEBUG xfs_dqlock(udq);
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 = udq->q_gdquot)) {
if (tmp == gdq) { if (tmp == gdq) {
if (! locked) xfs_dqunlock(udq);
xfs_dqunlock(udq);
return; return;
} }
...@@ -781,8 +742,6 @@ xfs_qm_dqattach_grouphint( ...@@ -781,8 +742,6 @@ xfs_qm_dqattach_grouphint(
* because the freelist lock comes before dqlocks. * because the freelist lock comes before dqlocks.
*/ */
xfs_dqunlock(udq); xfs_dqunlock(udq);
if (locked)
xfs_dqunlock(gdq);
/* /*
* we took a hard reference once upon a time in dqget, * we took a hard reference once upon a time in dqget,
* so give it back when the udquot no longer points at it * so give it back when the udquot no longer points at it
...@@ -795,9 +754,7 @@ xfs_qm_dqattach_grouphint( ...@@ -795,9 +754,7 @@ xfs_qm_dqattach_grouphint(
} else { } else {
ASSERT(XFS_DQ_IS_LOCKED(udq)); ASSERT(XFS_DQ_IS_LOCKED(udq));
if (! locked) { xfs_dqlock(gdq);
xfs_dqlock(gdq);
}
} }
ASSERT(XFS_DQ_IS_LOCKED(udq)); ASSERT(XFS_DQ_IS_LOCKED(udq));
...@@ -810,10 +767,9 @@ xfs_qm_dqattach_grouphint( ...@@ -810,10 +767,9 @@ xfs_qm_dqattach_grouphint(
XFS_DQHOLD(gdq); XFS_DQHOLD(gdq);
udq->q_gdquot = gdq; udq->q_gdquot = gdq;
} }
if (! locked) {
xfs_dqunlock(gdq); xfs_dqunlock(gdq);
xfs_dqunlock(udq); xfs_dqunlock(udq);
}
} }
...@@ -821,8 +777,6 @@ xfs_qm_dqattach_grouphint( ...@@ -821,8 +777,6 @@ xfs_qm_dqattach_grouphint(
* Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
* into account. * into account.
* If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. * 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. * 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 * Inode may get unlocked and relocked in here, and the caller must deal with
* the consequences. * the consequences.
...@@ -851,7 +805,6 @@ xfs_qm_dqattach( ...@@ -851,7 +805,6 @@ xfs_qm_dqattach(
if (XFS_IS_UQUOTA_ON(mp)) { if (XFS_IS_UQUOTA_ON(mp)) {
error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQALLOC,
flags & XFS_QMOPT_DQLOCK,
NULL, &ip->i_udquot); NULL, &ip->i_udquot);
if (error) if (error)
goto done; goto done;
...@@ -863,11 +816,9 @@ xfs_qm_dqattach( ...@@ -863,11 +816,9 @@ xfs_qm_dqattach(
error = XFS_IS_GQUOTA_ON(mp) ? error = XFS_IS_GQUOTA_ON(mp) ?
xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQALLOC,
flags & XFS_QMOPT_DQLOCK,
ip->i_udquot, &ip->i_gdquot) : ip->i_udquot, &ip->i_gdquot) :
xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQALLOC,
flags & XFS_QMOPT_DQLOCK,
ip->i_udquot, &ip->i_gdquot); ip->i_udquot, &ip->i_gdquot);
/* /*
* Don't worry about the udquot that we may have * Don't worry about the udquot that we may have
...@@ -898,22 +849,13 @@ xfs_qm_dqattach( ...@@ -898,22 +849,13 @@ xfs_qm_dqattach(
/* /*
* Attach i_gdquot to the gdquot hint inside the i_udquot. * Attach i_gdquot to the gdquot hint inside the i_udquot.
*/ */
xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot, xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot);
flags & XFS_QMOPT_DQLOCK);
} }
done: done:
#ifdef QUOTADEBUG #ifdef QUOTADEBUG
if (! error) { 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)) if (XFS_IS_UQUOTA_ON(mp))
ASSERT(ip->i_udquot); ASSERT(ip->i_udquot);
if (XFS_IS_OQUOTA_ON(mp)) if (XFS_IS_OQUOTA_ON(mp))
......
...@@ -624,10 +624,9 @@ xfs_trans_dqresv( ...@@ -624,10 +624,9 @@ xfs_trans_dqresv(
xfs_qcnt_t *resbcountp; xfs_qcnt_t *resbcountp;
xfs_quotainfo_t *q = mp->m_quotainfo; xfs_quotainfo_t *q = mp->m_quotainfo;
if (! (flags & XFS_QMOPT_DQLOCK)) {
xfs_dqlock(dqp); xfs_dqlock(dqp);
}
ASSERT(XFS_DQ_IS_LOCKED(dqp));
if (flags & XFS_TRANS_DQ_RES_BLKS) { if (flags & XFS_TRANS_DQ_RES_BLKS) {
hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
if (!hardlimit) if (!hardlimit)
...@@ -740,10 +739,8 @@ xfs_trans_dqresv( ...@@ -740,10 +739,8 @@ xfs_trans_dqresv(
ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount)); ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
error_return: error_return:
if (! (flags & XFS_QMOPT_DQLOCK)) { xfs_dqunlock(dqp);
xfs_dqunlock(dqp); return error;
}
return (error);
} }
...@@ -753,8 +750,7 @@ xfs_trans_dqresv( ...@@ -753,8 +750,7 @@ xfs_trans_dqresv(
* grp/prj quotas is important, because this follows a both-or-nothing * grp/prj quotas is important, because this follows a both-or-nothing
* approach. * approach.
* *
* flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked. * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
* XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
* XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota. * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
* XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
* XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
......
...@@ -297,6 +297,26 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) ...@@ -297,6 +297,26 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
xfs_sbversion_add_attr2(mp, args->trans); xfs_sbversion_add_attr2(mp, args->trans);
} }
/*
* After the last attribute is removed revert to original inode format,
* making all literal area available to the data fork once more.
*/
STATIC void
xfs_attr_fork_reset(
struct xfs_inode *ip,
struct xfs_trans *tp)
{
xfs_idestroy_fork(ip, XFS_ATTR_FORK);
ip->i_d.di_forkoff = 0;
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
ASSERT(ip->i_d.di_anextents == 0);
ASSERT(ip->i_afp == NULL);
ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
}
/* /*
* Remove an attribute from the shortform attribute list structure. * Remove an attribute from the shortform attribute list structure.
*/ */
...@@ -344,22 +364,10 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) ...@@ -344,22 +364,10 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
*/ */
totsize -= size; totsize -= size;
if (totsize == sizeof(xfs_attr_sf_hdr_t) && if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
!(args->op_flags & XFS_DA_OP_ADDNAME) && (mp->m_flags & XFS_MOUNT_ATTR2) &&
(mp->m_flags & XFS_MOUNT_ATTR2) && (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
(dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) { !(args->op_flags & XFS_DA_OP_ADDNAME)) {
/* xfs_attr_fork_reset(dp, args->trans);
* Last attribute now removed, revert to original
* inode format making all literal area available
* to the data fork once more.
*/
xfs_idestroy_fork(dp, XFS_ATTR_FORK);
dp->i_d.di_forkoff = 0;
dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
ASSERT(dp->i_d.di_anextents == 0);
ASSERT(dp->i_afp == NULL);
dp->i_df.if_ext_max =
XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
} else { } else {
xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
...@@ -786,20 +794,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) ...@@ -786,20 +794,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
if (forkoff == -1) { if (forkoff == -1) {
ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
xfs_attr_fork_reset(dp, args->trans);
/*
* Last attribute was removed, revert to original
* inode format making all literal area available
* to the data fork once more.
*/
xfs_idestroy_fork(dp, XFS_ATTR_FORK);
dp->i_d.di_forkoff = 0;
dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
ASSERT(dp->i_d.di_anextents == 0);
ASSERT(dp->i_afp == NULL);
dp->i_df.if_ext_max =
XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
goto out; goto out;
} }
......
...@@ -118,19 +118,17 @@ xfs_swap_extents( ...@@ -118,19 +118,17 @@ xfs_swap_extents(
xfs_bstat_t *sbp = &sxp->sx_stat; xfs_bstat_t *sbp = &sxp->sx_stat;
xfs_ifork_t *tempifp, *ifp, *tifp; xfs_ifork_t *tempifp, *ifp, *tifp;
int ilf_fields, tilf_fields; int ilf_fields, tilf_fields;
static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
int error = 0; int error = 0;
int aforkblks = 0; int aforkblks = 0;
int taforkblks = 0; int taforkblks = 0;
__uint64_t tmp; __uint64_t tmp;
char locked = 0;
mp = ip->i_mount; mp = ip->i_mount;
tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
if (!tempifp) { if (!tempifp) {
error = XFS_ERROR(ENOMEM); error = XFS_ERROR(ENOMEM);
goto error0; goto out;
} }
sbp = &sxp->sx_stat; sbp = &sxp->sx_stat;
...@@ -143,25 +141,24 @@ xfs_swap_extents( ...@@ -143,25 +141,24 @@ xfs_swap_extents(
*/ */
xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
locked = 1;
/* Verify that both files have the same format */ /* Verify that both files have the same format */
if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error0; goto out_unlock;
} }
/* Verify both files are either real-time or non-realtime */ /* Verify both files are either real-time or non-realtime */
if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) { if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error0; goto out_unlock;
} }
/* Should never get a local format */ /* Should never get a local format */
if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL ||
tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error0; goto out_unlock;
} }
if (VN_CACHED(VFS_I(tip)) != 0) { if (VN_CACHED(VFS_I(tip)) != 0) {
...@@ -169,13 +166,13 @@ xfs_swap_extents( ...@@ -169,13 +166,13 @@ xfs_swap_extents(
error = xfs_flushinval_pages(tip, 0, -1, error = xfs_flushinval_pages(tip, 0, -1,
FI_REMAPF_LOCKED); FI_REMAPF_LOCKED);
if (error) if (error)
goto error0; goto out_unlock;
} }
/* Verify O_DIRECT for ftmp */ /* Verify O_DIRECT for ftmp */
if (VN_CACHED(VFS_I(tip)) != 0) { if (VN_CACHED(VFS_I(tip)) != 0) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error0; goto out_unlock;
} }
/* Verify all data are being swapped */ /* Verify all data are being swapped */
...@@ -183,7 +180,7 @@ xfs_swap_extents( ...@@ -183,7 +180,7 @@ xfs_swap_extents(
sxp->sx_length != ip->i_d.di_size || sxp->sx_length != ip->i_d.di_size ||
sxp->sx_length != tip->i_d.di_size) { sxp->sx_length != tip->i_d.di_size) {
error = XFS_ERROR(EFAULT); error = XFS_ERROR(EFAULT);
goto error0; goto out_unlock;
} }
/* /*
...@@ -193,7 +190,7 @@ xfs_swap_extents( ...@@ -193,7 +190,7 @@ xfs_swap_extents(
*/ */
if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) { if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error0; goto out_unlock;
} }
/* /*
...@@ -208,7 +205,7 @@ xfs_swap_extents( ...@@ -208,7 +205,7 @@ xfs_swap_extents(
(sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) || (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) ||
(sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) { (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) {
error = XFS_ERROR(EBUSY); error = XFS_ERROR(EBUSY);
goto error0; goto out_unlock;
} }
/* We need to fail if the file is memory mapped. Once we have tossed /* We need to fail if the file is memory mapped. Once we have tossed
...@@ -219,7 +216,7 @@ xfs_swap_extents( ...@@ -219,7 +216,7 @@ xfs_swap_extents(
*/ */
if (VN_MAPPED(VFS_I(ip))) { if (VN_MAPPED(VFS_I(ip))) {
error = XFS_ERROR(EBUSY); error = XFS_ERROR(EBUSY);
goto error0; goto out_unlock;
} }
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
...@@ -242,8 +239,7 @@ xfs_swap_extents( ...@@ -242,8 +239,7 @@ xfs_swap_extents(
xfs_iunlock(ip, XFS_IOLOCK_EXCL); xfs_iunlock(ip, XFS_IOLOCK_EXCL);
xfs_iunlock(tip, XFS_IOLOCK_EXCL); xfs_iunlock(tip, XFS_IOLOCK_EXCL);
xfs_trans_cancel(tp, 0); xfs_trans_cancel(tp, 0);
locked = 0; goto out;
goto error0;
} }
xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
...@@ -253,19 +249,15 @@ xfs_swap_extents( ...@@ -253,19 +249,15 @@ xfs_swap_extents(
if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) &&
(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks); error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks);
if (error) { if (error)
xfs_trans_cancel(tp, 0); goto out_trans_cancel;
goto error0;
}
} }
if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) &&
(tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK,
&taforkblks); &taforkblks);
if (error) { if (error)
xfs_trans_cancel(tp, 0); goto out_trans_cancel;
goto error0;
}
} }
/* /*
...@@ -332,10 +324,10 @@ xfs_swap_extents( ...@@ -332,10 +324,10 @@ xfs_swap_extents(
IHOLD(ip); IHOLD(ip);
xfs_trans_ijoin(tp, ip, lock_flags); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
IHOLD(tip); IHOLD(tip);
xfs_trans_ijoin(tp, tip, lock_flags); xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_log_inode(tp, ip, ilf_fields); xfs_trans_log_inode(tp, ip, ilf_fields);
xfs_trans_log_inode(tp, tip, tilf_fields); xfs_trans_log_inode(tp, tip, tilf_fields);
...@@ -344,19 +336,19 @@ xfs_swap_extents( ...@@ -344,19 +336,19 @@ xfs_swap_extents(
* If this is a synchronous mount, make sure that the * If this is a synchronous mount, make sure that the
* transaction goes to disk before returning to the user. * transaction goes to disk before returning to the user.
*/ */
if (mp->m_flags & XFS_MOUNT_WSYNC) { if (mp->m_flags & XFS_MOUNT_WSYNC)
xfs_trans_set_sync(tp); xfs_trans_set_sync(tp);
}
error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT); error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
locked = 0;
error0: out_unlock:
if (locked) { xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_iunlock(ip, lock_flags); xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_iunlock(tip, lock_flags); out:
} kmem_free(tempifp);
if (tempifp != NULL)
kmem_free(tempifp);
return error; return error;
out_trans_cancel:
xfs_trans_cancel(tp, 0);
goto out_unlock;
} }
...@@ -886,8 +886,6 @@ xfs_check_sizes(xfs_mount_t *mp) ...@@ -886,8 +886,6 @@ xfs_check_sizes(xfs_mount_t *mp)
} }
/* /*
* xfs_mountfs
*
* This function does the following on an initial mount of a file system: * This function does the following on an initial mount of a file system:
* - reads the superblock from disk and init the mount struct * - reads the superblock from disk and init the mount struct
* - if we're a 32-bit kernel, do a size check on the superblock * - if we're a 32-bit kernel, do a size check on the superblock
...@@ -905,7 +903,6 @@ xfs_mountfs( ...@@ -905,7 +903,6 @@ xfs_mountfs(
xfs_inode_t *rip; xfs_inode_t *rip;
__uint64_t resblks; __uint64_t resblks;
uint quotamount, quotaflags; uint quotamount, quotaflags;
int uuid_mounted = 0;
int error = 0; int error = 0;
xfs_mount_common(mp, sbp); xfs_mount_common(mp, sbp);
...@@ -960,7 +957,7 @@ xfs_mountfs( ...@@ -960,7 +957,7 @@ xfs_mountfs(
*/ */
error = xfs_update_alignment(mp); error = xfs_update_alignment(mp);
if (error) if (error)
goto error1; goto out;
xfs_alloc_compute_maxlevels(mp); xfs_alloc_compute_maxlevels(mp);
xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
...@@ -977,12 +974,11 @@ xfs_mountfs( ...@@ -977,12 +974,11 @@ xfs_mountfs(
* since a single partition filesystem is identical to a single * since a single partition filesystem is identical to a single
* partition volume/filesystem. * partition volume/filesystem.
*/ */
if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) { if (!(mp->m_flags & XFS_MOUNT_NOUUID)) {
if (xfs_uuid_mount(mp)) { if (xfs_uuid_mount(mp)) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error1; goto out;
} }
uuid_mounted=1;
} }
/* /*
...@@ -1007,7 +1003,7 @@ xfs_mountfs( ...@@ -1007,7 +1003,7 @@ xfs_mountfs(
*/ */
error = xfs_check_sizes(mp); error = xfs_check_sizes(mp);
if (error) if (error)
goto error1; goto out_remove_uuid;
/* /*
* Initialize realtime fields in the mount structure * Initialize realtime fields in the mount structure
...@@ -1015,7 +1011,7 @@ xfs_mountfs( ...@@ -1015,7 +1011,7 @@ xfs_mountfs(
error = xfs_rtmount_init(mp); error = xfs_rtmount_init(mp);
if (error) { if (error) {
cmn_err(CE_WARN, "XFS: RT mount failed"); cmn_err(CE_WARN, "XFS: RT mount failed");
goto error1; goto out_remove_uuid;
} }
/* /*
...@@ -1045,26 +1041,26 @@ xfs_mountfs( ...@@ -1045,26 +1041,26 @@ xfs_mountfs(
mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t),
KM_MAYFAIL); KM_MAYFAIL);
if (!mp->m_perag) if (!mp->m_perag)
goto error1; goto out_remove_uuid;
mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
if (!sbp->sb_logblocks) {
cmn_err(CE_WARN, "XFS: no log defined");
XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto out_free_perag;
}
/* /*
* log's mount-time initialization. Perform 1st part recovery if needed * log's mount-time initialization. Perform 1st part recovery if needed
*/ */
if (likely(sbp->sb_logblocks > 0)) { /* check for volume case */ error = xfs_log_mount(mp, mp->m_logdev_targp,
error = xfs_log_mount(mp, mp->m_logdev_targp, XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
XFS_FSB_TO_DADDR(mp, sbp->sb_logstart), XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
XFS_FSB_TO_BB(mp, sbp->sb_logblocks)); if (error) {
if (error) { cmn_err(CE_WARN, "XFS: log mount failed");
cmn_err(CE_WARN, "XFS: log mount failed"); goto out_free_perag;
goto error2;
}
} else { /* No log has been defined */
cmn_err(CE_WARN, "XFS: no log defined");
XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp);
error = XFS_ERROR(EFSCORRUPTED);
goto error2;
} }
/* /*
...@@ -1086,15 +1082,14 @@ xfs_mountfs( ...@@ -1086,15 +1082,14 @@ xfs_mountfs(
* If we are currently making the filesystem, the initialisation will * If we are currently making the filesystem, the initialisation will
* fail as the perag data is in an undefined state. * fail as the perag data is in an undefined state.
*/ */
if (xfs_sb_version_haslazysbcount(&mp->m_sb) && if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
!XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) &&
!mp->m_sb.sb_inprogress) { !mp->m_sb.sb_inprogress) {
error = xfs_initialize_perag_data(mp, sbp->sb_agcount); error = xfs_initialize_perag_data(mp, sbp->sb_agcount);
if (error) { if (error)
goto error2; goto out_free_perag;
}
} }
/* /*
* Get and sanity-check the root inode. * Get and sanity-check the root inode.
* Save the pointer to it in the mount structure. * Save the pointer to it in the mount structure.
...@@ -1102,7 +1097,7 @@ xfs_mountfs( ...@@ -1102,7 +1097,7 @@ xfs_mountfs(
error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0); error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0);
if (error) { if (error) {
cmn_err(CE_WARN, "XFS: failed to read root inode"); cmn_err(CE_WARN, "XFS: failed to read root inode");
goto error3; goto out_log_dealloc;
} }
ASSERT(rip != NULL); ASSERT(rip != NULL);
...@@ -1116,7 +1111,7 @@ xfs_mountfs( ...@@ -1116,7 +1111,7 @@ xfs_mountfs(
XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
mp); mp);
error = XFS_ERROR(EFSCORRUPTED); error = XFS_ERROR(EFSCORRUPTED);
goto error4; goto out_rele_rip;
} }
mp->m_rootip = rip; /* save it */ mp->m_rootip = rip; /* save it */
...@@ -1131,7 +1126,7 @@ xfs_mountfs( ...@@ -1131,7 +1126,7 @@ xfs_mountfs(
* Free up the root inode. * Free up the root inode.
*/ */
cmn_err(CE_WARN, "XFS: failed to read RT inodes"); cmn_err(CE_WARN, "XFS: failed to read RT inodes");
goto error4; goto out_rele_rip;
} }
/* /*
...@@ -1143,7 +1138,7 @@ xfs_mountfs( ...@@ -1143,7 +1138,7 @@ xfs_mountfs(
error = xfs_mount_log_sb(mp, mp->m_update_flags); error = xfs_mount_log_sb(mp, mp->m_update_flags);
if (error) { if (error) {
cmn_err(CE_WARN, "XFS: failed to write sb changes"); cmn_err(CE_WARN, "XFS: failed to write sb changes");
goto error4; goto out_rtunmount;
} }
} }
...@@ -1152,7 +1147,7 @@ xfs_mountfs( ...@@ -1152,7 +1147,7 @@ xfs_mountfs(
*/ */
error = XFS_QM_INIT(mp, &quotamount, &quotaflags); error = XFS_QM_INIT(mp, &quotamount, &quotaflags);
if (error) if (error)
goto error4; goto out_rtunmount;
/* /*
* Finish recovering the file system. This part needed to be * Finish recovering the file system. This part needed to be
...@@ -1162,7 +1157,7 @@ xfs_mountfs( ...@@ -1162,7 +1157,7 @@ xfs_mountfs(
error = xfs_log_mount_finish(mp); error = xfs_log_mount_finish(mp);
if (error) { if (error) {
cmn_err(CE_WARN, "XFS: log mount finish failed"); cmn_err(CE_WARN, "XFS: log mount finish failed");
goto error4; goto out_rtunmount;
} }
/* /*
...@@ -1170,7 +1165,7 @@ xfs_mountfs( ...@@ -1170,7 +1165,7 @@ xfs_mountfs(
*/ */
error = XFS_QM_MOUNT(mp, quotamount, quotaflags); error = XFS_QM_MOUNT(mp, quotamount, quotaflags);
if (error) if (error)
goto error4; goto out_rtunmount;
/* /*
* Now we are mounted, reserve a small amount of unused space for * Now we are mounted, reserve a small amount of unused space for
...@@ -1194,18 +1189,18 @@ xfs_mountfs( ...@@ -1194,18 +1189,18 @@ xfs_mountfs(
return 0; return 0;
error4: out_rtunmount:
/* xfs_rtunmount_inodes(mp);
* Free up the root inode. out_rele_rip:
*/
IRELE(rip); IRELE(rip);
error3: out_log_dealloc:
xfs_log_unmount_dealloc(mp); xfs_log_unmount_dealloc(mp);
error2: out_free_perag:
xfs_free_perag(mp); xfs_free_perag(mp);
error1: out_remove_uuid:
if (uuid_mounted) if (!(mp->m_flags & XFS_MOUNT_NOUUID))
uuid_table_remove(&mp->m_sb.sb_uuid); uuid_table_remove(&mp->m_sb.sb_uuid);
out:
return error; return error;
} }
...@@ -1226,10 +1221,7 @@ xfs_unmountfs( ...@@ -1226,10 +1221,7 @@ xfs_unmountfs(
*/ */
XFS_QM_UNMOUNT(mp); XFS_QM_UNMOUNT(mp);
if (mp->m_rbmip) xfs_rtunmount_inodes(mp);
IRELE(mp->m_rbmip);
if (mp->m_rsumip)
IRELE(mp->m_rsumip);
IRELE(mp->m_rootip); IRELE(mp->m_rootip);
/* /*
......
...@@ -500,9 +500,6 @@ typedef struct xfs_mod_sb { ...@@ -500,9 +500,6 @@ typedef struct xfs_mod_sb {
int64_t msb_delta; /* Change to make to specified field */ int64_t msb_delta; /* Change to make to specified field */
} xfs_mod_sb_t; } xfs_mod_sb_t;
#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock))
#define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock))
extern int xfs_log_sbcount(xfs_mount_t *, uint); extern int xfs_log_sbcount(xfs_mount_t *, uint);
extern int xfs_mountfs(xfs_mount_t *mp); extern int xfs_mountfs(xfs_mount_t *mp);
extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
......
...@@ -185,7 +185,6 @@ typedef struct xfs_qoff_logformat { ...@@ -185,7 +185,6 @@ typedef struct xfs_qoff_logformat {
* to a single function. None of these XFS_QMOPT_* flags are meant to have * to a single function. None of these XFS_QMOPT_* flags are meant to have
* persistent values (ie. their values can and will change between versions) * persistent values (ie. their values can and will change between versions)
*/ */
#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ #define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ #define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
......
...@@ -2288,6 +2288,16 @@ xfs_rtmount_inodes( ...@@ -2288,6 +2288,16 @@ xfs_rtmount_inodes(
return 0; return 0;
} }
void
xfs_rtunmount_inodes(
struct xfs_mount *mp)
{
if (mp->m_rbmip)
IRELE(mp->m_rbmip);
if (mp->m_rsumip)
IRELE(mp->m_rsumip);
}
/* /*
* Pick an extent for allocation at the start of a new realtime file. * Pick an extent for allocation at the start of a new realtime file.
* Use the sequence number stored in the atime field of the bitmap inode. * Use the sequence number stored in the atime field of the bitmap inode.
......
...@@ -108,6 +108,9 @@ xfs_rtfree_extent( ...@@ -108,6 +108,9 @@ xfs_rtfree_extent(
int /* error */ int /* error */
xfs_rtmount_init( xfs_rtmount_init(
struct xfs_mount *mp); /* file system mount structure */ struct xfs_mount *mp); /* file system mount structure */
void
xfs_rtunmount_inodes(
struct xfs_mount *mp);
/* /*
* Get the bitmap and summary inodes into the mount structure * Get the bitmap and summary inodes into the mount structure
...@@ -146,6 +149,7 @@ xfs_growfs_rt( ...@@ -146,6 +149,7 @@ xfs_growfs_rt(
# define xfs_growfs_rt(mp,in) (ENOSYS) # define xfs_growfs_rt(mp,in) (ENOSYS)
# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) # define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) # define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
# define xfs_rtunmount_inodes(m)
#endif /* CONFIG_XFS_RT */ #endif /* CONFIG_XFS_RT */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -2004,8 +2004,10 @@ xfs_link( ...@@ -2004,8 +2004,10 @@ xfs_link(
/* Return through std_return after this point. */ /* Return through std_return after this point. */
error = XFS_QM_DQATTACH(mp, sip, 0); error = XFS_QM_DQATTACH(mp, sip, 0);
if (!error && sip != tdp) if (error)
error = XFS_QM_DQATTACH(mp, tdp, 0); goto std_return;
error = XFS_QM_DQATTACH(mp, tdp, 0);
if (error) if (error)
goto std_return; goto std_return;
...@@ -2586,51 +2588,6 @@ xfs_symlink( ...@@ -2586,51 +2588,6 @@ xfs_symlink(
goto std_return; goto std_return;
} }
int
xfs_inode_flush(
xfs_inode_t *ip,
int flags)
{
xfs_mount_t *mp = ip->i_mount;
int error = 0;
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
/*
* Bypass inodes which have already been cleaned by
* the inode flush clustering code inside xfs_iflush
*/
if (xfs_inode_clean(ip))
return 0;
/*
* 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 (flags & FLUSH_SYNC) {
xfs_ilock(ip, XFS_ILOCK_SHARED);
xfs_iflock(ip);
} else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
xfs_iunlock(ip, XFS_ILOCK_SHARED);
return EAGAIN;
}
} else {
return EAGAIN;
}
error = xfs_iflush(ip, (flags & FLUSH_SYNC) ? XFS_IFLUSH_SYNC
: XFS_IFLUSH_ASYNC_NOBLOCK);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
return error;
}
int int
xfs_set_dmattrs( xfs_set_dmattrs(
xfs_inode_t *ip, xfs_inode_t *ip,
......
...@@ -38,7 +38,6 @@ int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, ...@@ -38,7 +38,6 @@ int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize,
int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
const char *target_path, mode_t mode, struct xfs_inode **ipp, const char *target_path, mode_t mode, struct xfs_inode **ipp,
cred_t *credp); cred_t *credp);
int xfs_inode_flush(struct xfs_inode *ip, int flags);
int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
int xfs_reclaim(struct xfs_inode *ip); int xfs_reclaim(struct xfs_inode *ip);
int xfs_change_file_space(struct xfs_inode *ip, int cmd, int xfs_change_file_space(struct xfs_inode *ip, int cmd,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册