This is part [4/7] of the v9fs-2.0.2 patch against Linux 2.6.13-rc2-mm2.
This part of the patch contains VFS superblock and mapping code changes
related to hch's comments.
Signed-off-by: Eric Van Hensbergen <[email protected]>
----------
v9fs.c | 103 +++++++++++++++++++++++++++++++++---------------------------
v9fs.h | 27 +++++++++++----
vfs_super.c | 45 +++++++++++++++++++++++---
3 files changed, 119 insertions(+), 56 deletions(-)
----------
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -22,6 +22,16 @@
*
*/
+/*
+ * Idpool structure provides lock and id management
+ *
+ */
+
+struct v9fs_idpool {
+ struct semaphore lock;
+ struct idr pool;
+};
+
/*
* Session structure provides information for an opened session
*
@@ -36,7 +46,6 @@ struct v9fs_session_info {
unsigned short debug; /* debug level */
unsigned short proto; /* protocol to use */
unsigned int afid; /* authentication fid */
- unsigned int timeout; /* transport timeout in msec */
char *name; /* user name to mount as */
char *remotename; /* name of remote hierarchy being mounted */
@@ -44,8 +53,8 @@ struct v9fs_session_info {
unsigned int gid; /* default gid for legacy support */
/* book keeping */
- struct idpool fidpool; /* The FID pool for file descriptors */
- struct idpool tidpool; /* The TID pool for transactions ids */
+ struct v9fs_idpool fidpool; /* The FID pool for file descriptors */
+ struct v9fs_idpool tidpool; /* The TID pool for transactions ids */
/* transport information */
struct v9fs_transport *transport;
@@ -65,10 +74,17 @@ struct v9fs_session_info {
struct list_head mux_fcalls;
};
+/* possible values of ->proto */
+enum {
+ PROTO_TCP,
+ PROTO_UNIX,
+};
+
int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
struct v9fs_session_info *v9fs_inode2v9ses(struct inode *);
void v9fs_session_close(struct v9fs_session_info *v9ses);
-
+int v9fs_get_idpool(struct v9fs_idpool *p);
+void v9fs_put_idpool(int id, struct v9fs_idpool *p);
int v9fs_get_option(char *opts, char *name, char *buf, int buflen);
long long v9fs_get_int_option(char *opts, char *name, long long dflt);
int v9fs_parse_tcp_devname(const char *devname, char **addr, char **remotename);
@@ -79,10 +95,7 @@ int v9fs_parse_tcp_devname(const char *d
#define V9FS_PORT 564
#define V9FS_DEFUSER "nobody"
#define V9FS_DEFANAME ""
-#define V9FS_TIMEOUT 60000
/* inital pool sizes for fids and tags */
#define V9FS_START_FIDS 8192
#define V9FS_START_TIDS 256
-
-#define safe_cache_free(x, y) { if(y) kmem_cache_free(x, y); }
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -29,9 +29,9 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/parser.h>
+#include <linux/idr.h>
#include "debug.h"
-#include "idpool.h"
#include "v9fs.h"
#include "9p.h"
#include "v9fs_vfs.h"
@@ -48,13 +48,8 @@ int v9fs_debug_level = 0; /* feature-rif
*/
enum {
- PROTO_TCP,
- PROTO_UNIX,
-};
-
-enum {
/* Options that take integer arguments */
- Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug, Opt_timeo,
+ Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug,
/* String options */
Opt_name, Opt_remotename,
/* Options that take no arguments */
@@ -64,7 +59,6 @@ enum {
};
static match_table_t tokens = {
- {Opt_timeo, "timeout=%u"},
{Opt_port, "port=%u"},
{Opt_msize, "msize=%u"},
{Opt_uid, "uid=%u"},
@@ -107,7 +101,6 @@ static void v9fs_parse_options(char *opt
v9ses->extended = 1;
v9ses->afid = ~0;
v9ses->debug = 0;
- v9ses->timeout = V9FS_TIMEOUT;
if (!options)
return;
@@ -126,9 +119,6 @@ static void v9fs_parse_options(char *opt
}
switch (token) {
- case Opt_timeo:
- v9ses->timeout = option;
- break;
case Opt_port:
v9ses->port = option;
break;
@@ -169,20 +159,6 @@ static void v9fs_parse_options(char *opt
continue;
}
}
-
- dprintk(DEBUG_9P, "options=\n");
- dprintk(DEBUG_9P, " debug: %x\n", v9ses->debug);
- dprintk(DEBUG_9P, " port: %u\n", v9ses->port);
- dprintk(DEBUG_9P, " msize: %u\n", v9ses->maxdata);
- dprintk(DEBUG_9P, " uid: %u\n", v9ses->uid);
- dprintk(DEBUG_9P, " gid: %u\n", v9ses->gid);
- dprintk(DEBUG_9P, " afid: %d\n", v9ses->afid);
- dprintk(DEBUG_9P, " proto: %u\n", v9ses->proto);
- dprintk(DEBUG_9P, " extended: %u\n", v9ses->extended);
- dprintk(DEBUG_9P, " nomapdev: %u\n", v9ses->nodev);
- dprintk(DEBUG_9P, " timeout: %u\n", v9ses->timeout);
- dprintk(DEBUG_9P, " name: %s\n", v9ses->name);
- dprintk(DEBUG_9P, " remotename: %s\n", v9ses->remotename);
}
/**
@@ -196,21 +172,58 @@ static void v9fs_parse_options(char *opt
struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
{
- if (inode) {
- if (inode->i_sb) {
- if (inode->i_sb->s_fs_info)
- return (inode->i_sb->s_fs_info);
- else {
- dprintk(DEBUG_ERROR, "no s_fs_info\n");
- return NULL;
- }
- } else {
- dprintk(DEBUG_ERROR, "no superblock\n");
- return NULL;
- }
+ return (inode->i_sb->s_fs_info);
+}
+
+/**
+ * v9fs_get_idpool - allocate numeric id from pool
+ * @p - pool to allocate from
+ *
+ * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * the lock included in struct idr?
+ */
+
+int v9fs_get_idpool(struct v9fs_idpool *p)
+{
+ int i = 0;
+ int error;
+
+retry:
+ if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
+ return 0;
+
+ if (down_interruptible(&p->lock) == -EINTR) {
+ eprintk(KERN_WARNING, "Interrupted while locking\n");
+ return -1;
}
- dprintk(DEBUG_ERROR, "no inode\n");
- return NULL;
+
+ error = idr_get_new(&p->pool, NULL, &i);
+ up(&p->lock);
+
+ if (error == -EAGAIN)
+ goto retry;
+ else if (error)
+ return -1;
+
+ return i;
+}
+
+/**
+ * v9fs_put_idpool - release numeric id from pool
+ * @p - pool to allocate from
+ *
+ * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * the lock included in struct idr?
+ */
+
+void v9fs_put_idpool(int id, struct v9fs_idpool *p)
+{
+ if (down_interruptible(&p->lock) == -EINTR) {
+ eprintk(KERN_WARNING, "Interrupted while locking\n");
+ return;
+ }
+ idr_remove(&p->pool, id);
+ up(&p->lock);
}
/**
@@ -250,8 +263,11 @@ v9fs_session_init(struct v9fs_session_in
v9fs_debug_level = v9ses->debug;
/* id pools that are session-dependent: FIDs and TIDs */
- v9fs_alloc_idpool(&v9ses->fidpool, V9FS_START_FIDS);
- v9fs_alloc_idpool(&v9ses->tidpool, V9FS_START_TIDS);
+ idr_init(&v9ses->fidpool.pool);
+ init_MUTEX(&v9ses->fidpool.lock);
+ idr_init(&v9ses->tidpool.pool);
+ init_MUTEX(&v9ses->tidpool.lock);
+
switch (v9ses->proto) {
case PROTO_TCP:
@@ -371,9 +387,6 @@ void v9fs_session_close(struct v9fs_sess
putname(v9ses->name);
putname(v9ses->remotename);
-
- v9fs_free_idpool(&v9ses->fidpool);
- v9fs_free_idpool(&v9ses->tidpool);
}
extern int v9fs_error_init(void);
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -35,9 +35,11 @@
#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
+#include <linux/idr.h>
#include "debug.h"
-#include "idpool.h"
#include "v9fs.h"
#include "9p.h"
#include "v9fs_vfs.h"
@@ -184,7 +186,7 @@ static struct super_block *v9fs_get_sb(s
root_fid = v9fs_fid_create(root);
if (root_fid == NULL) {
retval = -ENOMEM;
- goto release_inode;
+ goto release_dentry;
}
root_fid->fidopen = 0;
@@ -207,18 +209,20 @@ static struct super_block *v9fs_get_sb(s
if (stat_result < 0) {
retval = stat_result;
- goto release_inode;
+ goto release_dentry;
}
return sb;
+ release_dentry:
+ dput(sb->s_root);
+
release_inode:
iput(inode);
put_back_sb:
up_write(&sb->s_umount);
deactivate_super(sb);
-
v9fs_session_close(v9ses);
free_session:
@@ -248,9 +252,42 @@ static void v9fs_kill_super(struct super
dprintk(DEBUG_VFS, "exiting kill_super\n");
}
+/**
+ * v9fs_show_options - Show mount options in /proc/mounts
+ * @m: seq_file to write to
+ * @mnt: mount descriptor
+ *
+ */
+
+static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+ struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info;
+
+ if (v9ses->debug != 0)
+ seq_printf(m, ",debug=%u", v9ses->debug);
+ if (v9ses->port != V9FS_PORT)
+ seq_printf(m, ",port=%u", v9ses->port);
+ if (v9ses->maxdata != 9000)
+ seq_printf(m, ",msize=%u", v9ses->maxdata);
+ if (v9ses->afid != ~0)
+ seq_printf(m, ",afid=%u", v9ses->afid);
+ if (v9ses->proto == PROTO_UNIX)
+ seq_puts(m, ",proto=unix");
+ if (v9ses->extended == 0)
+ seq_puts(m, ",noextend");
+ if (v9ses->nodev == 1)
+ seq_puts(m, ",nodevmap");
+ seq_printf(m, ",name=%s", v9ses->name);
+ seq_printf(m, ",aname=%s", v9ses->remotename);
+ seq_printf(m, ",uid=%u", v9ses->uid);
+ seq_printf(m, ",gid=%u", v9ses->gid);
+ return 0;
+}
+
static struct super_operations v9fs_super_ops = {
.statfs = simple_statfs,
.clear_inode = v9fs_clear_inode,
+ .show_options = v9fs_show_options,
};
struct file_system_type v9fs_fs_type = {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
|
|