linux/fs/xfs/xfs_symlink.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
   3 * Copyright (c) 2012-2013 Red Hat, Inc.
   4 * All rights reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it would be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write the Free Software Foundation,
  17 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18 */
  19#include "xfs.h"
  20#include "xfs_shared.h"
  21#include "xfs_fs.h"
  22#include "xfs_format.h"
  23#include "xfs_log_format.h"
  24#include "xfs_trans_resv.h"
  25#include "xfs_bit.h"
  26#include "xfs_mount.h"
  27#include "xfs_da_format.h"
  28#include "xfs_da_btree.h"
  29#include "xfs_defer.h"
  30#include "xfs_dir2.h"
  31#include "xfs_inode.h"
  32#include "xfs_ialloc.h"
  33#include "xfs_alloc.h"
  34#include "xfs_bmap.h"
  35#include "xfs_bmap_btree.h"
  36#include "xfs_bmap_util.h"
  37#include "xfs_error.h"
  38#include "xfs_quota.h"
  39#include "xfs_trans_space.h"
  40#include "xfs_trace.h"
  41#include "xfs_symlink.h"
  42#include "xfs_trans.h"
  43#include "xfs_log.h"
  44
  45/* ----- Kernel only functions below ----- */
  46STATIC int
  47xfs_readlink_bmap(
  48        struct xfs_inode        *ip,
  49        char                    *link)
  50{
  51        struct xfs_mount        *mp = ip->i_mount;
  52        struct xfs_bmbt_irec    mval[XFS_SYMLINK_MAPS];
  53        struct xfs_buf          *bp;
  54        xfs_daddr_t             d;
  55        char                    *cur_chunk;
  56        int                     pathlen = ip->i_d.di_size;
  57        int                     nmaps = XFS_SYMLINK_MAPS;
  58        int                     byte_cnt;
  59        int                     n;
  60        int                     error = 0;
  61        int                     fsblocks = 0;
  62        int                     offset;
  63
  64        fsblocks = xfs_symlink_blocks(mp, pathlen);
  65        error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
  66        if (error)
  67                goto out;
  68
  69        offset = 0;
  70        for (n = 0; n < nmaps; n++) {
  71                d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
  72                byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
  73
  74                bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
  75                                  &xfs_symlink_buf_ops);
  76                if (!bp)
  77                        return -ENOMEM;
  78                error = bp->b_error;
  79                if (error) {
  80                        xfs_buf_ioerror_alert(bp, __func__);
  81                        xfs_buf_relse(bp);
  82
  83                        /* bad CRC means corrupted metadata */
  84                        if (error == -EFSBADCRC)
  85                                error = -EFSCORRUPTED;
  86                        goto out;
  87                }
  88                byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
  89                if (pathlen < byte_cnt)
  90                        byte_cnt = pathlen;
  91
  92                cur_chunk = bp->b_addr;
  93                if (xfs_sb_version_hascrc(&mp->m_sb)) {
  94                        if (!xfs_symlink_hdr_ok(ip->i_ino, offset,
  95                                                        byte_cnt, bp)) {
  96                                error = -EFSCORRUPTED;
  97                                xfs_alert(mp,
  98"symlink header does not match required off/len/owner (0x%x/Ox%x,0x%llx)",
  99                                        offset, byte_cnt, ip->i_ino);
 100                                xfs_buf_relse(bp);
 101                                goto out;
 102
 103                        }
 104
 105                        cur_chunk += sizeof(struct xfs_dsymlink_hdr);
 106                }
 107
 108                memcpy(link + offset, cur_chunk, byte_cnt);
 109
 110                pathlen -= byte_cnt;
 111                offset += byte_cnt;
 112
 113                xfs_buf_relse(bp);
 114        }
 115        ASSERT(pathlen == 0);
 116
 117        link[ip->i_d.di_size] = '\0';
 118        error = 0;
 119
 120 out:
 121        return error;
 122}
 123
 124int
 125xfs_readlink(
 126        struct xfs_inode *ip,
 127        char            *link)
 128{
 129        struct xfs_mount *mp = ip->i_mount;
 130        xfs_fsize_t     pathlen;
 131        int             error = 0;
 132
 133        trace_xfs_readlink(ip);
 134
 135        ASSERT(!(ip->i_df.if_flags & XFS_IFINLINE));
 136
 137        if (XFS_FORCED_SHUTDOWN(mp))
 138                return -EIO;
 139
 140        xfs_ilock(ip, XFS_ILOCK_SHARED);
 141
 142        pathlen = ip->i_d.di_size;
 143        if (!pathlen)
 144                goto out;
 145
 146        if (pathlen < 0 || pathlen > MAXPATHLEN) {
 147                xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
 148                         __func__, (unsigned long long) ip->i_ino,
 149                         (long long) pathlen);
 150                ASSERT(0);
 151                error = -EFSCORRUPTED;
 152                goto out;
 153        }
 154
 155
 156        error = xfs_readlink_bmap(ip, link);
 157
 158 out:
 159        xfs_iunlock(ip, XFS_ILOCK_SHARED);
 160        return error;
 161}
 162
 163int
 164xfs_symlink(
 165        struct xfs_inode        *dp,
 166        struct xfs_name         *link_name,
 167        const char              *target_path,
 168        umode_t                 mode,
 169        struct xfs_inode        **ipp)
 170{
 171        struct xfs_mount        *mp = dp->i_mount;
 172        struct xfs_trans        *tp = NULL;
 173        struct xfs_inode        *ip = NULL;
 174        int                     error = 0;
 175        int                     pathlen;
 176        struct xfs_defer_ops    dfops;
 177        xfs_fsblock_t           first_block;
 178        bool                    unlock_dp_on_error = false;
 179        xfs_fileoff_t           first_fsb;
 180        xfs_filblks_t           fs_blocks;
 181        int                     nmaps;
 182        struct xfs_bmbt_irec    mval[XFS_SYMLINK_MAPS];
 183        xfs_daddr_t             d;
 184        const char              *cur_chunk;
 185        int                     byte_cnt;
 186        int                     n;
 187        xfs_buf_t               *bp;
 188        prid_t                  prid;
 189        struct xfs_dquot        *udqp = NULL;
 190        struct xfs_dquot        *gdqp = NULL;
 191        struct xfs_dquot        *pdqp = NULL;
 192        uint                    resblks;
 193
 194        *ipp = NULL;
 195
 196        trace_xfs_symlink(dp, link_name);
 197
 198        if (XFS_FORCED_SHUTDOWN(mp))
 199                return -EIO;
 200
 201        /*
 202         * Check component lengths of the target path name.
 203         */
 204        pathlen = strlen(target_path);
 205        if (pathlen >= MAXPATHLEN)      /* total string too long */
 206                return -ENAMETOOLONG;
 207
 208        udqp = gdqp = NULL;
 209        prid = xfs_get_initial_prid(dp);
 210
 211        /*
 212         * Make sure that we have allocated dquot(s) on disk.
 213         */
 214        error = xfs_qm_vop_dqalloc(dp,
 215                        xfs_kuid_to_uid(current_fsuid()),
 216                        xfs_kgid_to_gid(current_fsgid()), prid,
 217                        XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
 218                        &udqp, &gdqp, &pdqp);
 219        if (error)
 220                return error;
 221
 222        /*
 223         * The symlink will fit into the inode data fork?
 224         * There can't be any attributes so we get the whole variable part.
 225         */
 226        if (pathlen <= XFS_LITINO(mp, dp->i_d.di_version))
 227                fs_blocks = 0;
 228        else
 229                fs_blocks = xfs_symlink_blocks(mp, pathlen);
 230        resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
 231
 232        error = xfs_trans_alloc(mp, &M_RES(mp)->tr_symlink, resblks, 0, 0, &tp);
 233        if (error == -ENOSPC && fs_blocks == 0) {
 234                resblks = 0;
 235                error = xfs_trans_alloc(mp, &M_RES(mp)->tr_symlink, 0, 0, 0,
 236                                &tp);
 237        }
 238        if (error)
 239                goto out_release_inode;
 240
 241        xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
 242        unlock_dp_on_error = true;
 243
 244        /*
 245         * Check whether the directory allows new symlinks or not.
 246         */
 247        if (dp->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) {
 248                error = -EPERM;
 249                goto out_trans_cancel;
 250        }
 251
 252        /*
 253         * Reserve disk quota : blocks and inode.
 254         */
 255        error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
 256                                                pdqp, resblks, 1, 0);
 257        if (error)
 258                goto out_trans_cancel;
 259
 260        /*
 261         * Check for ability to enter directory entry, if no space reserved.
 262         */
 263        if (!resblks) {
 264                error = xfs_dir_canenter(tp, dp, link_name);
 265                if (error)
 266                        goto out_trans_cancel;
 267        }
 268        /*
 269         * Initialize the bmap freelist prior to calling either
 270         * bmapi or the directory create code.
 271         */
 272        xfs_defer_init(&dfops, &first_block);
 273
 274        /*
 275         * Allocate an inode for the symlink.
 276         */
 277        error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), 1, 0,
 278                               prid, resblks > 0, &ip, NULL);
 279        if (error)
 280                goto out_trans_cancel;
 281
 282        /*
 283         * Now we join the directory inode to the transaction.  We do not do it
 284         * earlier because xfs_dir_ialloc might commit the previous transaction
 285         * (and release all the locks).  An error from here on will result in
 286         * the transaction cancel unlocking dp so don't do it explicitly in the
 287         * error path.
 288         */
 289        xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
 290        unlock_dp_on_error = false;
 291
 292        /*
 293         * Also attach the dquot(s) to it, if applicable.
 294         */
 295        xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
 296
 297        if (resblks)
 298                resblks -= XFS_IALLOC_SPACE_RES(mp);
 299        /*
 300         * If the symlink will fit into the inode, write it inline.
 301         */
 302        if (pathlen <= XFS_IFORK_DSIZE(ip)) {
 303                xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
 304
 305                ip->i_d.di_size = pathlen;
 306                ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
 307                xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
 308        } else {
 309                int     offset;
 310
 311                first_fsb = 0;
 312                nmaps = XFS_SYMLINK_MAPS;
 313
 314                error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks,
 315                                  XFS_BMAPI_METADATA, &first_block, resblks,
 316                                  mval, &nmaps, &dfops);
 317                if (error)
 318                        goto out_bmap_cancel;
 319
 320                if (resblks)
 321                        resblks -= fs_blocks;
 322                ip->i_d.di_size = pathlen;
 323                xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 324
 325                cur_chunk = target_path;
 326                offset = 0;
 327                for (n = 0; n < nmaps; n++) {
 328                        char    *buf;
 329
 330                        d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
 331                        byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
 332                        bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
 333                                               BTOBB(byte_cnt), 0);
 334                        if (!bp) {
 335                                error = -ENOMEM;
 336                                goto out_bmap_cancel;
 337                        }
 338                        bp->b_ops = &xfs_symlink_buf_ops;
 339
 340                        byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
 341                        byte_cnt = min(byte_cnt, pathlen);
 342
 343                        buf = bp->b_addr;
 344                        buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset,
 345                                                   byte_cnt, bp);
 346
 347                        memcpy(buf, cur_chunk, byte_cnt);
 348
 349                        cur_chunk += byte_cnt;
 350                        pathlen -= byte_cnt;
 351                        offset += byte_cnt;
 352
 353                        xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
 354                        xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
 355                                                        (char *)bp->b_addr);
 356                }
 357                ASSERT(pathlen == 0);
 358        }
 359
 360        /*
 361         * Create the directory entry for the symlink.
 362         */
 363        error = xfs_dir_createname(tp, dp, link_name, ip->i_ino,
 364                                        &first_block, &dfops, resblks);
 365        if (error)
 366                goto out_bmap_cancel;
 367        xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
 368        xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
 369
 370        /*
 371         * If this is a synchronous mount, make sure that the
 372         * symlink transaction goes to disk before returning to
 373         * the user.
 374         */
 375        if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
 376                xfs_trans_set_sync(tp);
 377        }
 378
 379        error = xfs_defer_finish(&tp, &dfops, NULL);
 380        if (error)
 381                goto out_bmap_cancel;
 382
 383        error = xfs_trans_commit(tp);
 384        if (error)
 385                goto out_release_inode;
 386
 387        xfs_qm_dqrele(udqp);
 388        xfs_qm_dqrele(gdqp);
 389        xfs_qm_dqrele(pdqp);
 390
 391        *ipp = ip;
 392        return 0;
 393
 394out_bmap_cancel:
 395        xfs_defer_cancel(&dfops);
 396out_trans_cancel:
 397        xfs_trans_cancel(tp);
 398out_release_inode:
 399        /*
 400         * Wait until after the current transaction is aborted to finish the
 401         * setup of the inode and release the inode.  This prevents recursive
 402         * transactions and deadlocks from xfs_inactive.
 403         */
 404        if (ip) {
 405                xfs_finish_inode_setup(ip);
 406                IRELE(ip);
 407        }
 408
 409        xfs_qm_dqrele(udqp);
 410        xfs_qm_dqrele(gdqp);
 411        xfs_qm_dqrele(pdqp);
 412
 413        if (unlock_dp_on_error)
 414                xfs_iunlock(dp, XFS_ILOCK_EXCL);
 415        return error;
 416}
 417
 418/*
 419 * Free a symlink that has blocks associated with it.
 420 */
 421STATIC int
 422xfs_inactive_symlink_rmt(
 423        struct xfs_inode *ip)
 424{
 425        xfs_buf_t       *bp;
 426        int             done;
 427        int             error;
 428        xfs_fsblock_t   first_block;
 429        struct xfs_defer_ops    dfops;
 430        int             i;
 431        xfs_mount_t     *mp;
 432        xfs_bmbt_irec_t mval[XFS_SYMLINK_MAPS];
 433        int             nmaps;
 434        int             size;
 435        xfs_trans_t     *tp;
 436
 437        mp = ip->i_mount;
 438        ASSERT(ip->i_df.if_flags & XFS_IFEXTENTS);
 439        /*
 440         * We're freeing a symlink that has some
 441         * blocks allocated to it.  Free the
 442         * blocks here.  We know that we've got
 443         * either 1 or 2 extents and that we can
 444         * free them all in one bunmapi call.
 445         */
 446        ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2);
 447
 448        error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
 449        if (error)
 450                return error;
 451
 452        xfs_ilock(ip, XFS_ILOCK_EXCL);
 453        xfs_trans_ijoin(tp, ip, 0);
 454
 455        /*
 456         * Lock the inode, fix the size, and join it to the transaction.
 457         * Hold it so in the normal path, we still have it locked for
 458         * the second transaction.  In the error paths we need it
 459         * held so the cancel won't rele it, see below.
 460         */
 461        size = (int)ip->i_d.di_size;
 462        ip->i_d.di_size = 0;
 463        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 464        /*
 465         * Find the block(s) so we can inval and unmap them.
 466         */
 467        done = 0;
 468        xfs_defer_init(&dfops, &first_block);
 469        nmaps = ARRAY_SIZE(mval);
 470        error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size),
 471                                mval, &nmaps, 0);
 472        if (error)
 473                goto error_trans_cancel;
 474        /*
 475         * Invalidate the block(s). No validation is done.
 476         */
 477        for (i = 0; i < nmaps; i++) {
 478                bp = xfs_trans_get_buf(tp, mp->m_ddev_targp,
 479                        XFS_FSB_TO_DADDR(mp, mval[i].br_startblock),
 480                        XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0);
 481                if (!bp) {
 482                        error = -ENOMEM;
 483                        goto error_bmap_cancel;
 484                }
 485                xfs_trans_binval(tp, bp);
 486        }
 487        /*
 488         * Unmap the dead block(s) to the dfops.
 489         */
 490        error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps,
 491                            &first_block, &dfops, &done);
 492        if (error)
 493                goto error_bmap_cancel;
 494        ASSERT(done);
 495        /*
 496         * Commit the first transaction.  This logs the EFI and the inode.
 497         */
 498        error = xfs_defer_finish(&tp, &dfops, ip);
 499        if (error)
 500                goto error_bmap_cancel;
 501        /*
 502         * The first xact was committed, so add the inode to the new one.
 503         * Mark it dirty so it will be logged and moved forward in the log as
 504         * part of every commit.
 505         */
 506        xfs_trans_ijoin(tp, ip, 0);
 507        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 508        /*
 509         * Commit the transaction containing extent freeing and EFDs.
 510         */
 511        error = xfs_trans_commit(tp);
 512        if (error) {
 513                ASSERT(XFS_FORCED_SHUTDOWN(mp));
 514                goto error_unlock;
 515        }
 516
 517        /*
 518         * Remove the memory for extent descriptions (just bookkeeping).
 519         */
 520        if (ip->i_df.if_bytes)
 521                xfs_idata_realloc(ip, -ip->i_df.if_bytes, XFS_DATA_FORK);
 522        ASSERT(ip->i_df.if_bytes == 0);
 523
 524        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 525        return 0;
 526
 527error_bmap_cancel:
 528        xfs_defer_cancel(&dfops);
 529error_trans_cancel:
 530        xfs_trans_cancel(tp);
 531error_unlock:
 532        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 533        return error;
 534}
 535
 536/*
 537 * xfs_inactive_symlink - free a symlink
 538 */
 539int
 540xfs_inactive_symlink(
 541        struct xfs_inode        *ip)
 542{
 543        struct xfs_mount        *mp = ip->i_mount;
 544        int                     pathlen;
 545
 546        trace_xfs_inactive_symlink(ip);
 547
 548        if (XFS_FORCED_SHUTDOWN(mp))
 549                return -EIO;
 550
 551        xfs_ilock(ip, XFS_ILOCK_EXCL);
 552
 553        /*
 554         * Zero length symlinks _can_ exist.
 555         */
 556        pathlen = (int)ip->i_d.di_size;
 557        if (!pathlen) {
 558                xfs_iunlock(ip, XFS_ILOCK_EXCL);
 559                return 0;
 560        }
 561
 562        if (pathlen < 0 || pathlen > MAXPATHLEN) {
 563                xfs_alert(mp, "%s: inode (0x%llx) bad symlink length (%d)",
 564                         __func__, (unsigned long long)ip->i_ino, pathlen);
 565                xfs_iunlock(ip, XFS_ILOCK_EXCL);
 566                ASSERT(0);
 567                return -EFSCORRUPTED;
 568        }
 569
 570        if (ip->i_df.if_flags & XFS_IFINLINE) {
 571                if (ip->i_df.if_bytes > 0) 
 572                        xfs_idata_realloc(ip, -(ip->i_df.if_bytes),
 573                                          XFS_DATA_FORK);
 574                xfs_iunlock(ip, XFS_ILOCK_EXCL);
 575                ASSERT(ip->i_df.if_bytes == 0);
 576                return 0;
 577        }
 578
 579        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 580
 581        /* remove the remote symlink */
 582        return xfs_inactive_symlink_rmt(ip);
 583}
 584