aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/ubd_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/ubd_kern.c')
-rw-r--r--arch/um/drivers/ubd_kern.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 7696f8d2d89c..101efd26d467 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1103,31 +1103,33 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1103 return(-EINVAL); 1103 return(-EINVAL);
1104} 1104}
1105 1105
1106static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) 1106static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
1107{ 1107{
1108 struct uml_stat buf1, buf2; 1108 struct uml_stat buf1, buf2;
1109 int err; 1109 int err;
1110 1110
1111 if(from_cmdline == NULL) return(1); 1111 if(from_cmdline == NULL)
1112 if(!strcmp(from_cmdline, from_cow)) return(1); 1112 return 0;
1113 if(!strcmp(from_cmdline, from_cow))
1114 return 0;
1113 1115
1114 err = os_stat_file(from_cmdline, &buf1); 1116 err = os_stat_file(from_cmdline, &buf1);
1115 if(err < 0){ 1117 if(err < 0){
1116 printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err); 1118 printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
1117 return(1); 1119 return 0;
1118 } 1120 }
1119 err = os_stat_file(from_cow, &buf2); 1121 err = os_stat_file(from_cow, &buf2);
1120 if(err < 0){ 1122 if(err < 0){
1121 printk("Couldn't stat '%s', err = %d\n", from_cow, -err); 1123 printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
1122 return(1); 1124 return 1;
1123 } 1125 }
1124 if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino)) 1126 if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
1125 return(1); 1127 return 0;
1126 1128
1127 printk("Backing file mismatch - \"%s\" requested,\n" 1129 printk("Backing file mismatch - \"%s\" requested,\n"
1128 "\"%s\" specified in COW header of \"%s\"\n", 1130 "\"%s\" specified in COW header of \"%s\"\n",
1129 from_cmdline, from_cow, cow); 1131 from_cmdline, from_cow, cow);
1130 return(0); 1132 return 1;
1131} 1133}
1132 1134
1133static int backing_file_mismatch(char *file, __u64 size, time_t mtime) 1135static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
@@ -1189,18 +1191,19 @@ int open_ubd_file(char *file, struct openflags *openflags,
1189 unsigned long long size; 1191 unsigned long long size;
1190 __u32 version, align; 1192 __u32 version, align;
1191 char *backing_file; 1193 char *backing_file;
1192 int fd, err, sectorsize, same, mode = 0644; 1194 int fd, err, sectorsize, asked_switch, mode = 0644;
1193 1195
1194 fd = os_open_file(file, *openflags, mode); 1196 fd = os_open_file(file, *openflags, mode);
1195 if(fd < 0){ 1197 if (fd < 0) {
1196 if((fd == -ENOENT) && (create_cow_out != NULL)) 1198 if ((fd == -ENOENT) && (create_cow_out != NULL))
1197 *create_cow_out = 1; 1199 *create_cow_out = 1;
1198 if(!openflags->w || 1200 if (!openflags->w ||
1199 ((fd != -EROFS) && (fd != -EACCES))) return(fd); 1201 ((fd != -EROFS) && (fd != -EACCES)))
1202 return fd;
1200 openflags->w = 0; 1203 openflags->w = 0;
1201 fd = os_open_file(file, *openflags, mode); 1204 fd = os_open_file(file, *openflags, mode);
1202 if(fd < 0) 1205 if (fd < 0)
1203 return(fd); 1206 return fd;
1204 } 1207 }
1205 1208
1206 err = os_lock_file(fd, openflags->w); 1209 err = os_lock_file(fd, openflags->w);
@@ -1209,7 +1212,9 @@ int open_ubd_file(char *file, struct openflags *openflags,
1209 goto out_close; 1212 goto out_close;
1210 } 1213 }
1211 1214
1212 if(backing_file_out == NULL) return(fd); 1215 /* Succesful return case! */
1216 if(backing_file_out == NULL)
1217 return(fd);
1213 1218
1214 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, 1219 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
1215 &size, &sectorsize, &align, bitmap_offset_out); 1220 &size, &sectorsize, &align, bitmap_offset_out);
@@ -1218,34 +1223,34 @@ int open_ubd_file(char *file, struct openflags *openflags,
1218 "errno = %d\n", file, -err); 1223 "errno = %d\n", file, -err);
1219 goto out_close; 1224 goto out_close;
1220 } 1225 }
1221 if(err) return(fd); 1226 if(err)
1222 1227 return(fd);
1223 if(backing_file_out == NULL) return(fd);
1224 1228
1225 same = same_backing_files(*backing_file_out, backing_file, file); 1229 asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
1226 1230
1227 if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){ 1231 /* Allow switching only if no mismatch. */
1232 if (asked_switch && !backing_file_mismatch(*backing_file_out, size, mtime)) {
1228 printk("Switching backing file to '%s'\n", *backing_file_out); 1233 printk("Switching backing file to '%s'\n", *backing_file_out);
1229 err = write_cow_header(file, fd, *backing_file_out, 1234 err = write_cow_header(file, fd, *backing_file_out,
1230 sectorsize, align, &size); 1235 sectorsize, align, &size);
1231 if(err){ 1236 if (err) {
1232 printk("Switch failed, errno = %d\n", -err); 1237 printk("Switch failed, errno = %d\n", -err);
1233 return(err); 1238 goto out_close;
1234 } 1239 }
1235 } 1240 } else {
1236 else {
1237 *backing_file_out = backing_file; 1241 *backing_file_out = backing_file;
1238 err = backing_file_mismatch(*backing_file_out, size, mtime); 1242 err = backing_file_mismatch(*backing_file_out, size, mtime);
1239 if(err) goto out_close; 1243 if (err)
1244 goto out_close;
1240 } 1245 }
1241 1246
1242 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 1247 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
1243 bitmap_len_out, data_offset_out); 1248 bitmap_len_out, data_offset_out);
1244 1249
1245 return(fd); 1250 return fd;
1246 out_close: 1251 out_close:
1247 os_close_file(fd); 1252 os_close_file(fd);
1248 return(err); 1253 return err;
1249} 1254}
1250 1255
1251int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, 1256int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,