struct dt_device_param *param);
/**
+ * Return device's super block.
+ *
+ * \param[in] dev dt device
+ */
+ struct super_block *(*dt_mnt_sb_get)(const struct dt_device *dev);
+
+ /**
* Sync the device.
*
* Sync all the cached state (dirty buffers, pages, etc) to the
return dev->dd_ops->dt_conf_get(env, dev, param);
}
+static inline struct super_block *dt_mnt_sb_get(const struct dt_device *dev)
+{
+ LASSERT(dev);
+ LASSERT(dev->dd_ops);
+ if (dev->dd_ops->dt_mnt_sb_get)
+ return dev->dd_ops->dt_mnt_sb_get(dev);
+
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
static inline int dt_sync(const struct lu_env *env, struct dt_device *dev)
{
LASSERT(dev);
return -EOPNOTSUPP;
}
+static bool is_cmd_supported(unsigned int command)
+{
+ switch (command) {
+ case FITRIM:
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+static long server_ioctl(struct file *filp, unsigned int command,
+ unsigned long arg)
+{
+ struct file active_filp;
+ struct inode *inode = file_inode(filp);
+ struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
+ struct super_block *dd_sb = dt_mnt_sb_get(lsi->lsi_dt_dev);
+ struct inode *active_inode;
+ int err = -EOPNOTSUPP;
+
+ if (IS_ERR(dd_sb) || !is_cmd_supported(command))
+ return err;
+
+ active_inode = igrab(dd_sb->s_root->d_inode);
+ if (!active_inode)
+ return -EACCES;
+
+ active_filp.f_inode = active_inode;
+ if (active_inode->i_fop && active_inode->i_fop->unlocked_ioctl)
+ err = active_inode->i_fop->unlocked_ioctl(&active_filp,
+ command, arg);
+ iput(active_inode);
+ return err;
+}
+
static const struct inode_operations server_inode_operations = {
#ifdef HAVE_IOP_XATTR
.setxattr = lustre_setxattr,
.listxattr = lustre_listxattr,
};
+static const struct file_operations server_file_operations = {
+ .unlocked_ioctl = server_ioctl,
+};
+
#define log2(n) ffz(~(n))
#define LUSTRE_SUPER_MAGIC 0x0BD00BD1
/* apparently we need to be a directory for the mount to finish */
root->i_mode = S_IFDIR;
root->i_op = &server_inode_operations;
+ root->i_fop = &server_file_operations;
sb->s_root = d_make_root(root);
if (!sb->s_root) {
CERROR("%s: can't make root dentry\n", sb->s_id);
}
}
+static struct super_block *osd_mnt_sb_get(const struct dt_device *d)
+{
+ return osd_sb(osd_dt_dev(d));
+}
+
/*
* Concurrency: shouldn't matter.
*/
.dt_trans_stop = osd_trans_stop,
.dt_trans_cb_add = osd_trans_cb_add,
.dt_conf_get = osd_conf_get,
+ .dt_mnt_sb_get = osd_mnt_sb_get,
.dt_sync = osd_sync,
.dt_ro = osd_ro,
.dt_commit_async = osd_commit_async,