]) # LC_HAVE_LIBAIO
#
+# LC_FOP_READDIR
+#
+# Kernel v3.10+ lost readdir
+#
+AC_DEFUN([LC_SRC_FOP_READDIR], [
+ LB2_LINUX_TEST_SRC([fop_readdir], [
+ #include <linux/fs.h>
+ ],[
+ struct file_operations fop;
+ fop.readdir = NULL;
+ ])
+])
+AC_DEFUN([LC_FOP_READDIR], [
+ LB2_MSG_LINUX_TEST_RESULT([if 'file_operations' has 'readdir'],
+ [fop_readdir], [
+ AC_DEFINE(HAVE_FOP_READDIR, 1,
+ [file_operations has readdir])
+ ])
+]) # LC_FOP_READDIR
+
+#
# LC_INVALIDATE_RANGE
#
# 3.11 invalidatepage requires the length of the range to invalidate
LC_SRC_D_COMPARE_5ARGS
LC_SRC_HAVE_DCOUNT
LC_SRC_PID_NS_FOR_CHILDREN
+ LC_SRC_FOP_READDIR
# 3.12
LC_SRC_OLDSIZE_TRUNCATE_PAGECACHE
LC_HAVE_DENTRY_D_U_D_ALIAS_HLIST
LC_HAVE_DENTRY_D_CHILD
LC_PID_NS_FOR_CHILDREN
+ LC_FOP_READDIR
# 3.12
LC_OLDSIZE_TRUNCATE_PAGECACHE
struct osd_thread_info *info = osd_oti_get(env);
struct osd_it_ea *oie;
struct file *file;
+ struct dentry *obj_dentry;
ENTRY;
- file = osd_alloc_file_pseudo(inode, dev->od_mnt, "/", O_NOATIME,
- inode->i_fop);
- if (IS_ERR(file))
- RETURN(ERR_CAST(file));
-
- /* Only FMODE_64BITHASH or FMODE_32BITHASH should be set, NOT both. */
- if (attr & LUDA_64BITHASH)
- file->f_mode |= FMODE_64BITHASH;
- else
- file->f_mode |= FMODE_32BITHASH;
- ihold(inode);
-
- OBD_SLAB_ALLOC_PTR(oie, osd_itea_cachep);
- if (!oie)
- goto out_fput;
-
- oie->oie_rd_dirent = 0;
- oie->oie_it_dirent = 0;
- oie->oie_dirent = NULL;
+ OBD_SLAB_ALLOC_PTR_GFP(oie, osd_itea_cachep, GFP_NOFS);
+ if (oie == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
+ obj_dentry = &oie->oie_dentry;
+ obj_dentry->d_inode = inode;
+ obj_dentry->d_sb = inode->i_sb;
+ obj_dentry->d_name.hash = 0;
+
+ oie->oie_rd_dirent = 0;
+ oie->oie_it_dirent = 0;
+ oie->oie_dirent = NULL;
if (unlikely(!info->oti_it_ea_buf_used)) {
oie->oie_buf = info->oti_it_ea_buf;
info->oti_it_ea_buf_used = 1;
goto out_free;
}
oie->oie_obj = NULL;
- oie->oie_file = file;
+ file = &oie->oie_file;
+ /* Only FMODE_64BITHASH or FMODE_32BITHASH should be set, NOT both. */
+ if (attr & LUDA_64BITHASH)
+ file->f_mode |= FMODE_64BITHASH;
+ else
+ file->f_mode |= FMODE_32BITHASH;
+ file->f_path.dentry = obj_dentry;
+ file->f_flags = O_NOATIME | __FMODE_NONOTIFY;
+ file->f_mapping = inode->i_mapping;
+ file->f_op = inode->i_fop;
+ file->f_inode = inode;
RETURN(oie);
out_free:
OBD_SLAB_FREE_PTR(oie, osd_itea_cachep);
-out_fput:
- fput(file);
return ERR_PTR(-ENOMEM);
}
struct osd_thread_info *info = osd_oti_get(env);
ENTRY;
- fput(oie->oie_file);
+ oie->oie_file.f_op->release(inode, &oie->oie_file);
if (unlikely(oie->oie_buf != info->oti_it_ea_buf))
OBD_FREE(oie->oie_buf, OSD_IT_EA_BUFSIZE);
else
info->oti_it_ea_buf_used = 0;
+
OBD_SLAB_FREE_PTR(oie, osd_itea_cachep);
EXIT;
}
ENTRY;
LASSERT(((const char *)key)[0] == '\0');
- it->oie_file->f_pos = 0;
+ it->oie_file.f_pos = 0;
it->oie_rd_dirent = 0;
it->oie_it_dirent = 0;
it->oie_dirent = NULL;
struct osd_it_ea *it = (struct osd_it_ea *)di;
struct osd_object *obj = it->oie_obj;
struct htree_lock *hlock = NULL;
- struct file *filp = it->oie_file;
+ struct file *filp = &it->oie_file;
+ struct inode *ino = file_inode(filp);
int rc = 0;
struct osd_filldir_cbs buf = {
.ctx.actor = osd_ldiskfs_filldir,
}
}
- rc = iterate_dir(filp, &buf.ctx);
+#ifdef HAVE_FOP_ITERATE_SHARED
+ inode_lock_shared(ino);
+#else
+ inode_lock(ino);
+#endif
+ if (!IS_DEADDIR(ino)) {
+ if (filp->f_op->iterate_shared) {
+ buf.ctx.pos = filp->f_pos;
+ rc = filp->f_op->iterate_shared(filp, &buf.ctx);
+ filp->f_pos = buf.ctx.pos;
+ } else {
+#ifdef HAVE_FOP_READDIR
+ rc = filp->f_op->readdir(filp, &buf.ctx, buf.ctx.actor);
+ buf.ctx.pos = filp->f_pos;
+#else
+ rc = -ENOTDIR;
+#endif
+ }
+ }
+#ifdef HAVE_FOP_ITERATE_SHARED
+ inode_unlock_shared(ino);
+#else
+ inode_unlock(ino);
+#endif
if (rc)
GOTO(unlock, rc);
* If it does not get any dirent, it means it has been reached
* to the end of the dir
*/
- it->oie_file->f_pos = ldiskfs_get_htree_eof(it->oie_file);
+ it->oie_file.f_pos = ldiskfs_get_htree_eof(&it->oie_file);
if (rc == 0)
rc = 1;
} else {
it->oie_it_dirent++;
rc = 0;
} else {
- if (it->oie_file->f_pos == ldiskfs_get_htree_eof(it->oie_file))
+ if (it->oie_file.f_pos == ldiskfs_get_htree_eof(&it->oie_file))
rc = 1;
else
rc = osd_ldiskfs_it_fill(env, di);
int rc;
ENTRY;
- it->oie_file->f_pos = hash;
+ it->oie_file.f_pos = hash;
rc = osd_ldiskfs_it_fill(env, di);
if (rc > 0)