diff options
Diffstat (limited to 'arch/um/drivers/ubd_kern.c')
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 59 |
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 | ||
1106 | static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) | 1106 | static 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 | ||
1133 | static int backing_file_mismatch(char *file, __u64 size, time_t mtime) | 1135 | static 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, §orsize, &align, bitmap_offset_out); | 1220 | &size, §orsize, &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 | ||
1251 | int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, | 1256 | int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, |