X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=fs%2Fxfs%2Fxfs_symlink.c;h=2f2a7c005be2d32219fd9c580bb2050f2f4e0050;hb=7aab1b28879d2280c9a0e50000e4ae153cfac55a;hp=e830fb56e27f9fa0a979dee9f3f58b56e6afa6ae;hpb=75fcf64dc7180a6258dbefd671edb9d86a38d22f;p=platform%2Fadaptation%2Frenesas_rcar%2Frenesas_kernel.git diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index e830fb5..2f2a7c0 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -18,200 +18,29 @@ */ #include "xfs.h" #include "xfs_fs.h" -#include "xfs_types.h" +#include "xfs_format.h" #include "xfs_bit.h" #include "xfs_log.h" #include "xfs_trans.h" #include "xfs_sb.h" #include "xfs_ag.h" -#include "xfs_dir2.h" #include "xfs_mount.h" #include "xfs_da_btree.h" +#include "xfs_dir2_format.h" +#include "xfs_dir2.h" #include "xfs_bmap_btree.h" #include "xfs_ialloc_btree.h" #include "xfs_dinode.h" #include "xfs_inode.h" -#include "xfs_inode_item.h" -#include "xfs_itable.h" #include "xfs_ialloc.h" #include "xfs_alloc.h" #include "xfs_bmap.h" +#include "xfs_bmap_util.h" #include "xfs_error.h" #include "xfs_quota.h" -#include "xfs_utils.h" #include "xfs_trans_space.h" -#include "xfs_log_priv.h" #include "xfs_trace.h" #include "xfs_symlink.h" -#include "xfs_cksum.h" -#include "xfs_buf_item.h" - - -/* - * Each contiguous block has a header, so it is not just a simple pathlen - * to FSB conversion. - */ -int -xfs_symlink_blocks( - struct xfs_mount *mp, - int pathlen) -{ - int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize); - - return (pathlen + buflen - 1) / buflen; -} - -static int -xfs_symlink_hdr_set( - struct xfs_mount *mp, - xfs_ino_t ino, - uint32_t offset, - uint32_t size, - struct xfs_buf *bp) -{ - struct xfs_dsymlink_hdr *dsl = bp->b_addr; - - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return 0; - - dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC); - dsl->sl_offset = cpu_to_be32(offset); - dsl->sl_bytes = cpu_to_be32(size); - uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_uuid); - dsl->sl_owner = cpu_to_be64(ino); - dsl->sl_blkno = cpu_to_be64(bp->b_bn); - bp->b_ops = &xfs_symlink_buf_ops; - - return sizeof(struct xfs_dsymlink_hdr); -} - -/* - * Checking of the symlink header is split into two parts. the verifier does - * CRC, location and bounds checking, the unpacking function checks the path - * parameters and owner. - */ -bool -xfs_symlink_hdr_ok( - struct xfs_mount *mp, - xfs_ino_t ino, - uint32_t offset, - uint32_t size, - struct xfs_buf *bp) -{ - struct xfs_dsymlink_hdr *dsl = bp->b_addr; - - if (offset != be32_to_cpu(dsl->sl_offset)) - return false; - if (size != be32_to_cpu(dsl->sl_bytes)) - return false; - if (ino != be64_to_cpu(dsl->sl_owner)) - return false; - - /* ok */ - return true; -} - -static bool -xfs_symlink_verify( - struct xfs_buf *bp) -{ - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_dsymlink_hdr *dsl = bp->b_addr; - - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return false; - if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC)) - return false; - if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_uuid)) - return false; - if (bp->b_bn != be64_to_cpu(dsl->sl_blkno)) - return false; - if (be32_to_cpu(dsl->sl_offset) + - be32_to_cpu(dsl->sl_bytes) >= MAXPATHLEN) - return false; - if (dsl->sl_owner == 0) - return false; - - return true; -} - -static void -xfs_symlink_read_verify( - struct xfs_buf *bp) -{ - struct xfs_mount *mp = bp->b_target->bt_mount; - - /* no verification of non-crc buffers */ - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return; - - if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), - offsetof(struct xfs_dsymlink_hdr, sl_crc)) || - !xfs_symlink_verify(bp)) { - XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); - xfs_buf_ioerror(bp, EFSCORRUPTED); - } -} - -static void -xfs_symlink_write_verify( - struct xfs_buf *bp) -{ - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; - - /* no verification of non-crc buffers */ - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return; - - if (!xfs_symlink_verify(bp)) { - XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); - xfs_buf_ioerror(bp, EFSCORRUPTED); - return; - } - - if (bip) { - struct xfs_dsymlink_hdr *dsl = bp->b_addr; - dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn); - } - xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), - offsetof(struct xfs_dsymlink_hdr, sl_crc)); -} - -const struct xfs_buf_ops xfs_symlink_buf_ops = { - .verify_read = xfs_symlink_read_verify, - .verify_write = xfs_symlink_write_verify, -}; - -void -xfs_symlink_local_to_remote( - struct xfs_trans *tp, - struct xfs_buf *bp, - struct xfs_inode *ip, - struct xfs_ifork *ifp) -{ - struct xfs_mount *mp = ip->i_mount; - char *buf; - - if (!xfs_sb_version_hascrc(&mp->m_sb)) { - bp->b_ops = NULL; - memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes); - return; - } - - /* - * As this symlink fits in an inode literal area, it must also fit in - * the smallest buffer the filesystem supports. - */ - ASSERT(BBTOB(bp->b_length) >= - ifp->if_bytes + sizeof(struct xfs_dsymlink_hdr)); - - bp->b_ops = &xfs_symlink_buf_ops; - - buf = bp->b_addr; - buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp); - memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes); -} /* ----- Kernel only functions below ----- */ STATIC int @@ -360,6 +189,7 @@ xfs_symlink( prid_t prid; struct xfs_dquot *udqp = NULL; struct xfs_dquot *gdqp = NULL; + struct xfs_dquot *pdqp = NULL; uint resblks; *ipp = NULL; @@ -385,8 +215,11 @@ xfs_symlink( /* * Make sure that we have allocated dquot(s) on disk. */ - error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, - XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); + error = xfs_qm_vop_dqalloc(dp, + xfs_kuid_to_uid(current_fsuid()), + xfs_kgid_to_gid(current_fsgid()), prid, + XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, + &udqp, &gdqp, &pdqp); if (error) goto std_return; @@ -401,12 +234,10 @@ xfs_symlink( else fs_blocks = xfs_symlink_blocks(mp, pathlen); resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks); - error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_symlink, resblks, 0); if (error == ENOSPC && fs_blocks == 0) { resblks = 0; - error = xfs_trans_reserve(tp, 0, XFS_SYMLINK_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_symlink, 0, 0); } if (error) { cancel_flags = 0; @@ -427,7 +258,8 @@ xfs_symlink( /* * Reserve disk quota : blocks and inode. */ - error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, resblks, 1, 0); + error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, + pdqp, resblks, 1, 0); if (error) goto error_return; @@ -465,7 +297,7 @@ xfs_symlink( /* * Also attach the dquot(s) to it, if applicable. */ - xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp); + xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); if (resblks) resblks -= XFS_IALLOC_SPACE_RES(mp); @@ -563,6 +395,7 @@ xfs_symlink( error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); xfs_qm_dqrele(udqp); xfs_qm_dqrele(gdqp); + xfs_qm_dqrele(pdqp); *ipp = ip; return 0; @@ -576,6 +409,7 @@ xfs_symlink( xfs_trans_cancel(tp, cancel_flags); xfs_qm_dqrele(udqp); xfs_qm_dqrele(gdqp); + xfs_qm_dqrele(pdqp); if (unlock_dp_on_error) xfs_iunlock(dp, XFS_ILOCK_EXCL); @@ -706,8 +540,8 @@ xfs_inactive_symlink_rmt( * Put an itruncate log reservation in the new transaction * for our caller. */ - if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, XFS_ITRUNCATE_LOG_COUNT))) { + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); + if (error) { ASSERT(XFS_FORCED_SHUTDOWN(mp)); goto error0; }