Skip to content
Snippets Groups Projects
Commit b5db8fc0 authored by Wang Di's avatar Wang Di
Browse files

update smfs. 1)fix bugs in sm_read_super 2) add some methods in symlink ops

parent cf339296
No related branches found
No related tags found
No related merge requests found
...@@ -45,21 +45,6 @@ static char *smfs_options(char *options, char **devstr, char **namestr) ...@@ -45,21 +45,6 @@ static char *smfs_options(char *options, char **devstr, char **namestr)
} }
return pos; return pos;
} }
static int get_fd(struct file *filp)
{
struct files_struct *files = current->files;
int fd = 0;
write_lock(&files->file_lock);
for (fd = 0; fd < files->max_fds; fd++) {
if(files->fd[fd] == filp) {
write_unlock(&files->file_lock);
return fd;
}
}
write_unlock(&files->file_lock);
RETURN(-1);
}
static int close_fd(int fd) static int close_fd(int fd)
{ {
struct files_struct *files = current->files; struct files_struct *files = current->files;
...@@ -72,65 +57,137 @@ static int close_fd(int fd) ...@@ -72,65 +57,137 @@ static int close_fd(int fd)
write_unlock(&files->file_lock); write_unlock(&files->file_lock);
return 0; return 0;
} }
static int set_loop_fd(char *dev_path, char *loop_dev)
#define MAX_LOOP_DEVICES 256
static char *parse_path2dev(struct super_block *sb, char *dev_path)
{ {
struct loop_info loopinfo;
struct nameidata nd;
struct dentry *dentry;
struct block_device_operations *bd_ops;
struct file *filp; struct file *filp;
int i = 0, fd = 0, error = 0; int fd = 0, error = 0;
char *name = NULL;
fd = get_unused_fd();
if (!fd) RETURN(-EINVAL);
filp = filp_open(dev_path, 0, 0); filp = filp_open(dev_path, 0, 0);
if (!filp) if (!filp || !S_ISREG(filp->f_dentry->d_inode->i_mode))
RETURN(NULL); RETURN(-EINVAL);
if (S_ISREG(filp->f_dentry->d_inode->i_mode)) {
/*here we must walk through all the snap cache to fd_install(fd, filp);
*find the loop device */
fd = get_unused_fd();
if (!fd) RETURN(NULL);
fd_install(fd, filp); if (path_init(loop_dev, LOOKUP_FOLLOW, &nd)) {
SM_ALLOC(name, strlen("/dev/loop/") + 2); error = path_walk(loop_dev, &nd);
if (error) {
path_release(&nd);
filp_close(filp, current->files);
RETURN(-EINVAL);
}
} else {
path_release(&nd);
filp_close(filp, current->files);
RETURN(-EINVAL);
}
dentry = nd.dentry;
bd_ops = get_blkfops(LOOP_MAJOR);
for (i = 0; i < MAX_LOOP_DEVICES; i++) { error = bd_ops->ioctl(dentry->d_inode, filp, LOOP_SET_FD,
fd = get_fd(filp); (unsigned long)fd);
if (fd > 0) { if (error) {
struct block_device_operations *bd_ops; path_release(&nd);
struct dentry *dentry; filp_close(filp, current->files);
struct nameidata nd; RETURN(-EINVAL);
/*FIXME later, the loop file should }
*be different for different system*/ memset(&loopinfo, 0, sizeof(struct loop_info));
sprintf(name, "/dev/loop/%d", i); error = bd_ops->ioctl(dentry->d_inode, filp, LOOP_SET_STATUS,
(unsigned long)(&loopinfo));
if (path_init(name, LOOKUP_FOLLOW, &nd)) { path_release(&nd);
error = path_walk(name, &nd); RETURN(error);
if (error) { }
path_release(&nd);
SM_FREE(name, sizeof(name) + 1); #define SIZE(a) (sizeof(a)/sizeof(a[0]))
RETURN(NULL); static char *find_unused_and_set_loop_device(char *dev_path)
} {
} else { char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
SM_FREE(name, sizeof(name) + 1); struct loop_info loopinfo;
RETURN(NULL); struct nameidata nd;
} struct dentry *dentry;
dentry = nd.dentry; char *dev = NULL;
bd_ops = get_blkfops(LOOP_MAJOR); int i, j, error;
error = bd_ops->ioctl(dentry->d_inode,
filp, LOOP_SET_FD, for (j = 0; j < SIZE(loop_formats); j++) {
(unsigned long)fd); SM_ALLOC(dev, strlen(loop_formats[i]) + 1);
path_release(&nd); for(i = 0; i < 256; i++) {
if (!error) { struct block_device_operations *bd_ops;
filp_close(filp, current->files);
RETURN(name); sprintf(dev, loop_formats[j], i);
if (path_init(dev, LOOKUP_FOLLOW, &nd)) {
error = path_walk(dev, &nd);
if (error) {
path_release(&nd);
SM_FREE(dev, strlen(loop_formats[i]) + 1);
RETURN(NULL);
}
} else {
SM_FREE(dev, strlen(loop_formats[i]) + 1);
RETURN(NULL);
}
dentry = nd.dentry;
bd_ops = get_blkfops(LOOP_MAJOR);
error = bd_ops->ioctl(dentry->d_inode, NULL, LOOP_GET_STATUS,
(unsigned long)&loopinfo);
path_release(&nd);
if (error == ENXIO) {
/*find unused loop and set dev_path to loopdev*/
error = set_loop_fd(dev_path, dev);
if (error) {
SM_FREE(dev, strlen(loop_formats[i]) + 1);
dev = NULL;
} }
return dev;/* probably free */
} }
}
SM_FREE(dev, strlen(loop_formats[i]) + 1);
}
RETURN(NULL);
}
#define MAX_LOOP_DEVICES 256
static char *parse_path2dev(struct super_block *sb, char *dev_path)
{
struct dentry *dentry;
struct nameidata nd;
char *name = NULL;
int error = 0;
if (path_init(name, LOOKUP_FOLLOW, &nd)) {
error = path_walk(name, &nd);
if (error) {
path_release(&nd);
RETURN(NULL);
} }
} else {
RETURN(NULL);
}
dentry = nd.dentry;
if (!dentry->d_inode || is_bad_inode(dentry->d_inode) ||
(!S_ISBLK(dentry->d_inode->i_mode) &&
!S_ISREG(dentry->d_inode->i_mode))){
path_release(&nd);
RETURN(NULL);
}
if (S_ISREG(dentry->d_inode->i_mode)) {
name = find_unused_and_set_loop_device(dev_path);
path_release(&nd);
RETURN(name);
} }
SM_ALLOC(name, strlen(dev_path) + 1); SM_ALLOC(name, strlen(dev_path) + 1);
memcpy(name, dev_path, strlen(dev_path) + 1); memcpy(name, dev_path, strlen(dev_path) + 1);
filp_close(filp, current->files);
RETURN(name); RETURN(name);
} }
extern struct super_operations smfs_super_ops; extern struct super_operations smfs_super_ops;
......
/* /*
* fs/snap/snap.c * smfs/symlink.c
* *
* A snap shot file system.
* *
*/ */
#define DEBUG_SUBSYSTEM S_SNAP #define DEBUG_SUBSYSTEM S_SNAP
...@@ -14,7 +13,31 @@ ...@@ -14,7 +13,31 @@
#include "smfs_internal.h" #include "smfs_internal.h"
static int smfs_readlink(struct dentry * dentry, char * buffer, int buflen)
{
struct inode *cache_inode = I2CI(dentry->d_inode);
int rc = 0;
if (cache_inode->i_op && cache_inode->i_op->readlink)
rc = cache_inode->i_op->readlink(dentry, buffer, buflen);
return rc;
}
static int smfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *cache_inode = I2CI(dentry->d_inode);
int rc = 0;
if (cache_inode->i_op && cache_inode->i_op->follow_link)
rc = cache_inode->i_op->follow_link(dentry, nd);
return rc;
}
struct inode_operations smfs_sym_iops = { struct inode_operations smfs_sym_iops = {
readlink: smfs_readlink,
follow_link: smfs_follow_link,
}; };
struct file_operations smfs_sym_fops = { struct file_operations smfs_sym_fops = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment