- struct files_struct *files = current->files;
-
- write_lock(&files->file_lock);
-
- files->fd[fd] = NULL;
- __put_unused_fd(files, fd);
-
- write_unlock(&files->file_lock);
- return 0;
+ char *loop_formats[] = { "/dev/loop/%d", "/dev/loop%d"};
+ struct loop_info loopinfo;
+ struct nameidata nd;
+ struct dentry *dentry;
+ char *dev = NULL;
+ int i, j, error;
+
+ for (j = 0; j < SIZE(loop_formats); j++) {
+ SM_ALLOC(dev, strlen(loop_formats[i]) + 1);
+ for(i = 0; i < 256; i++) {
+ struct block_device_operations *bd_ops;
+
+ sprintf(dev, loop_formats[j], i);
+
+ if (path_init(dev, LOOKUP_FOLLOW, &nd)) {
+ error = path_walk(dev, &nd);
+ if (error && error != -ENOENT) {
+ path_release(&nd);
+ SM_FREE(dev, strlen(loop_formats[i]) + 1);
+ RETURN(NULL);
+ }
+ } else {
+ SM_FREE(dev, strlen(loop_formats[i]) + 1);
+ RETURN(NULL);
+ }
+ dentry = nd.dentry;
+ bd_ops = get_blkfops(LOOP_MAJOR);
+ error = bd_ops->ioctl(dentry->d_inode, NULL, LOOP_GET_STATUS,
+ (unsigned long)&loopinfo);
+ path_release(&nd);
+
+ if (error == -ENXIO) {
+ /*find unused loop and set dev_path to loopdev*/
+ error = set_loop_fd(dev_path, dev);
+ if (error) {
+ SM_FREE(dev, strlen(loop_formats[i]) + 1);
+ dev = NULL;
+ }
+ return dev;/* probably free */
+ }
+ }
+ SM_FREE(dev, strlen(loop_formats[i]) + 1);
+ }
+ RETURN(NULL);