Beispiel #1
0
/*
 * careful here - this function can get called recursively, so
 * we need to be very careful about how much stack we use.
 * uio is kmalloced for this reason...
 */
STATIC const char *
xfs_vn_get_link(
	struct dentry		*dentry,
	struct inode		*inode,
	struct delayed_call	*done)
{
	char			*link;
	int			error = -ENOMEM;

	if (!dentry)
		return ERR_PTR(-ECHILD);

	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
	if (!link)
		goto out_err;

	error = xfs_readlink(XFS_I(d_inode(dentry)), link);
	if (unlikely(error))
		goto out_kfree;

	set_delayed_call(done, kfree_link, link);
	return link;

 out_kfree:
	kfree(link);
 out_err:
	return ERR_PTR(error);
}
Beispiel #2
0
/*
 * careful here - this function can get called recursively, so
 * we need to be very careful about how much stack we use.
 * uio is kmalloced for this reason...
 */
STATIC void *
xfs_vn_follow_link(
	struct dentry		*dentry,
	struct nameidata	*nd)
{
	char			*link;
	int			error = -ENOMEM;

	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
	if (!link)
		goto out_err;

	error = -xfs_readlink(XFS_I(dentry->d_inode), link);
	if (unlikely(error))
		goto out_kfree;

	nd_set_link(nd, link);
	return NULL;

 out_kfree:
	kfree(link);
 out_err:
	nd_set_link(nd, ERR_PTR(error));
	return NULL;
}
Beispiel #3
0
STATIC int
xfs_readlink_by_handle(
	xfs_mount_t		*mp,
	void			__user *arg,
	struct inode		*parinode)
{
	struct inode		*inode;
	xfs_fsop_handlereq_t	hreq;
	__u32			olen;
	void			*link;
	int			error;

	if (!capable(CAP_SYS_ADMIN))
		return -XFS_ERROR(EPERM);
	if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
		return -XFS_ERROR(EFAULT);

	error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode);
	if (error)
		return -error;

	/* Restrict this handle operation to symlinks only. */
	if (!S_ISLNK(inode->i_mode)) {
		error = -XFS_ERROR(EINVAL);
		goto out_iput;
	}

	if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
		error = -XFS_ERROR(EFAULT);
		goto out_iput;
	}

	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
	if (!link)
		goto out_iput;

	error = -xfs_readlink(XFS_I(inode), link);
	if (error)
		goto out_kfree;
	error = do_readlink(hreq.ohandle, olen, link);
	if (error)
		goto out_kfree;

 out_kfree:
	kfree(link);
 out_iput:
	iput(inode);
	return error;
}
Beispiel #4
0
int
xfs_readlink_by_handle(
	struct file		*parfilp,
	xfs_fsop_handlereq_t	*hreq)
{
	struct dentry		*dentry;
	__u32			olen;
	void			*link;
	int			error;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	/* Restrict this handle operation to symlinks only. */
	if (!d_is_symlink(dentry)) {
		error = -EINVAL;
		goto out_dput;
	}

	if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
		error = -EFAULT;
		goto out_dput;
	}

	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
	if (!link) {
		error = -ENOMEM;
		goto out_dput;
	}

	error = xfs_readlink(XFS_I(d_inode(dentry)), link);
	if (error)
		goto out_kfree;
	error = readlink_copy(hreq->ohandle, olen, link);
	if (error)
		goto out_kfree;

 out_kfree:
	kfree(link);
 out_dput:
	dput(dentry);
	return error;
}
Beispiel #5
0
int cli_ls_xfs_filldir(void *dirents, const char *name, int namelen, off_t offset, uint64_t inumber, unsigned flags) {
    char dname[256];
    char symlink[256];
    int r;
    xfs_inode_t *inode=NULL;
    struct stat fstats;
    char mode[]="rwxrwxrwx";
    int tests[]={S_IRUSR,S_IWUSR,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,S_IWOTH,S_IXOTH};

    struct filldir_data *data = (struct filldir_data *) dirents;
    memcpy(dname, name, namelen);
    dname[namelen] = '\0';
    r = libxfs_iget(data->mp, NULL, inumber, 0, &inode, 0);
    if (r) printf("Panic! %d\n", r);
    r = xfs_stat(inode, &fstats);
    if (r) printf("Panic! stats %d\n", r);
    if (xfs_is_dir(inode)) {
        printf("d");
    } else if (xfs_is_link(inode)) {
        printf("l");
    } else printf("-");

    for (r=0; r<9; r++) {
        if (fstats.st_mode & tests[r]) {
            printf("%c", mode[r]);
        } else {
            printf("-");
        }
    }
    
    print_int(fstats.st_uid, 6);
    print_int(fstats.st_gid, 6);
    print_int(fstats.st_size, 12);
    
    printf(" %s", dname);
    if (xfs_is_link(inode)) {
        r = xfs_readlink(inode, symlink, 0, 255, NULL);
        if (r > 0) {
            symlink[r] = '\0';
            printf("->%s", symlink);
        }
    }
    printf("\n");
    libxfs_iput(inode, 0);
    return 0;
}
Beispiel #6
0
static int
fuse_xfs_readlink(const char *path, char *buf, size_t size) {
    int r;
    xfs_inode_t *inode=NULL;

    log_debug("readlink %s\n", path); 
    
    r = find_path(current_xfs_mount(), path, &inode);
    if (r) {
        return -ENOENT;
    }
    
    r = xfs_readlink(inode, buf, 0, size, NULL);
    if (r < 0) {
        return r;
    }
    libxfs_iput(inode, 0);
    return 0;
}
Beispiel #7
0
/*
 * careful here - this function can get called recursively, so
 * we need to be very careful about how much stack we use.
 * uio is kmalloced for this reason...
 */
STATIC const char *
xfs_vn_follow_link(
	struct dentry		*dentry,
	void			**cookie)
{
	char			*link;
	int			error = -ENOMEM;

	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
	if (!link)
		goto out_err;

	error = xfs_readlink(XFS_I(d_inode(dentry)), link);
	if (unlikely(error))
		goto out_kfree;

	return *cookie = link;

 out_kfree:
	kfree(link);
 out_err:
	return ERR_PTR(error);
}
Beispiel #8
0
int main(int argc, char *argv[]) {
    xfs_mount_t	*mp;
    xfs_inode_t *inode = NULL;
    xfs_off_t ofs;
    struct filldir_data filldata;
    char *progname;
    char *source_name;
    int r, fd;
    char *line;
    char path[FILENAME_MAX] = "/";
    char newpath[FILENAME_MAX] = "/";
    char *buffer[BUFSIZE];
    off_t offset;

    if (argc != 2) {
        printf("Usage: xfs-cli raw_device\n");
        return 1;
    }
    progname = argv[0];
    source_name = argv[1];
    
    mp = mount_xfs(progname, source_name);
    
    if (mp == NULL) 
        return 1;
    
    while (line == fetchline(mp, path)) {
        inode = NULL;
        strip(line, ' ');
        if (strncmp(line, "cd ", 3) == 0) {
            if (strcmp(line+3, "..") == 0) {
                goto_parent(path);
            } else {
                strcpy(newpath, path);
                strcat(newpath, line+3);
                r = find_path(mp, newpath, &inode);
                if ((!r) && (xfs_is_dir(inode))) {
                    //TODO: check if it is a directory
                    strcpy(path, newpath);
                    strcat(path, "/");
                    printf("%s\n", path);
                } else {
                    if (r) {
                        printf("No such directory\n");
                    } else {
                        printf("Not a directory\n");
                    }
                }
            }
        }
        else if (strcmp(line, "ls") == 0) {
            r = find_path(mp, path, &inode);
            if (!r) {
                //TODO: check if it is a directory
                ofs=0;
                filldata.mp = mp;
                filldata.base = inode;
                r = xfs_readdir(inode, (void *)&filldata, 102400, &ofs, cli_ls_xfs_filldir);
                if (r != 0) {
                    printf("Not a directory\n");
                }
            } else {
                printf("No such directory\n");
            }
        }
        else if (strncmp(line, "cat ", 4) == 0) {
            strcpy(newpath, path);
            strcat(newpath, line+4);
            r = find_path(mp, newpath, &inode);
            if (r)
                printf("File not found\n");
            else if (xfs_is_regular(inode)) {
                //TODO: check if it is a file
                r = 10;
                offset = 0;
                while (r) {
                    r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL);
                    if (r) {
                        write(1, buffer, r);
                        offset += r;
                    }
                }
            } else if (xfs_is_link(inode)) {
                r = 10;
                offset = 0;
                while (r) {
                    r = xfs_readlink(inode, buffer, offset, BUFSIZE, NULL);
                    if (r) {
                        write(1, buffer, r);
                        offset += r;
                    }
                }
            } else {
                printf("Not a regular file\n");
            }
        }
        else if (strncmp(line, "get ", 4) == 0) {
            strcpy(newpath, path);
            strcat(newpath, line+4);
            r = find_path(mp, newpath, &inode);
            if ((!r) && (xfs_is_regular(inode))) {
                //TODO: check if it is a file
                r = 10;
                offset = 0;
                fd = open(line+4, O_WRONLY|O_CREAT, 0660);
                if (fd < 0) {
                    printf("Failed to open local file\n");
                } else {
                    while (r) {
                        r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL);
                        if (r) {
                            write(fd, buffer, r);
                            offset += r;
                        }
                    }
                    close(fd);
                    printf("Retrieved %ld bytes\n", offset);
                }
            } else {
                if (r) 
                    printf("File not found\n");
                else
                    printf("Not a regular file\n");
            }
        }
        else if (strcmp(line, "exit") == 0) {
            libxfs_umount(mp);
            return 0;
        }
        else if (strcmp(line, "pwd") == 0) {
            printf("%s\n", path);
        } else {
            printf("Unknown command\n");
        }
        free(line);
        if (inode) {
            libxfs_iput(inode, 0);
        }
    }
    libxfs_umount(mp);
    return 0;
}