123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- --- a/fs/yaffs2/yaffs_vfs.c
- +++ b/fs/yaffs2/yaffs_vfs.c
- @@ -1701,6 +1701,110 @@ static void yaffs_remove_obj_callback(st
-
- /*-----------------------------------------------------------------*/
-
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
- +static int yaffs_readdir(struct file *file, struct dir_context *ctx)
- +{
- + struct yaffs_obj *obj;
- + struct yaffs_dev *dev;
- + struct yaffs_search_context *sc;
- + struct inode *inode = file->f_dentry->d_inode;
- + unsigned long offset, curoffs;
- + struct yaffs_obj *l;
- + int ret_val = 0;
- +
- + char name[YAFFS_MAX_NAME_LENGTH + 1];
- +
- + obj = yaffs_dentry_to_obj(file->f_dentry);
- + dev = obj->my_dev;
- +
- + yaffs_gross_lock(dev);
- +
- + yaffs_dev_to_lc(dev)->readdir_process = current;
- +
- + offset = ctx->pos;
- +
- + sc = yaffs_new_search(obj);
- + if (!sc) {
- + ret_val = -ENOMEM;
- + goto out;
- + }
- +
- + yaffs_trace(YAFFS_TRACE_OS,
- + "yaffs_readdir: starting at %d", (int)offset);
- +
- + if (offset == 0) {
- + yaffs_trace(YAFFS_TRACE_OS,
- + "yaffs_readdir: entry . ino %d",
- + (int)inode->i_ino);
- + yaffs_gross_unlock(dev);
- + if (!dir_emit_dot(file, ctx)) {
- + yaffs_gross_lock(dev);
- + goto out;
- + }
- + yaffs_gross_lock(dev);
- + offset++;
- + ctx->pos++;
- + }
- + if (offset == 1) {
- + yaffs_trace(YAFFS_TRACE_OS,
- + "yaffs_readdir: entry .. ino %d",
- + (int)file->f_dentry->d_parent->d_inode->i_ino);
- + yaffs_gross_unlock(dev);
- + if (!dir_emit_dotdot(file, ctx)) {
- + yaffs_gross_lock(dev);
- + goto out;
- + }
- + yaffs_gross_lock(dev);
- + offset++;
- + ctx->pos++;
- + }
- +
- + curoffs = 1;
- +
- + /* If the directory has changed since the open or last call to
- + readdir, rewind to after the 2 canned entries. */
- + if (file->f_version != inode->i_version) {
- + offset = 2;
- + ctx->pos = offset;
- + file->f_version = inode->i_version;
- + }
- +
- + while (sc->next_return) {
- + curoffs++;
- + l = sc->next_return;
- + if (curoffs >= offset) {
- + int this_inode = yaffs_get_obj_inode(l);
- + int this_type = yaffs_get_obj_type(l);
- +
- + yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
- + yaffs_trace(YAFFS_TRACE_OS,
- + "yaffs_readdir: %s inode %d",
- + name, yaffs_get_obj_inode(l));
- +
- + yaffs_gross_unlock(dev);
- +
- + if (!dir_emit(ctx, name, strlen(name),
- + this_inode, this_type) < 0) {
- + yaffs_gross_lock(dev);
- + goto out;
- + }
- +
- + yaffs_gross_lock(dev);
- +
- + offset++;
- + ctx->pos++;
- + }
- + yaffs_search_advance(sc);
- + }
- +
- +out:
- + yaffs_search_end(sc);
- + yaffs_dev_to_lc(dev)->readdir_process = NULL;
- + yaffs_gross_unlock(dev);
- +
- + return ret_val;
- +}
- +#else
- static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
- {
- struct yaffs_obj *obj;
- @@ -1807,10 +1911,15 @@ out:
-
- return ret_val;
- }
- +#endif
-
- static const struct file_operations yaffs_dir_operations = {
- .read = generic_read_dir,
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
- + .iterate = yaffs_readdir,
- +#else
- .readdir = yaffs_readdir,
- +#endif
- .fsync = yaffs_sync_object,
- .llseek = generic_file_llseek,
- };
|