aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/volume.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/volume.c')
-rw-r--r--fs/afs/volume.c109
1 files changed, 22 insertions, 87 deletions
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index 45491cfd4f4f..15e13678c216 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -41,83 +41,20 @@ static const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
41 * - Rule 3: If parent volume is R/W, then only mount R/W volume unless 41 * - Rule 3: If parent volume is R/W, then only mount R/W volume unless
42 * explicitly told otherwise 42 * explicitly told otherwise
43 */ 43 */
44struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell, 44struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
45 int rwpath)
46{ 45{
47 struct afs_vlocation *vlocation = NULL; 46 struct afs_vlocation *vlocation = NULL;
48 struct afs_volume *volume = NULL; 47 struct afs_volume *volume = NULL;
49 struct afs_server *server = NULL; 48 struct afs_server *server = NULL;
50 afs_voltype_t type;
51 const char *cellname, *volname, *suffix;
52 char srvtmask; 49 char srvtmask;
53 int force, ret, loop, cellnamesz, volnamesz; 50 int ret, loop;
54 51
55 _enter("%s,,%d,", name, rwpath); 52 _enter("{%*.*s,%d}",
56 53 params->volnamesz, params->volnamesz, params->volname, params->rwpath);
57 if (!name || (name[0] != '%' && name[0] != '#') || !name[1]) {
58 printk("kAFS: unparsable volume name\n");
59 return ERR_PTR(-EINVAL);
60 }
61
62 /* determine the type of volume we're looking for */
63 force = 0;
64 type = AFSVL_ROVOL;
65
66 if (rwpath || name[0] == '%') {
67 type = AFSVL_RWVOL;
68 force = 1;
69 }
70
71 suffix = strrchr(name, '.');
72 if (suffix) {
73 if (strcmp(suffix, ".readonly") == 0) {
74 type = AFSVL_ROVOL;
75 force = 1;
76 } else if (strcmp(suffix, ".backup") == 0) {
77 type = AFSVL_BACKVOL;
78 force = 1;
79 } else if (suffix[1] == 0) {
80 } else {
81 suffix = NULL;
82 }
83 }
84
85 /* split the cell and volume names */
86 name++;
87 volname = strchr(name, ':');
88 if (volname) {
89 cellname = name;
90 cellnamesz = volname - name;
91 volname++;
92 } else {
93 volname = name;
94 cellname = NULL;
95 cellnamesz = 0;
96 }
97
98 volnamesz = suffix ? suffix - volname : strlen(volname);
99
100 _debug("CELL:%*.*s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s",
101 cellnamesz, cellnamesz, cellname ?: "", cell,
102 volnamesz, volnamesz, volname, suffix ?: "-",
103 type,
104 force ? " FORCE" : "");
105
106 /* lookup the cell record */
107 if (cellname || !cell) {
108 cell = afs_cell_lookup(cellname, cellnamesz);
109 if (IS_ERR(cell)) {
110 ret = PTR_ERR(cell);
111 printk("kAFS: unable to lookup cell '%s'\n",
112 cellname ?: "");
113 goto error;
114 }
115 } else {
116 afs_get_cell(cell);
117 }
118 54
119 /* lookup the volume location record */ 55 /* lookup the volume location record */
120 vlocation = afs_vlocation_lookup(cell, volname, volnamesz); 56 vlocation = afs_vlocation_lookup(params->cell, params->key,
57 params->volname, params->volnamesz);
121 if (IS_ERR(vlocation)) { 58 if (IS_ERR(vlocation)) {
122 ret = PTR_ERR(vlocation); 59 ret = PTR_ERR(vlocation);
123 vlocation = NULL; 60 vlocation = NULL;
@@ -126,30 +63,30 @@ struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell,
126 63
127 /* make the final decision on the type we want */ 64 /* make the final decision on the type we want */
128 ret = -ENOMEDIUM; 65 ret = -ENOMEDIUM;
129 if (force && !(vlocation->vldb.vidmask & (1 << type))) 66 if (params->force && !(vlocation->vldb.vidmask & (1 << params->type)))
130 goto error; 67 goto error;
131 68
132 srvtmask = 0; 69 srvtmask = 0;
133 for (loop = 0; loop < vlocation->vldb.nservers; loop++) 70 for (loop = 0; loop < vlocation->vldb.nservers; loop++)
134 srvtmask |= vlocation->vldb.srvtmask[loop]; 71 srvtmask |= vlocation->vldb.srvtmask[loop];
135 72
136 if (force) { 73 if (params->force) {
137 if (!(srvtmask & (1 << type))) 74 if (!(srvtmask & (1 << params->type)))
138 goto error; 75 goto error;
139 } else if (srvtmask & AFS_VOL_VTM_RO) { 76 } else if (srvtmask & AFS_VOL_VTM_RO) {
140 type = AFSVL_ROVOL; 77 params->type = AFSVL_ROVOL;
141 } else if (srvtmask & AFS_VOL_VTM_RW) { 78 } else if (srvtmask & AFS_VOL_VTM_RW) {
142 type = AFSVL_RWVOL; 79 params->type = AFSVL_RWVOL;
143 } else { 80 } else {
144 goto error; 81 goto error;
145 } 82 }
146 83
147 down_write(&cell->vl_sem); 84 down_write(&params->cell->vl_sem);
148 85
149 /* is the volume already active? */ 86 /* is the volume already active? */
150 if (vlocation->vols[type]) { 87 if (vlocation->vols[params->type]) {
151 /* yes - re-use it */ 88 /* yes - re-use it */
152 volume = vlocation->vols[type]; 89 volume = vlocation->vols[params->type];
153 afs_get_volume(volume); 90 afs_get_volume(volume);
154 goto success; 91 goto success;
155 } 92 }
@@ -163,10 +100,10 @@ struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell,
163 goto error_up; 100 goto error_up;
164 101
165 atomic_set(&volume->usage, 1); 102 atomic_set(&volume->usage, 1);
166 volume->type = type; 103 volume->type = params->type;
167 volume->type_force = force; 104 volume->type_force = params->force;
168 volume->cell = cell; 105 volume->cell = params->cell;
169 volume->vid = vlocation->vldb.vid[type]; 106 volume->vid = vlocation->vldb.vid[params->type];
170 107
171 init_rwsem(&volume->server_sem); 108 init_rwsem(&volume->server_sem);
172 109
@@ -196,28 +133,26 @@ struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell,
196 afs_get_vlocation(vlocation); 133 afs_get_vlocation(vlocation);
197 volume->vlocation = vlocation; 134 volume->vlocation = vlocation;
198 135
199 vlocation->vols[type] = volume; 136 vlocation->vols[volume->type] = volume;
200 137
201success: 138success:
202 _debug("kAFS selected %s volume %08x", 139 _debug("kAFS selected %s volume %08x",
203 afs_voltypes[volume->type], volume->vid); 140 afs_voltypes[volume->type], volume->vid);
204 up_write(&cell->vl_sem); 141 up_write(&params->cell->vl_sem);
205 afs_put_vlocation(vlocation); 142 afs_put_vlocation(vlocation);
206 afs_put_cell(cell);
207 _leave(" = %p", volume); 143 _leave(" = %p", volume);
208 return volume; 144 return volume;
209 145
210 /* clean up */ 146 /* clean up */
211error_up: 147error_up:
212 up_write(&cell->vl_sem); 148 up_write(&params->cell->vl_sem);
213error: 149error:
214 afs_put_vlocation(vlocation); 150 afs_put_vlocation(vlocation);
215 afs_put_cell(cell);
216 _leave(" = %d", ret); 151 _leave(" = %d", ret);
217 return ERR_PTR(ret); 152 return ERR_PTR(ret);
218 153
219error_discard: 154error_discard:
220 up_write(&cell->vl_sem); 155 up_write(&params->cell->vl_sem);
221 156
222 for (loop = volume->nservers - 1; loop >= 0; loop--) 157 for (loop = volume->nservers - 1; loop >= 0; loop--)
223 afs_put_server(volume->servers[loop]); 158 afs_put_server(volume->servers[loop]);