aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>2006-01-18 20:43:00 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-18 22:20:21 -0500
commit4833aff757b747b51b878a13f3a6e2b1a2abb619 (patch)
treecaec57a746cb04ef62e04fc5cf14a6acc555de46
parentce2d2aedcc3ca582fed90f44970e8b3e4f006a7d (diff)
[PATCH] uml: allow again to move backing file and to override saved location
When the user specifies both a COW file and its backing file, if the previous backing file is not found, currently UML tries again to use it and fails. This can be corrected by changing same_backing_files() return value in that case, so that the caller will try to change the COW file to point to the new location, as already done in other cases. Additionally, given the change in the meaning of the func, change its name, invert its return value, so all values are inverted except when stat(from_cow,&buf2) fails. And add some comments and two minor bugfixes - remove a fd leak (return err rather than goto out) and a repeated check. Tested well. Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Cc: Jeff Dike <jdike@addtoit.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/um/drivers/ubd_kern.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 7696f8d2d89c..c171d0aa5e9d 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,7 +1191,7 @@ 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){
@@ -1209,6 +1211,7 @@ int open_ubd_file(char *file, struct openflags *openflags,
1209 goto out_close; 1211 goto out_close;
1210 } 1212 }
1211 1213
1214 /* Succesful return case! */
1212 if(backing_file_out == NULL) return(fd); 1215 if(backing_file_out == NULL) return(fd);
1213 1216
1214 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, 1217 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
@@ -1220,17 +1223,16 @@ int open_ubd_file(char *file, struct openflags *openflags,
1220 } 1223 }
1221 if(err) return(fd); 1224 if(err) return(fd);
1222 1225
1223 if(backing_file_out == NULL) return(fd); 1226 asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
1224
1225 same = same_backing_files(*backing_file_out, backing_file, file);
1226 1227
1227 if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){ 1228 /* Allow switching only if no mismatch. */
1229 if (asked_switch && !backing_file_mismatch(*backing_file_out, size, mtime)) {
1228 printk("Switching backing file to '%s'\n", *backing_file_out); 1230 printk("Switching backing file to '%s'\n", *backing_file_out);
1229 err = write_cow_header(file, fd, *backing_file_out, 1231 err = write_cow_header(file, fd, *backing_file_out,
1230 sectorsize, align, &size); 1232 sectorsize, align, &size);
1231 if(err){ 1233 if(err){
1232 printk("Switch failed, errno = %d\n", -err); 1234 printk("Switch failed, errno = %d\n", -err);
1233 return(err); 1235 goto out_close;
1234 } 1236 }
1235 } 1237 }
1236 else { 1238 else {