#include <linux/slab.h>
#include <linux/loop.h>
#include <linux/errno.h>
+#include <linux/lustre_idl.h>
#include "smfs_internal.h"
/* Find the options for the clone. These consist of a cache device
and an index in the snaptable associated with that device.
*/
-static char *smfs_options(char *options, char **devstr, char **namestr)
+static char *smfs_options(char *options, char **devstr, char **namestr, int *kml)
{
struct option *opt_value = NULL;
char *pos;
} else if (!strcmp(opt_value->opt, "type")) {
if (namestr != NULL)
*namestr = opt_value->value;
+ } else if (!strcmp(opt_value->opt, "kml")) {
+ *kml = 1;
} else {
break;
}
}
return pos;
}
-static int close_fd(int fd)
-{
- struct files_struct *files = current->files;
-
- write_lock(&files->file_lock);
-
- files->fd[fd] = NULL;
- __put_unused_fd(files, fd);
-
- write_unlock(&files->file_lock);
- return 0;
-}
+
static int set_loop_fd(char *dev_path, char *loop_dev)
{
struct loop_info loopinfo;
if (!fd) RETURN(-EINVAL);
- filp = filp_open(dev_path, 0, 0);
+ filp = filp_open(dev_path, FMODE_WRITE, 0);
if (!filp || !S_ISREG(filp->f_dentry->d_inode->i_mode))
RETURN(-EINVAL);
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
static char *find_unused_and_set_loop_device(char *dev_path)
{
- char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
+ char *loop_formats[] = { "/dev/loop/%d", "/dev/loop%d"};
struct loop_info loopinfo;
struct nameidata nd;
struct dentry *dentry;
if (path_init(dev, LOOKUP_FOLLOW, &nd)) {
error = path_walk(dev, &nd);
- if (error) {
+ if (error && error != -ENOENT) {
path_release(&nd);
SM_FREE(dev, strlen(loop_formats[i]) + 1);
RETURN(NULL);
(unsigned long)&loopinfo);
path_release(&nd);
- if (error == ENXIO) {
+ if (error == -ENXIO) {
/*find unused loop and set dev_path to loopdev*/
error = set_loop_fd(dev_path, dev);
if (error) {
char *name = NULL;
int error = 0;
- if (path_init(name, LOOKUP_FOLLOW, &nd)) {
- error = path_walk(name, &nd);
+ if (path_init(dev_path, LOOKUP_FOLLOW, &nd)) {
+ error = path_walk(dev_path, &nd);
if (error) {
path_release(&nd);
RETURN(NULL);
memcpy(name, dev_path, strlen(dev_path) + 1);
RETURN(name);
}
+void duplicate_sb(struct super_block *csb,
+ struct super_block *sb)
+{
+ sb->s_blocksize = csb->s_blocksize;
+ sb->s_magic = csb->s_magic;
+ sb->s_blocksize_bits = csb->s_blocksize_bits;
+ sb->s_maxbytes = csb->s_maxbytes;
+}
extern struct super_operations smfs_super_ops;
static int sm_mount_cache(struct super_block *sb,
free_page(page);
if (IS_ERR(mnt)) {
- CERROR("do_kern_mount failed: rc = %d\n", err);
- GOTO(err_out, 0);
+ CERROR("do_kern_mount failed: rc = %ld\n", PTR_ERR(mnt));
+ GOTO(err_out, err = PTR_ERR(mnt));
}
smb = S2SMI(sb);
smb->smsi_sb = mnt->mnt_sb;
smb->smsi_mnt = mnt;
+
+ duplicate_sb(mnt->mnt_sb, sb);
sm_set_sb_ops(mnt->mnt_sb, sb);
err_out:
if (dev_name)
struct smfs_super_info *smb = S2SMI(sb);
mntput(smb->smsi_mnt);
+
return 0;
}
void smfs_put_super(struct super_block *sb)
void *data,
int silent)
{
- struct smfs_inode_info *smi;
- struct dentry *bottom_root;
struct inode *root_inode = NULL;
char *devstr = NULL, *typestr = NULL;
char *cache_data;
ino_t root_ino;
- int err = 0;
+ int err = 0, kml = 0;
ENTRY;
init_option(data);
/* read and validate options */
- cache_data = smfs_options(data, &devstr, &typestr);
+ cache_data = smfs_options(data, &devstr, &typestr, &kml);
if (*cache_data) {
CERROR("invalid mount option %s\n", (char*)data);
GOTO(out_err, err=-EINVAL);
CERROR("Can not mount %s as %s\n", devstr, typestr);
GOTO(out_err, 0);
}
- /* set up the super block */
-
- bottom_root = dget(S2SMI(sb)->smsi_sb->s_root);
- if (!bottom_root) {
- CERROR("bottom not mounted\n");
- GOTO(out_err, err=-ENOENT);
- }
-
- root_ino = bottom_root->d_inode->i_ino;
- smi = I2SMI(root_inode);
- /*FIXME Intialize smi here*/
+ if (kml) smfs_kml_init(sb);
+
+ setup_sm_journal_ops(typestr);
+
+ dget(S2CSB(sb)->s_root);
+ root_ino = S2CSB(sb)->s_root->d_inode->i_ino;
+ root_inode = iget(sb, root_ino);
+
CDEBUG(D_SUPER, "readinode %p, root ino %ld, root inode at %p\n",
sb->s_op->read_inode, root_ino, root_inode);
- sb->s_root = d_alloc_root(bottom_root->d_inode);
+ sb->s_root = d_alloc_root(root_inode);
if (!sb->s_root) {
GOTO(out_err, err=-EINVAL);
}
-
+
CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
(ulong) sb, (ulong) &sb->u.generic_sbp);
- out_err:
+out_err:
cleanup_option();
if (err)
return NULL;