!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/fs/xfs/linux/   drwxr-xr-x
Free 318.36 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     xfs_iops.c (16.87 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 * 
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 * 
 * http://www.sgi.com 
 * 
 * For further information regarding this notice, see: 
 * 
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
 */

#include <xfs.h>
#include <linux/mm.h>
#include <linux/locks.h>
#include <linux/xfs_iops.h>


/*
 * Pull the link count and size up from the xfs inode to the linux inode
 */

static void validate_fields(struct inode *ip)
{
    vnode_t    *vp = LINVFS_GET_VN_ADDRESS(ip);
    vattr_t va;
    int    error;

    va.va_mask = AT_NLINK|AT_SIZE;
    VOP_GETATTR(vp, &va, ATTR_LAZY, NULL, error);
    ip->i_nlink = va.va_nlink;
    ip->i_size = va.va_size;
    ip->i_blocks = va.va_nblocks;
}


/*
 * Common code used to create/instantiate various things in a directory.
 */

int linvfs_common_cr(struct inode *dir, struct dentry *dentry, int mode,
                enum vtype tp, int rdev)
{
    int        error = 0;
    vnode_t        *dvp, *vp = NULL;
    struct inode    *ip;
    vattr_t        va;
    xfs_acl_t    pdacl; /* parent default ACL */
    int        have_default_acl;

    dvp = LINVFS_GET_VN_ADDRESS(dir);
    ASSERT(dvp);

    bzero(&va, sizeof(va));
    va.va_mask = AT_TYPE|AT_MODE;
    va.va_type = tp;
    have_default_acl = _ACL_GET_DEFAULT(dvp, &pdacl);
/* FIXME: This is a temporary fix for the XFS/NFS ACL/umask problem.  Review it
 * when we agree with Andreas G. how ACLs are to be handled.
 * It is wrapped in CONFIG_FS_POSIX_ACL so this code can compile without
 * applying the split-acl-extattr patch.  KAO
 */
#ifdef    CONFIG_FS_POSIX_ACL
    if (IS_POSIX_ACL(dir) && !have_default_acl)
        mode &= ~current->fs->umask;
#endif
    va.va_mode = mode;    
    va.va_size = 0;

    if (tp == VREG) {
        VOP_CREATE(dvp, (char *)dentry->d_name.name, &va, 0, 0, &vp,
                            NULL, error);
    } else if (ISVDEV(tp)) {
        /*
         * Get the real type from the mode
         */
        va.va_rdev = rdev;
        va.va_mask |= AT_RDEV;

        va.va_type = IFTOVT(mode);
        if (va.va_type == VNON) {
            return -EINVAL;
        }
        VOP_CREATE(dvp, (char *)dentry->d_name.name, &va, 0, 0, &vp,
            NULL, error);
    } else if (tp == VDIR) {
        VOP_MKDIR(dvp, (char *)dentry->d_name.name, &va, &vp,
            NULL, error);
    } else {
        error = EINVAL;
    }

    if (!error) {
        ASSERT(vp);
        ip = LINVFS_GET_IP(vp);
        if (!ip) {
            VN_RELE(vp);
            return -ENOMEM;
        }
        if (ISVDEV(tp))
            ip->i_rdev = to_kdev_t(rdev);
        linvfs_set_inode_ops(ip);
        /* linvfs_revalidate_core returns (-) errors */
        error = -linvfs_revalidate_core(ip, ATTR_COMM);
        validate_fields(dir);
        d_instantiate(dentry, ip);
        mark_inode_dirty(ip);
    }

    if (!error && have_default_acl) {
        error = _ACL_INHERIT(vp, &va, &pdacl);
        VMODIFY(vp);
    }

    return -error;
}

/*
 * Create a new file in dir using mode.
 */
int linvfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
    return(linvfs_common_cr(dir, dentry, mode, VREG, 0));
}

struct dentry * linvfs_lookup(struct inode *dir, struct dentry *dentry)
{
    int        error;
    vnode_t        *vp, *cvp;
    pathname_t    pn;
    pathname_t      *pnp = &pn;
    struct inode    *ip = NULL;

    if (dentry->d_name.len >= MAXNAMELEN)
        return ERR_PTR(-ENAMETOOLONG);

    vp = LINVFS_GET_VN_ADDRESS(dir);

    /*
     * Initialize a pathname_t to pass down.
     */
    bzero(pnp, sizeof(pathname_t));
    pnp->pn_complen = dentry->d_name.len;
    pnp->pn_hash = dentry->d_name.hash;
    pnp->pn_path = (char *)dentry->d_name.name;

    cvp = NULL;

    VOP_LOOKUP(vp, (char *)dentry->d_name.name, &cvp, pnp, 0, NULL,
                        NULL, error);
    if (!error) {
        ASSERT(cvp);
        ip = LINVFS_GET_IP(cvp);
        if (!ip) {
            VN_RELE(cvp);
            return ERR_PTR(-EACCES);
        }
        linvfs_set_inode_ops(ip);
        error = linvfs_revalidate_core(ip, ATTR_COMM);
    }
    d_add(dentry, ip);    /* Negative entry goes in if ip is NULL */
    return NULL;
}


int linvfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
    int        error;
    vnode_t        *tdvp;    /* Target directory for new name/link */
    vnode_t        *vp;    /* vp of name being linked */
    struct inode    *ip;    /* inode of guy being linked to */

    ip = old_dentry->d_inode;    /* inode being linked to */
    if (S_ISDIR(ip->i_mode))
        return -EPERM;

    tdvp = LINVFS_GET_VN_ADDRESS(dir);

    vp = LINVFS_GET_VN_ADDRESS(ip);

    error = 0;
    VOP_LINK(tdvp, vp, (char *)dentry->d_name.name, NULL, error);
    if (!error) {
        VMODIFY(tdvp);
        ip->i_ctime = CURRENT_TIME;
        VN_HOLD(vp);
        validate_fields(ip);
        d_instantiate(dentry, ip);
        mark_inode_dirty(ip);
        mark_inode_dirty(LINVFS_GET_IP(tdvp));
    }
    return -error;
}


int linvfs_unlink(struct inode *dir, struct dentry *dentry)
{
    int        error = 0;
    struct inode    *inode;
    vnode_t        *dvp;    /* directory containing name to remove */

    inode = dentry->d_inode;

    dvp = LINVFS_GET_VN_ADDRESS(dir);

    VOP_REMOVE(dvp, (char *)dentry->d_name.name, NULL, error);

    if (!error) {
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        dir->i_version = ++event;

        inode->i_ctime = dir->i_ctime;
        validate_fields(dir);    /* For size only */
        validate_fields(inode);
        mark_inode_dirty(inode);
        mark_inode_dirty(LINVFS_GET_IP(dvp));
    }

    return -error;
}


int linvfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
{
    int        error;
    vnode_t        *dvp;    /* directory containing name to remove */
    vnode_t        *cvp;    /* used to lookup symlink to put in dentry */
    vattr_t        va;
    struct inode    *ip = NULL;

    dvp = LINVFS_GET_VN_ADDRESS(dir);

    bzero(&va, sizeof(va));
    va.va_type = VLNK;
    va.va_mode = 0777 & ~current->fs->umask;
    va.va_mask = AT_TYPE|AT_MODE; /* AT_PROJID? */

    error = 0;
    VOP_SYMLINK(dvp, (char *)dentry->d_name.name, &va, (char *)symname,
                            &cvp, NULL, error);
    if (!error) {
        ASSERT(cvp);
        ASSERT(cvp->v_type == VLNK);
        ip = LINVFS_GET_IP(cvp);
        if (!ip) {
            error = ENOMEM;
            VN_RELE(cvp);
        } else {
            linvfs_set_inode_ops(ip);
            /* linvfs_revalidate_core returns (-) errors */
            error = -linvfs_revalidate_core(ip, ATTR_COMM);
            d_instantiate(dentry, ip);
            validate_fields(dir);
            mark_inode_dirty(ip);
            mark_inode_dirty(dir);
        }
    }
    return -error;
}


int linvfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
    return(linvfs_common_cr(dir, dentry, mode, VDIR, 0));
}


int linvfs_rmdir(struct inode *dir, struct dentry *dentry)
{
    int        error;
    vnode_t        *dvp,        /* directory with name to remove */
            *pwd_vp;    /* current working directory, vnode */
    struct inode *inode = dentry->d_inode;

    dvp = LINVFS_GET_VN_ADDRESS(dir);

    pwd_vp = NULL;            /* Used for an unnecessary test */

    /*
     * Someday we could pass the dentry->d_inode into VOP_REMOVE so
     * that it can skip the lookup.
     */

    error = 0;
    VOP_RMDIR(dvp, (char *)dentry->d_name.name, pwd_vp, NULL, error);
    if (!error) {
        validate_fields(inode);
        validate_fields(dir);
        inode->i_version = ++event;
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        mark_inode_dirty(inode);
        mark_inode_dirty(dir);
    }
    return -error;
}


int linvfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
{
    int error = 0;
    enum vtype tp;

    if (S_ISCHR(mode)) {
        tp = VCHR;
    } else if (S_ISBLK(mode)) {
        tp = VBLK;
    } else if (S_ISFIFO(mode)) {
        tp = VFIFO;
    } else if (S_ISSOCK(mode)) {
        tp = VSOCK;
    } else {
        return -EINVAL;
    }

    /* linvfs_common_cr will return (-) errors */
    error = linvfs_common_cr(dir, dentry, mode, tp, rdev);

    return(error);
}


int linvfs_rename(struct inode *odir, struct dentry *odentry,
           struct inode *ndir, struct dentry *ndentry)
{
    int        error;
    vnode_t        *fvp;    /* from directory */
    vnode_t        *tvp;    /* target directory */
    pathname_t    pn;
    pathname_t      *pnp = &pn;
    struct inode    *new_inode = NULL;

    bzero(pnp, sizeof(pathname_t));
    pnp->pn_complen = ndentry->d_name.len;
    pnp->pn_hash = ndentry->d_name.hash;
    pnp->pn_path = (char *)ndentry->d_name.name;

    fvp = LINVFS_GET_VN_ADDRESS(odir);

    tvp = LINVFS_GET_VN_ADDRESS(ndir);

    new_inode = ndentry->d_inode;

    VOP_RENAME(fvp, (char *)odentry->d_name.name, tvp,
               (char *)ndentry->d_name.name, pnp, NULL, error);
    if (error)
        return -error;

    ndir->i_version = ++event;
    odir->i_version = ++event;
    if (new_inode) {
        new_inode->i_ctime = CURRENT_TIME;
        validate_fields(new_inode);
    }

    odir->i_ctime = odir->i_mtime = CURRENT_TIME;

    validate_fields(odir);
    if (ndir != odir)
        validate_fields(ndir);
    mark_inode_dirty(ndir);
    return 0;
}


int linvfs_readlink(struct dentry *dentry, char *buf, int size)
{
    vnode_t    *vp;
    uio_t    uio;
    iovec_t    iov;
    int    error = 0;

    vp = LINVFS_GET_VN_ADDRESS(dentry->d_inode);

    iov.iov_base = buf;
    iov.iov_len = size;

    uio.uio_iov = &iov;
    uio.uio_offset = 0;
    uio.uio_segflg = UIO_USERSPACE;
    uio.uio_resid = size;

    VOP_READLINK(vp, &uio, NULL, error);
    if (error)
        return -error;

    return (size - uio.uio_resid);
}

/*
 * careful here - this function can get called recusively up
 * to 32 times, hence we need to be very careful about how much
 * stack we use. uio is kmalloced for this reason...
 */

int linvfs_follow_link(struct dentry *dentry,
                   struct nameidata *nd)
{
    vnode_t    *vp;
    uio_t    *uio;
    iovec_t    iov;
    int    error = 0;
    char    *link;

    ASSERT(dentry);
    ASSERT(nd);

    link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);
    if (!link)
        return -ENOMEM;

    uio = (uio_t*)kmalloc(sizeof(uio_t), GFP_KERNEL);
    if (!uio) {
        kfree(link);
        return -ENOMEM;
    }

    vp = LINVFS_GET_VN_ADDRESS(dentry->d_inode);

    iov.iov_base = link;
    iov.iov_len = MAXNAMELEN;

    uio->uio_iov = &iov;
    uio->uio_offset = 0;
    uio->uio_segflg = UIO_SYSSPACE;
    uio->uio_resid = MAXNAMELEN;
    uio->uio_fmode = 0;

    VOP_READLINK(vp, uio, NULL, error);
    if (error) {
        kfree(uio);
        kfree(link);
        return -error;
    }

    link[MAXNAMELEN - uio->uio_resid] = '\0';
    kfree(uio);

    /* vfs_follow_link returns (-) errors */
    error = vfs_follow_link(nd, link);
    kfree(link);
    return error;
}

int linvfs_permission(struct inode *ip, int mode)
{
    vnode_t    *vp;
    int    error;

    mode <<= 6;        /* convert from linux to vnode access bits */
    vp = LINVFS_GET_VN_ADDRESS(ip);
    VOP_ACCESS(vp, mode, NULL, error);
    return -error;
}

/* Brute force approach for now - copy data into linux inode
 * from the results of a getattr. This gets called out of things
 * like stat.
 */
int linvfs_revalidate_core(struct inode *inode, int flags)
{
    vnode_t *vp;

    vp = LINVFS_GET_VP(inode);
    ASSERT(vp);
    /* vn_revalidate returns (-) error so this is ok */
    return vn_revalidate(vp, flags);
}

STATIC int linvfs_revalidate(struct dentry *dentry)
{
    vnode_t *vp;

    vp = LINVFS_GET_VP(dentry->d_inode);
    if (vp->v_flag & VMODIFIED) {
        return linvfs_revalidate_core(dentry->d_inode, 0);
    }
    return 0;
}


int
linvfs_setattr(
    struct dentry    *dentry,
    struct iattr    *attr)
{
    vnode_t        *vp = LINVFS_GET_VN_ADDRESS(dentry->d_inode);
    vattr_t        vattr;

    unsigned int    ia_valid = attr->ia_valid;
    int        error;
    int        flags = 0;
    struct inode    *inode;

    inode = dentry->d_inode;

    memset(&vattr, 0, sizeof(vattr_t));
    if (ia_valid & ATTR_UID) {
        vattr.va_mask |= AT_UID; 
        vattr.va_uid = attr->ia_uid;
    }
    if (ia_valid & ATTR_GID) {
        vattr.va_mask |= AT_GID;
        vattr.va_gid = attr->ia_gid;
    }
    if (ia_valid & ATTR_SIZE) {
        vattr.va_mask |= AT_SIZE;
        vattr.va_size = attr->ia_size;
    }
    if (ia_valid & ATTR_ATIME) {
        vattr.va_mask |= AT_ATIME;
        vattr.va_atime.tv_sec = attr->ia_atime;
        vattr.va_atime.tv_nsec = 0;
    }
    if (ia_valid & ATTR_MTIME) {
        vattr.va_mask |= AT_MTIME;
        vattr.va_mtime.tv_sec = attr->ia_mtime;
        vattr.va_mtime.tv_nsec = 0;
    }
    if (ia_valid & ATTR_CTIME) {
        vattr.va_mask |= AT_CTIME;
        vattr.va_ctime.tv_sec = attr->ia_ctime;
        vattr.va_ctime.tv_nsec = 0;
    }
    if (ia_valid & ATTR_MODE) {
        vattr.va_mask |= AT_MODE;
        vattr.va_mode = attr->ia_mode;
        if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
            inode->i_mode &= ~S_ISGID;
    }

    if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))
        flags = ATTR_UTIME;

    VOP_SETATTR(vp, &vattr, flags, sys_cred, error);
    if (error)
        return(-error);    /* Positive error up from XFS */

    error = inode_setattr(inode, attr);
    
    return(error);
}

int
linvfs_pb_bmap(struct inode *inode, 
    loff_t offset,
    ssize_t count,
    page_buf_bmap_t *pbmapp,
    int maxpbbm, 
    int *retpbbm, 
    int flags)
{
    vnode_t        *vp;
    int        error;

    vp = LINVFS_GET_VN_ADDRESS(inode);

    *retpbbm = maxpbbm;

retry:
    if (flags & PBF_FILE_ALLOCATE) {
        VOP_STRATEGY(vp, offset, count, flags, NULL,
            (struct page_buf_bmap_s *) pbmapp, retpbbm, error);
    } else {
        VOP_BMAP(vp, offset, count, flags, NULL,
            (struct page_buf_bmap_s *) pbmapp, retpbbm, error);
    }
    if (flags & PBF_WRITE) {
        if ((flags & PBF_DIRECT) && *retpbbm &&
            (pbmapp->pbm_flags & PBMF_DELAY)) {
            flags = PBF_WRITE | PBF_FILE_ALLOCATE;
            goto retry;
        }
        VMODIFY(vp);
    }
    return -error;
}

STATIC
int linvfs_bmap(struct address_space *mapping, long block)
{
    struct inode        *inode          = (struct inode *)mapping->host;
    vnode_t             *vp             = LINVFS_GET_VN_ADDRESS(inode);
        pb_bmap_t           bmap            = {0};
        int                 nbm             = 1;
    int                 error;

    /* block             - linux disk blocks    512b */
    /* bmap input offset - bytes                  1b */
    /* bmap outut bn     - xfs BBs              512b */
    /* bmap outut delta  - bytes                  1b */

    vn_trace_entry(vp, "linvfs_bmap", (inst_t *)__return_address);

    VOP_RWLOCK(vp, VRWLOCK_READ);
    if (inode->i_mapping->nrpages) {
        VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
        if (error) {
            VOP_RWUNLOCK(vp, VRWLOCK_READ);
            /* VOP_FLUSH_PAGES currently returns nothing but 0... */
            return -error;
        }
    }

    VOP_BMAP(vp, block << 9, 1, PBF_READ, NULL, &bmap, &nbm, error);
    VOP_RWUNLOCK(vp, VRWLOCK_READ);
    if (error)
        return -error;
    if (bmap.pbm_bn < 0)
        return 0;
    return (int)(bmap.pbm_bn + (bmap.pbm_delta >> 9));
}
 
STATIC int linvfs_read_full_page(struct file *filp, struct page *page)
{
    return pagebuf_read_full_page(filp, page, linvfs_pb_bmap);
}

STATIC int linvfs_write_full_page(struct page *page)
{
    int    ret;
    int    flagset = 0;

    if ((current->flags & (PF_FSTRANS|PF_NOIO)) &&
        (!page->buffers || buffer_delay(page->buffers)))
        goto out_fail;

    if (!page->buffers || buffer_delay(page->buffers)) {
        current->flags |= PF_NOIO;
        flagset = 1;
    }

    ret = pagebuf_write_full_page(page, linvfs_pb_bmap);

    if (flagset)
        current->flags &= ~PF_NOIO;

    return ret;
out_fail:
    SetPageDirty(page);
    UnlockPage(page);
    return 0;
}

STATIC int linvfs_prepare_write(
    struct file *file,
    struct page *page,
    unsigned from,
    unsigned to)
{
    return pagebuf_prepare_write(file, page, from, to, linvfs_pb_bmap);
}

/* This gets a page into cleanable state - page locked on entry
 * kept locked on exit.
 */
STATIC int linvfs_release_page(
    struct page *page,
    int gfp_mask)
{
    if (page->buffers && !buffer_delay(page->buffers)) {
        return 1;
    }

    if (gfp_mask & __GFP_FS) {
        pagebuf_release_page(page, linvfs_pb_bmap);
        return 1;
    }
    return 0;
}


struct address_space_operations linvfs_aops = {
    readpage:        linvfs_read_full_page,
    writepage:        linvfs_write_full_page,
    sync_page:        block_sync_page,
    releasepage:        linvfs_release_page,
    bmap:            linvfs_bmap,
    prepare_write:        linvfs_prepare_write,
    commit_write:        pagebuf_commit_write,
};

struct inode_operations linvfs_file_inode_operations =
{
    permission:        linvfs_permission,
    revalidate:        linvfs_revalidate,
    setattr:        linvfs_setattr,
    setxattr:        linvfs_setxattr,
    getxattr:        linvfs_getxattr,
    listxattr:        linvfs_listxattr,
    removexattr:        linvfs_removexattr,
};

struct inode_operations linvfs_dir_inode_operations =
{
    create:            linvfs_create,
    lookup:            linvfs_lookup,
    link:            linvfs_link,    
    unlink:            linvfs_unlink,    
    symlink:        linvfs_symlink,    
    mkdir:            linvfs_mkdir,    
    rmdir:            linvfs_rmdir,    
    mknod:            linvfs_mknod,    
    rename:            linvfs_rename,    
    permission:        linvfs_permission,
    revalidate:        linvfs_revalidate,
    setattr:        linvfs_setattr,
    setxattr:        linvfs_setxattr,
    getxattr:        linvfs_getxattr,
    listxattr:        linvfs_listxattr,
    removexattr:        linvfs_removexattr,
};

struct inode_operations linvfs_symlink_inode_operations =
{
    readlink:        linvfs_readlink,
    follow_link:        linvfs_follow_link,
    permission:        linvfs_permission,
    revalidate:        linvfs_revalidate,
    setattr:        linvfs_setattr,
    setxattr:        linvfs_setxattr,
    getxattr:        linvfs_getxattr,
    listxattr:        linvfs_listxattr,
    removexattr:        linvfs_removexattr,
};

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0277 ]--