From b5db8fc05a77ad3c47ceed4f9afbb67507f2a298 Mon Sep 17 00:00:00 2001 From: wangdi <wangdi> Date: Tue, 3 Feb 2004 16:39:38 +0000 Subject: [PATCH] update smfs. 1)fix bugs in sm_read_super 2) add some methods in symlink ops --- lustre/smfs/super.c | 183 +++++++++++++++++++++++++++--------------- lustre/smfs/symlink.c | 27 ++++++- 2 files changed, 145 insertions(+), 65 deletions(-) diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c index 2cb0346758..8e8cdd95ac 100644 --- a/lustre/smfs/super.c +++ b/lustre/smfs/super.c @@ -45,21 +45,6 @@ static char *smfs_options(char *options, char **devstr, char **namestr) } 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) { struct files_struct *files = current->files; @@ -72,65 +57,137 @@ static int close_fd(int fd) write_unlock(&files->file_lock); return 0; } - -#define MAX_LOOP_DEVICES 256 -static char *parse_path2dev(struct super_block *sb, char *dev_path) +static int set_loop_fd(char *dev_path, char *loop_dev) { + struct loop_info loopinfo; + struct nameidata nd; + struct dentry *dentry; + struct block_device_operations *bd_ops; struct file *filp; - int i = 0, fd = 0, error = 0; - char *name = NULL; - + int fd = 0, error = 0; + + fd = get_unused_fd(); + + if (!fd) RETURN(-EINVAL); + filp = filp_open(dev_path, 0, 0); - if (!filp) - RETURN(NULL); - if (S_ISREG(filp->f_dentry->d_inode->i_mode)) { - /*here we must walk through all the snap cache to - *find the loop device */ - - fd = get_unused_fd(); - if (!fd) RETURN(NULL); + if (!filp || !S_ISREG(filp->f_dentry->d_inode->i_mode)) + RETURN(-EINVAL); + + fd_install(fd, filp); - fd_install(fd, filp); - SM_ALLOC(name, strlen("/dev/loop/") + 2); + if (path_init(loop_dev, LOOKUP_FOLLOW, &nd)) { + 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++) { - fd = get_fd(filp); - if (fd > 0) { - struct block_device_operations *bd_ops; - struct dentry *dentry; - struct nameidata nd; - /*FIXME later, the loop file should - *be different for different system*/ - - sprintf(name, "/dev/loop/%d", i); - - if (path_init(name, LOOKUP_FOLLOW, &nd)) { - error = path_walk(name, &nd); - if (error) { - path_release(&nd); - SM_FREE(name, sizeof(name) + 1); - RETURN(NULL); - } - } else { - SM_FREE(name, sizeof(name) + 1); - RETURN(NULL); - } - dentry = nd.dentry; - bd_ops = get_blkfops(LOOP_MAJOR); - error = bd_ops->ioctl(dentry->d_inode, - filp, LOOP_SET_FD, - (unsigned long)fd); - path_release(&nd); - if (!error) { - filp_close(filp, current->files); - RETURN(name); + error = bd_ops->ioctl(dentry->d_inode, filp, LOOP_SET_FD, + (unsigned long)fd); + if (error) { + path_release(&nd); + filp_close(filp, current->files); + RETURN(-EINVAL); + } + memset(&loopinfo, 0, sizeof(struct loop_info)); + + error = bd_ops->ioctl(dentry->d_inode, filp, LOOP_SET_STATUS, + (unsigned long)(&loopinfo)); + path_release(&nd); + RETURN(error); +} + +#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" }; + struct loop_info loopinfo; + struct nameidata nd; + struct dentry *dentry; + char *dev = NULL; + int i, j, error; + + for (j = 0; j < SIZE(loop_formats); j++) { + SM_ALLOC(dev, strlen(loop_formats[i]) + 1); + for(i = 0; i < 256; i++) { + struct block_device_operations *bd_ops; + + 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); memcpy(name, dev_path, strlen(dev_path) + 1); - filp_close(filp, current->files); RETURN(name); } extern struct super_operations smfs_super_ops; diff --git a/lustre/smfs/symlink.c b/lustre/smfs/symlink.c index 4174846185..72c68f4a68 100644 --- a/lustre/smfs/symlink.c +++ b/lustre/smfs/symlink.c @@ -1,7 +1,6 @@ /* - * fs/snap/snap.c + * smfs/symlink.c * - * A snap shot file system. * */ #define DEBUG_SUBSYSTEM S_SNAP @@ -14,7 +13,31 @@ #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 = { + readlink: smfs_readlink, + follow_link: smfs_follow_link, }; struct file_operations smfs_sym_fops = { -- GitLab