Example #1
0
asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * dirent, unsigned int count)
{
    struct file * file;
    struct linux_dirent64 __user * lastdirent;
    struct getdents_callback64 buf;
    int error;

    error = -EFAULT;
    if (!access_ok(VERIFY_WRITE, dirent, count))
        goto out;

    error = -EBADF;
    file = fget(fd);
    if (!file)
        goto out;

    buf.current_dir = dirent;
    buf.previous = NULL;
    buf.count = count;
    buf.error = 0;

#if BITS_PER_LONG < 64
    error = vfs_readdir64(file, filldir6464, &buf);
    if (error < 0) {
        if (error != -ENOSYS)
            goto out_putf;
        error = vfs_readdir(file, filldir64, &buf);
        if (error < 0)
            goto out_putf;
    }
#else

    error = vfs_readdir(file, filldir64, &buf);
    if (error < 0)
        goto out_putf;

#endif

    error = buf.error;
    lastdirent = buf.previous;
    if (lastdirent) {
        typeof(lastdirent->d_off) d_off = file->f_pos;
        __put_user(d_off, &lastdirent->d_off);
        error = count - buf.count;
    }

out_putf:
    fput(file);
out:
    return error;
}
Example #2
0
static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct dentry *wrapfs_dentry = file->f_path.dentry;
#ifdef EXTRA_CREDIT
	struct wrapfs_getdents_callback buf;
	
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_MESG("Enter");
#endif

	lower_file = wrapfs_lower_file(file);
	// lower_file->f_pos = file->f_pos;

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_OTHER)
		DEBUG_MESG("Encrypting and Decrypting filenames");

	memset(&buf, 0, sizeof(buf));
	buf.dirent = dirent;
	buf.dentry = wrapfs_dentry;
	buf.filldir = filldir;
	buf.filldir_called = 0;
	buf.entries_written = 0;

	err = vfs_readdir(lower_file, wrapfs_filldir, (void *)&buf);

	if(err<0)
		goto out;
	if(buf.filldir_called && !buf.entries_written) {
		printk(KERN_ERR "wrapfs_readdir: filldir called but entries not written\n");
		goto out;
	}
#else
	err = vfs_readdir(lower_file, filldir, dirent);
#endif

	file->f_pos = lower_file->f_pos;
	if (err >= 0)		/* copy the atime */
		fsstack_copy_attr_atime(wrapfs_dentry->d_inode, lower_file->f_path.dentry->d_inode);

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_RETURN("Exit", err);

out:
#endif
	return err;
}
Example #3
0
static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir)
{
    struct dentry *dentry = file->f_dentry;
    struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
    int status;

    DPRINTK("file=%p dentry=%p %.*s",
            file, dentry, dentry->d_name.len, dentry->d_name.name);

    if (autofs4_oz_mode(sbi))
        goto out;

    if (autofs4_ispending(dentry)) {
        DPRINTK("dentry busy");
        return -EBUSY;
    }

    if (d_mountpoint(dentry)) {
        struct file *fp = file->private_data;

        if (!fp)
            return -ENOENT;

        if (!fp->f_op || !fp->f_op->readdir)
            goto out;

        status = vfs_readdir(fp, filldir, dirent);
        file->f_pos = fp->f_pos;
        if (status)
            autofs4_copy_atime(file, fp);
        return status;
    }
out:
    return autofs4_dcache_readdir(file, dirent, filldir);
}
Example #4
0
File: fs.c Project: 7L/pi_plus
int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
{
	struct file * file;
	struct hpux_dirent __user * lastdirent;
	struct getdents_callback buf;
	int error = -EBADF;

	file = fget(fd);
	if (!file)
		goto out;

	buf.current_dir = dirent;
	buf.previous = NULL;
	buf.count = count;
	buf.error = 0;

	error = vfs_readdir(file, filldir, &buf);
	if (error >= 0)
		error = buf.error;
	lastdirent = buf.previous;
	if (lastdirent) {
		if (put_user(file->f_pos, &lastdirent->d_off))
			error = -EFAULT;
		else
			error = count - buf.count;
	}

	fput(file);
out:
	return error;
}
Example #5
0
static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct dentry *dentry = file->f_path.dentry;
	struct dentry *parent;
	struct inode *inode = NULL;
	int bindex = 0;

	inode = dentry->d_inode;
	parent = dget_parent(dentry);

	for (bindex = 0; bindex <= 1; bindex++) {
		lower_file = wrapfs_lower_file_idx(file, bindex);
		if (!lower_file)
			continue;
		err = vfs_readdir(lower_file, filldir, dirent);
		file->f_pos = lower_file->f_pos;
		if (err >= 0) {
			/* copy the atime */
			fsstack_copy_attr_atime(dentry->d_inode,
				lower_file->f_path.dentry->d_inode);
			}
		}
	dput(parent);
	return err;
}
Example #6
0
static void fat_mmc_test_process_line(tstr_t *line)
{
    if (!tstr_cmp(line, &S("dir")))
        vfs_readdir(&S("FAT/"), fat_mmc_test_readdir_cb, NULL);

    console_printf("Ok\n");
}
Example #7
0
asmlinkage long sys_getdents64(unsigned int fd, void * dirent, unsigned int count)
{
	struct file * file;
	struct linux_dirent64 * lastdirent;
	struct getdents_callback64 buf;
	int error;

	error = -EBADF;
	file = fget(fd);
	if (!file)
		goto out;

	buf.current_dir = (struct linux_dirent64 *) dirent;
	buf.previous = NULL;
	buf.count = count;
	buf.error = 0;

	error = vfs_readdir(file, filldir64, &buf);
	if (error < 0)
		goto out_putf;
	error = buf.error;
	lastdirent = buf.previous;
	if (lastdirent) {
		struct linux_dirent64 d;
		d.d_off = file->f_pos;
		copy_to_user(&lastdirent->d_off, &d.d_off, sizeof(d.d_off));
		error = count - buf.count;
	}

out_putf:
	fput(file);
out:
	return error;
}
Example #8
0
int sys_readdir (uint_t fd, struct vfs_dirent_s *dirent)
{
	error_t err;
	struct task_s *task;
	struct thread_s *this;
	struct vfs_file_s *file;
  
	task = current_task;
	this = current_thread;

	if((dirent == NULL)                || 
	   (fd >= CONFIG_TASK_FILE_MAX_NR) || 
	   (task_fd_lookup(task,fd) == NULL))
	{
		this->info.errno = EBADFD;
		return -1;
	}

	file = task_fd_lookup(task,fd);
   
	if((err = vfs_readdir(file, dirent)))
	{
		this->info.errno = (err < 0) ? -err : err; 
		return -1;
	}
   
	return 0;
}
Example #9
0
SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
		struct old_linux_dirent __user *, dirent, unsigned int, count)
{
	int error;
	struct file * file;
	struct readdir_callback buf;

	if (scribe_track_next_file_read()) {
		scribe_kill(current->scribe->ctx, -ENOMEM);
		return -ENOMEM;
	}

	error = -EBADF;
	file = fget(fd);
	if (!file)
		goto out;

	buf.result = 0;
	buf.dirent = dirent;

	error = vfs_readdir(file, fillonedir, &buf);
	if (buf.result)
		error = buf.result;

	fput(file);
out:
	return error;
}
Example #10
0
asmlinkage long
sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count)
{
	struct file * file;
	struct linux32_dirent __user * lastdirent;
	struct getdents32_callback buf;
	int error;

	error = -EBADF;
	file = fget(fd);
	if (!file)
		goto out;

	buf.current_dir = (struct linux32_dirent __user *) dirent;
	buf.previous = NULL;
	buf.count = count;
	buf.error = 0;

	error = vfs_readdir(file, filldir32, &buf);
	if (error < 0)
		goto out_putf;
	error = buf.error;
	lastdirent = buf.previous;
	if (lastdirent) {
		put_user(file->f_pos, &lastdirent->d_off);
		error = count - buf.count;
	}

out_putf:
	fput(file);
out:
	return error;
}
/* file operations for directories */
int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir)
{
	struct dentry *coda_dentry = coda_file->f_dentry;
	struct coda_file_info *cfi;
	struct file *host_file;
	int ret;

	cfi = CODA_FTOC(coda_file);
	if (!cfi || cfi->cfi_magic != CODA_MAGIC) BUG();
	host_file = cfi->cfi_container;

	coda_vfs_stat.readdir++;

	down(&host_file->f_dentry->d_inode->i_sem);
	host_file->f_pos = coda_file->f_pos;

	if ( !host_file->f_op->readdir ) {
		/* Venus: we must read Venus dirents from the file */
		ret = coda_venus_readdir(host_file, filldir, dirent, coda_dentry);
	} else {
		/* potemkin case: we were handed a directory inode */
		ret = vfs_readdir(host_file, filldir, dirent);
	}

	coda_file->f_pos = host_file->f_pos;
	up(&host_file->f_dentry->d_inode->i_sem);

	return ret;
}
Example #12
0
/**
 * ecryptfs_readdir
 * @file: The eCryptfs directory file
 * @dirent: Directory entry handle
 * @filldir: The filldir callback function
 */
static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int rc;
	struct file *lower_file;
	struct inode *inode;
	struct ecryptfs_getdents_callback buf;

	lower_file = ecryptfs_file_to_lower(file);
	lower_file->f_pos = file->f_pos;
	inode = file->f_path.dentry->d_inode;
	memset(&buf, 0, sizeof(buf));
	buf.dirent = dirent;
	buf.dentry = file->f_path.dentry;
	buf.filldir = filldir;
	buf.filldir_called = 0;
	buf.entries_written = 0;
	rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf);
	file->f_pos = lower_file->f_pos;
	if (rc < 0)
		goto out;
	if (buf.filldir_called && !buf.entries_written)
		goto out;
	if (rc >= 0)
		fsstack_copy_attr_atime(inode,
					lower_file->f_path.dentry->d_inode);
out:
	return rc;
}
Example #13
0
void op_ls(const char **params, int nparams) {
  assert(nparams > 0);
  inode_t *ino = vfs_open(params[0], &dummy_access);

  assert(ino && "File not found!");
  vector_t files = vfs_readdir(ino);

  for (unsigned i = 0; i < vector_length(&files); ++i) {
    dirent_t *dent = vector_get(&files, i);
    const char *c;
    switch (dent->ino->type) {
    case it_file: c = "FILE"; break;
    case it_dir: c = "DIR"; break;
    case it_chardev: c = "CDEV"; break;
    case it_blockdev: c = "BDEV"; break;
    case it_fifo: c = "FIFO"; break;
    case it_socket: c = "SOCK"; break;
    default: assert(0);
    }
    kprintf("[[%s]] %s : nlink %d mode %x ctime %d mtime %d atime %d uid %d gid %d size %d\n",
            c,
            dent->name,
            dent->ino->nlink, dent->ino->mode,
            dent->ino->ctime, dent->ino->mtime, dent->ino->atime,
            dent->ino->uid, dent->ino->gid, dent->ino->size);
  }
}
Example #14
0
void list_directory (tux_req_t *req, int cachemiss)
{
	struct getdents_callback64 buf;
	struct linux_dirent64 *dirp0;
	mm_segment_t oldmm;
	int total;

	Dprintk("list_directory(%p, %d), dentry: %p.\n", req, cachemiss, req->dentry);
	if (!req->cwd_dentry)
		TUX_BUG();

	if (!cachemiss) {
		add_tux_atom(req, list_directory);
		queue_cachemiss(req);
		return;
	}

	dirp0 = tux_kmalloc(DIRENT_SIZE);

	buf.current_dir = dirp0;
	buf.previous = NULL;
	buf.count = DIRENT_SIZE;
	buf.error = 0;

	oldmm = get_fs(); set_fs(KERNEL_DS);
	set_fs(KERNEL_DS);
	total = vfs_readdir(req->in_file, filldir64, &buf);
	set_fs(oldmm);

	if (buf.previous)
		total = DIRENT_SIZE - buf.count;

	Dprintk("total: %d (buf.error: %d, buf.previous %p)\n",
		total, buf.error, buf.previous);

	if (total < 0) {
		kfree(dirp0);
		req_err(req);
		add_req_to_workqueue(req);
		return;
	}
	if (!total) {
		kfree(dirp0);
		req->in_file->f_pos = 0;
		add_req_to_workqueue(req);
		return;
	}

	if (!req->cwd_dentry)
		TUX_BUG();
	add_tux_atom(req, list_directory);

	req->dirp0 = dirp0;
	req->curroff = 0;
	req->total = total;
	add_tux_atom(req, do_dir_line);

	add_req_to_workqueue(req);
}
int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
{
	int err;

	err = vfs_readdir(file, filldir, arg);
	if (err >= 0)
		vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
	return err;
}
Example #16
0
int _ls_handler(int argc, char **argv)
{
    if (argc < 2) {
        _ls_usage(argv);
        return 1;
    }
    char *path = argv[1];
    uint8_t buf[16];
    int res;
    int ret = 0;
    res = vfs_normalize_path(path, path, strlen(path) + 1);
    if (res < 0) {
        _errno_string(res, (char *)buf, sizeof(buf));
        printf("Invalid path \"%s\": %s\n", path, buf);
        return 5;
    }
    vfs_DIR dir;
    res = vfs_opendir(&dir, path);
    if (res < 0) {
        _errno_string(res, (char *)buf, sizeof(buf));
        printf("vfs_opendir error: %s\n", buf);
        return 1;
    }
    unsigned int nfiles = 0;

    while (1) {
        vfs_dirent_t entry;
        res = vfs_readdir(&dir, &entry);
        if (res < 0) {
            _errno_string(res, (char *)buf, sizeof(buf));
            printf("vfs_readdir error: %s\n", buf);
            if (res == -EAGAIN) {
                /* try again */
                continue;
            }
            ret = 2;
            break;
        }
        if (res == 0) {
            /* end of stream */
            break;
        }
        printf("%s\n", entry.d_name);
        ++nfiles;
    }
    if (ret == 0) {
        printf("total %u files\n", nfiles);
    }

    res = vfs_closedir(&dir);
    if (res < 0) {
        _errno_string(res, (char *)buf, sizeof(buf));
        printf("vfs_closedir error: %s\n", buf);
        return 2;
    }
    return ret;
}
Example #17
0
/**
 * get_name - default export_operations->get_name function
 * @dentry: the directory in which to find a name
 * @name:   a pointer to a %NAME_MAX+1 char buffer to store the name
 * @child:  the dentry for the child directory.
 *
 * calls readdir on the parent until it finds an entry with
 * the same inode number as the child, and returns that.
 */
static int get_name(struct dentry *dentry, char *name,
			struct dentry *child)
{
	struct inode *dir = dentry->d_inode;
	int error;
	struct file *file;
	struct getdents_callback buffer;

	error = -ENOTDIR;
	if (!dir || !S_ISDIR(dir->i_mode))
		goto out;
	error = -EINVAL;
	if (!dir->i_fop)
		goto out;
	/*
	 * Open the directory ...
	 */
	file = dentry_open(dget(dentry), NULL, O_RDONLY);
	error = PTR_ERR(file);
	if (IS_ERR(file))
		goto out;

	error = -EINVAL;
	if (!file->f_op->readdir)
		goto out_close;

	buffer.name = name;
	buffer.ino = child->d_inode->i_ino;
	buffer.found = 0;
	buffer.sequence = 0;
	while (1) {
		int old_seq = buffer.sequence;

		error = vfs_readdir(file, filldir_one, &buffer);

		if (error < 0)
			break;

		error = 0;
		if (buffer.found)
			break;
		error = -ENOENT;
		if (old_seq == buffer.sequence)
			break;
	}

out_close:
	fput(file);
out:
	return error;
}
Example #18
0
/**
 * nfsd_get_name - default nfsd_operations->get_name function
 * @dentry: the directory in which to find a name
 * @name:   a pointer to a %NAME_MAX+1 char buffer to store the name
 * @child:  the dentry for the child directory.
 *
 * calls readdir on the parent until it finds an entry with
 * the same inode number as the child, and returns that.
 */
static int nfsd_get_name(struct dentry *dentry, char *name,
			struct dentry *child)
{
	struct inode *dir = dentry->d_inode;
	int error;
	struct file file;
	struct nfsd_getdents_callback buffer;

	error = -ENOTDIR;
	if (!dir || !S_ISDIR(dir->i_mode))
		goto out;
	error = -EINVAL;
	if (!dir->i_fop)
		goto out;
	/*
	 * Open the directory ...
	 */
	error = init_private_file(&file, dentry, FMODE_READ);
	if (error)
		goto out;
	error = -EINVAL;
	if (!file.f_op->readdir)
		goto out_close;

	buffer.name = name;
	buffer.ino = child->d_inode->i_ino;
	buffer.found = 0;
	buffer.sequence = 0;
	while (1) {
		int old_seq = buffer.sequence;

		error = vfs_readdir(&file, filldir_one, &buffer);

		if (error < 0)
			break;

		error = 0;
		if (buffer.found)
			break;
		error = -ENOENT;
		if (old_seq == buffer.sequence)
			break;
	}

out_close:
	if (file.f_op->release)
		file.f_op->release(dir, &file);
out:
	return error;
}
Example #19
0
static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct dentry *dentry = file->f_path.dentry;

	lower_file = wrapfs_lower_file(file);
	err = vfs_readdir(lower_file, filldir, dirent);
	file->f_pos = lower_file->f_pos;
	if (err >= 0)		/* copy the atime */
		fsstack_copy_attr_atime(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);
	return err;
}
Example #20
0
int do_vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
{
	int err;

	LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry));

	lockdep_off();
	err = vfs_readdir(file, filldir, arg);
	lockdep_on();
	if (err >= 0)
		au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry);
	/*ignore*/
	return err;
}
/*
 * scfs_readdir
 */
static int scfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	struct file *lower_file = NULL;
	struct dentry *dentry = file->f_path.dentry;
	int ret = 0;

	lower_file = scfs_lower_file(file);
	lower_file->f_pos = file->f_pos;
	ret = vfs_readdir(lower_file, filldir, dirent);
	file->f_pos = lower_file->f_pos;
	if (ret >= 0)
		fsstack_copy_attr_atime(dentry->d_inode, lower_file->f_path.dentry->d_inode);

	return ret;
}
Example #22
0
/**
 * lofs_readdir
 * @file:       The lofs directory file.
 * @dirent:     Buffer to fill with directory entries.
 * @filldir:    The filldir callback function
 */
static int lofs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
        int rc;
        struct file *lower_file;
        struct inode *inode;

        lower_file = lofs_file_to_lower(file);
        if (lower_file->f_pos != file->f_pos) {
            vfs_llseek(lower_file, file->f_pos, 0 /* SEEK_SET */);
        }
        inode = FILE_TO_DENTRY(file)->d_inode;
        rc = vfs_readdir(lower_file, filldir, dirent);
        file->f_pos = lower_file->f_pos;
        if (rc >= 0) {
            fsstack_copy_attr_atime(inode,FILE_TO_DENTRY(lower_file)->d_inode);
        }
        return rc;
}
Example #23
0
static int
nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
{
	struct file *filp;
	struct dentry_list_arg dla = {
		.parent = dir,
	};
	struct list_head *dentries = &dla.dentries;
	struct dentry_list *child;
	uid_t uid;
	gid_t gid;
	int status;

	if (!rec_dir_init)
		return 0;

	nfs4_save_user(&uid, &gid);

	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
	status = PTR_ERR(filp);
	if (IS_ERR(filp))
		goto out;
	INIT_LIST_HEAD(dentries);
	status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla);
	fput(filp);
	while (!list_empty(dentries)) {
		child = list_entry(dentries->next, struct dentry_list, list);
		status = f(dir, child->dentry);
		if (status)
			goto out;
		list_del(&child->list);
		dput(child->dentry);
		kfree(child);
	}
out:
	while (!list_empty(dentries)) {
		child = list_entry(dentries->next, struct dentry_list, list);
		list_del(&child->list);
		dput(child->dentry);
		kfree(child);
	}
	nfs4_reset_user(uid, gid);
	return status;
}
Example #24
0
long l_readdir(struct file *file, cfs_list_t *dentry_list)
{
        struct l_linux_dirent *lastdirent;
        struct l_readdir_callback buf;
        int error;

        buf.lrc_dirent = NULL;
        buf.lrc_list = dentry_list;

        error = vfs_readdir(file, l_filldir, &buf);
        if (error < 0)
                return error;

        lastdirent = buf.lrc_dirent;
        if (lastdirent)
                lastdirent->lld_off = file->f_pos;

        return 0;
}
Example #25
0
static int fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                       off_t offset, struct fuse_file_info *fi)
{
    dirent *de;

    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    vfs_seekdir(fi->fh, offset);
    while ((de = vfs_readdir(fi->fh)) != NULL) {
        stat st;
        memset(&st, 0, sizeof(st));
        st.st_ino = de->d_ino;
        st.st_mode = de->d_type << 12;
        if (filler(buf, de->d_name, &st, 0))
            break;
    }

    return 0;
}
Example #26
0
struct vnode *vfs_lookup(struct vnode *parent, char *name)
{
    parent = get_real_node(parent);

    DIR *dh = vfs_opendir(parent);
    struct vnode *node = 0;

    while ((node = vfs_readdir(dh)) != NULL)
    {
        if (!strcmp(node->v_name, name))
        {
            vfs_closedir(dh);
            return node;
        }
    }

    vfs_closedir(dh);
    return NULL;
}
Example #27
0
asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
				   int cnt, u32 u_basep)
{
	void *dirent = (void *) A(u_dirent);
	unsigned int *basep = (unsigned int *)A(u_basep);
	struct file * file;
	struct sunos_direntry * lastdirent;
	int error = -EBADF;
	struct sunos_direntry_callback buf;

	if(fd >= SUNOS_NR_OPEN)
		goto out;

	file = fget(fd);
	if(!file)
		goto out;

	error = -EINVAL;
	if(cnt < (sizeof(struct sunos_direntry) + 255))
		goto out_putf;

	buf.curr = (struct sunos_direntry *) dirent;
	buf.previous = NULL;
	buf.count = cnt;
	buf.error = 0;

	error = vfs_readdir(file, sunos_filldirentry, &buf);
	if (error < 0)
		goto out_putf;

	lastdirent = buf.previous;
	error = buf.error;
	if (lastdirent) {
		put_user(file->f_pos, basep);
		error = cnt - buf.count;
	}

out_putf:
	fput(file);
out:
	return error;
}
Example #28
0
SYSCALL_DEFINE3(getdents64, unsigned int, fd,
		struct linux_dirent64 __user *, dirent, unsigned int, count)
{
	struct file * file;
	struct linux_dirent64 __user * lastdirent;
	struct getdents_callback64 buf;
	int error;

	error = -EFAULT;
	if (!access_ok(VERIFY_WRITE, dirent, count))
		goto out;

	if (scribe_track_next_file_read()) {
		scribe_kill(current->scribe->ctx, -ENOMEM);
		return -ENOMEM;
	}

	error = -EBADF;
	file = fget(fd);
	if (!file)
		goto out;

	buf.current_dir = dirent;
	buf.previous = NULL;
	buf.count = count;
	buf.error = 0;

	error = vfs_readdir(file, filldir64, &buf);
	if (error >= 0)
		error = buf.error;
	lastdirent = buf.previous;
	if (lastdirent) {
		typeof(lastdirent->d_off) d_off = file->f_pos;
		if (__put_user(d_off, &lastdirent->d_off))
			error = -EFAULT;
		else
			error = count - buf.count;
	}
	fput(file);
out:
	return error;
}
Example #29
0
static int sdcardfs_getdents(struct file * file, struct sdcardfs_dirent * dirent) 
{
	/* This function is copy old_readdir */
	int error;
	struct sdcardfs_getdents_callback buf;

	error = -EBADF;

	if (!file)
		goto out;

	buf.result = 0; 
	buf.dirent = dirent; 

	error = vfs_readdir(file, sdcardfs_fillonedir, &buf);
	if (buf.result)
		error = buf.result;
out:
	return error;
}
Example #30
0
SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
		struct old_linux_dirent __user *, dirent, unsigned int, count)
{
	int error;
	struct fd f = fdget(fd);
	struct readdir_callback buf;

	if (!f.file)
		return -EBADF;

	buf.result = 0;
	buf.dirent = dirent;

	error = vfs_readdir(f.file, fillonedir, &buf);
	if (buf.result)
		error = buf.result;

	fdput(f);
	return error;
}