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; }
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; }
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); }
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; }
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; }
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"); }
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; }
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; }
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; }
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; }
/** * 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; }
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); } }
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; }
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; }
/** * 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; }
/** * 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; }
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; }
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; }
/** * 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }