diff options
Diffstat (limited to 'fs/afs/volume.c')
-rw-r--r-- | fs/afs/volume.c | 109 |
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 | */ |
44 | struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell, | 44 | struct 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(¶ms->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 | ||
201 | success: | 138 | success: |
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(¶ms->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 */ |
211 | error_up: | 147 | error_up: |
212 | up_write(&cell->vl_sem); | 148 | up_write(¶ms->cell->vl_sem); |
213 | error: | 149 | error: |
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 | ||
219 | error_discard: | 154 | error_discard: |
220 | up_write(&cell->vl_sem); | 155 | up_write(¶ms->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]); |