afs/fs/afs proc.c,1.5,1.6 main.c,1.15,1.16 cell.h,1.7,1.8
cell.c,1.16,1.17
dwh at infradead.org
dwh at infradead.org
Mon Jan 19 10:04:51 GMT 2004
Update of /home/cvs/afs/fs/afs
In directory phoenix.infradead.org:/tmp/cvs-serv28491/fs/afs
Modified Files:
proc.c main.c cell.h cell.c
Log Message:
handle rootcell being set later if AFS fs compiled into kernel
Index: proc.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/proc.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- proc.c 10 Sep 2003 13:32:37 -0000 1.5
+++ proc.c 19 Jan 2004 10:04:48 -0000 1.6
@@ -45,6 +45,21 @@
.release = seq_release,
};
+static int afs_proc_rootcell_open(struct inode *inode, struct file *file);
+static int afs_proc_rootcell_release(struct inode *inode, struct file *file);
+static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
+ size_t size, loff_t *_pos);
+static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
+ size_t size, loff_t *_pos);
+
+static struct file_operations afs_proc_rootcell_fops = {
+ .open = afs_proc_rootcell_open,
+ .read = afs_proc_rootcell_read,
+ .write = afs_proc_rootcell_write,
+ .llseek = no_llseek,
+ .release = afs_proc_rootcell_release
+};
+
static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file);
static int afs_proc_cell_volumes_release(struct inode *inode,
struct file *file);
@@ -136,9 +151,17 @@
p->proc_fops = &afs_proc_cells_fops;
p->owner = THIS_MODULE;
+ p = create_proc_entry("rootcell", 0, proc_afs);
+ if (!p)
+ goto error_cells;
+ p->proc_fops = &afs_proc_rootcell_fops;
+ p->owner = THIS_MODULE;
+
_leave(" = 0");
return 0;
+ error_cells:
+ remove_proc_entry("cells", proc_afs);
error_proc:
remove_proc_entry("fs/afs", NULL);
error:
@@ -253,7 +276,7 @@
/*****************************************************************************/
/*
* handle writes to /proc/fs/afs/cells
- * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]*
+ * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]"
*/
static ssize_t afs_proc_cells_write(struct file *file, const char *buf,
size_t size, loff_t *_pos)
@@ -325,6 +348,70 @@
printk("kAFS: Invalid Command on /proc/fs/afs/cells file\n");
goto done;
} /* end afs_proc_cells_write() */
+
+/*****************************************************************************/
+/*
+ * Stubs for /proc/fs/afs/rootcell
+ */
+static int afs_proc_rootcell_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int afs_proc_rootcell_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
+ size_t size, loff_t *_pos)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+/*
+ * handle writes to /proc/fs/afs/rootcell
+ * - to initialize rootcell: echo "cell.name:192.168.231.14"
+ */
+static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
+ size_t size, loff_t *_pos)
+{
+ char *kbuf, *s;
+ int ret;
+
+ /* start by dragging the command into memory */
+ if (size <= 1 || size >= PAGE_SIZE)
+ return -EINVAL;
+
+ ret = -ENOMEM;
+ kbuf = kmalloc(size + 1, GFP_KERNEL);
+ if (!kbuf)
+ goto nomem;
+
+ ret = -EFAULT;
+ if (copy_from_user(kbuf, buf, size) != 0)
+ goto infault;
+ kbuf[size] = 0;
+
+ /* trim to first NL */
+ s = memchr(kbuf, '\n', size);
+ if (s)
+ *s = 0;
+
+ /* determine command to perform */
+ _debug("rootcell=%s", kbuf);
+
+ ret = afs_cell_init(kbuf);
+ if (ret >= 0)
+ ret = size; /* consume everything, always */
+
+ infault:
+ kfree(kbuf);
+ nomem:
+ _leave(" = %d", ret);
+ return ret;
+} /* end afs_proc_rootcell_write() */
/*****************************************************************************/
/*
Index: main.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/main.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- main.c 10 Sep 2003 13:32:37 -0000 1.15
+++ main.c 19 Jan 2004 10:04:48 -0000 1.16
@@ -33,13 +33,24 @@
static int afs_adding_peer(struct rxrpc_peer *peer);
static void afs_discarding_peer(struct rxrpc_peer *peer);
-module_init(afs_init);
+/* XXX late_initcall is kludgy, but the only alternative seems to create
+ * a transport upon the first mount, which is worse. Or is it?
+ */
+/* module_init(afs_init); */
+late_initcall(afs_init); /* must be called after net/ to create socket */
+
module_exit(afs_exit);
MODULE_DESCRIPTION("AFS Client File System");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");
+static char *rootcell;
+
+MODULE_PARM(rootcell, "s");
+MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
+
+
static struct rxrpc_peer_ops afs_peer_ops = {
.adding = afs_adding_peer,
.discarding = afs_discarding_peer,
@@ -95,7 +106,7 @@
#endif
/* initialise the cell DB */
- ret = afs_cell_init();
+ ret = afs_cell_init(rootcell);
if (ret < 0)
goto error_keys;
Index: cell.h
===================================================================
RCS file: /home/cvs/afs/fs/afs/cell.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- cell.h 19 Aug 2003 13:37:08 -0000 1.7
+++ cell.h 19 Jan 2004 10:04:48 -0000 1.8
@@ -61,7 +61,7 @@
char name[0]; /* cell name - must go last */
};
-extern int afs_cell_init(void);
+extern int afs_cell_init(char *rootcell);
extern int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell);
Index: cell.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/cell.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- cell.c 24 Sep 2003 07:09:18 -0000 1.16
+++ cell.c 19 Jan 2004 10:04:48 -0000 1.17
@@ -31,11 +31,6 @@
static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */
static struct afs_cell *afs_cell_root;
-static char *rootcell;
-
-MODULE_PARM(rootcell, "s");
-MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
-
#ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_cell_cache_match(void *target,
const void *entry);
@@ -66,8 +61,6 @@
BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */
- down_write(&afs_cells_sem);
-
/* allocate and initialise a cell record */
cell = kmalloc(sizeof(struct afs_cell) + strlen(name) + 1, GFP_KERNEL);
if (!cell) {
@@ -75,6 +68,8 @@
return -ENOMEM;
}
+ down_write(&afs_cells_sem);
+
memset(cell, 0, sizeof(struct afs_cell));
atomic_set(&cell->usage, 0);
@@ -144,10 +139,11 @@
return 0;
badaddr:
- printk("kAFS: bad VL server IP address: '%s'\n", vllist);
+ printk(KERN_ERR "kAFS: bad VL server IP address: '%s'\n", vllist);
error:
up_write(&afs_cells_sem);
kfree(cell);
+ _leave(" = %d", ret);
return ret;
} /* end afs_cell_create() */
@@ -155,29 +151,52 @@
/*
* initialise the cell database from module parameters
*/
-int afs_cell_init(void)
+int afs_cell_init(char *rootcell)
{
+ struct afs_cell *old_root, *new_root;
char *cp;
int ret;
_enter("");
if (!rootcell) {
- printk("kAFS: no root cell specified\n");
- return -EINVAL;
+ /* module is loaded with no parameters, or built statically.
+ * - in the future we might initialize cell DB here.
+ */
+ _leave(" = 0 (but no root)");
+ return 0;
}
cp = strchr(rootcell, ':');
if (!cp) {
- printk("kAFS: no VL server IP addresses specified\n");
+ printk(KERN_ERR "kAFS: no VL server IP addresses specified\n");
+ _leave(" = %d (no colon)", -EINVAL);
return -EINVAL;
}
/* allocate a cell record for the root cell */
*cp++ = 0;
- ret = afs_cell_create(rootcell, cp, &afs_cell_root);
- if (ret == 0)
- afs_get_cell(afs_cell_root);
+ ret = afs_cell_create(rootcell, cp, &new_root);
+ if (ret < 0) {
+ _leave(" = %d", ret);
+ return ret;
+ }
+
+ /* as afs_put_cell() takes locks by itself, we have to do
+ * a little gymnastics to be race-free.
+ */
+ afs_get_cell(new_root);
+
+ write_lock(&afs_cells_lock);
+ while (afs_cell_root) {
+ old_root = afs_cell_root;
+ afs_cell_root = NULL;
+ write_unlock(&afs_cells_lock);
+ afs_put_cell(old_root);
+ write_lock(&afs_cells_lock);
+ }
+ afs_cell_root = new_root;
+ write_unlock(&afs_cells_lock);
_leave(" = %d", ret);
return ret;
@@ -218,9 +237,24 @@
ret = 0;
}
else {
+ read_lock(&afs_cells_lock);
+
cell = afs_cell_root;
- afs_get_cell(cell);
- ret = 0;
+ if (!cell) {
+ /* this should not happen unless user tries to mount
+ * when root cell is not set. Return an impossibly
+ * bizzare errno to alert the user. Things like
+ * ENOENT might be "more appropriate" but they happen
+ * for other reasons.
+ */
+ ret = -EDESTADDRREQ;
+ }
+ else {
+ afs_get_cell(cell);
+ ret = 0;
+ }
+
+ read_unlock(&afs_cells_lock);
}
*_cell = cell;
@@ -402,7 +436,7 @@
/*****************************************************************************/
/*
- * purge in-memory cell database on module unload
+ * purge in-memory cell database on module unload or afs_init() failure
* - the timeout daemon is stopped before calling this
*/
void afs_cell_purge(void)
More information about the linux-afs-cvs
mailing list