View | Details | Raw Unified | Return to bug 15838
Collapse All | Expand All

(-)linux-2.6.25.4.orig/Documentation/filesystems/00-INDEX (+2 lines)
Lines 92-97 Link Here
92
	- a description of shared subtrees for namespaces.
92
	- a description of shared subtrees for namespaces.
93
smbfs.txt
93
smbfs.txt
94
	- info on using filesystems with the SMB protocol (Win 3.11 and NT).
94
	- info on using filesystems with the SMB protocol (Win 3.11 and NT).
95
supermount.txt
96
	- info on using supermount for removable media.
95
spufs.txt
97
spufs.txt
96
	- info and mount options for the SPU filesystem used on Cell.
98
	- info and mount options for the SPU filesystem used on Cell.
97
sysfs-pci.txt
99
sysfs-pci.txt
(-)linux-2.6.25.4.orig/Documentation/filesystems/supermount.txt (+258 lines)
Line 0 Link Here
1
Supermount README
2
=================
3
4
Running supermount
5
------------------
6
7
To run supermount, compile and install a kernel with the supermount
8
patches and select "Y" to the question
9
10
	Supermount removable media support (CONFIG_SUPERMOUNT) [Y/n/?] 
11
12
when you run "make config".  You mount a supermount filesystem with
13
the normal mount command, using the syntax
14
15
	mount -t supermount -o <superfs-options>,--,<subfs-options> none <mpt>
16
17
or by adding correpsonding line to /etc/fstab
18
19
	none  <mpt> supermount <superfs-options>,--,<subfs-options> 0 0
20
21
where
22
23
	<superfs-options> are the options you want to pass to supermount
24
	itself.  These are described below.
25
26
	<subfs-options> are the options you want supermount to pass to the
27
	dismountable filesystem underneath.
28
29
	<mpt> is the mount point where you want your removable media to be
30
	mounted. 
31
	
32
WARNING: If you get errors with GCC 3.4.X or avobe with inline on subfs.c
33
replace all instances of "inline" by "" (nothing) and go ahead.
34
[updated for kernel 2.6.X by madgus@gmail.com]
35
Many thanks to:
36
Robert Sombrutzki <sombrutz@informatik.hu-berlin.de>
37
Alexandre Teixeira <alexandre@insignesoftware.com>
38
Keith Smith <keith@ksmith.com>
39
English
40
[http://www.compunauta.com/forums/linux/instalarlinux/supermount_en.html]
41
EspaƱol
42
[http://www.compunauta.com/forums/linux/instalarlinux/supermount_es.html]
43
44
WARNING: in the above description `none' is literal word. While device
45
is ignored by supermount itself, using real files in this place (real
46
device name or mount point directory name) is known to cause problems.
47
Some programs - fuser is one of them - will try to descend into filesystem
48
if dev can be statted, thus making supermount to attempt to access media.
49
This is annoying at best - in the worst case it can take very long time
50
during startup or shutdown.
51
52
Notice that you do not directly specify the block device you are going
53
to mount on the mount command line.  This is because the supermount
54
filesystem is NOT connected to a block device; rather, supermount is
55
responsible for connecting a separate filesystem to the block device.
56
You specify the sub-filesystem and block device name by providing the
57
<superfs-options> field, where the following options are currently
58
recognised:
59
60
61
* fs=<filesystem-type>			[default is "auto"]
62
63
	Specify the subfilesystem type. Not every filesystem type has
64
been tested.  If you use `auto', it will try the following filesystems
65
in order:
66
		    	"udf"
67
			"iso9660"
68
			"ext2"
69
			"vfat"
70
			"msdos"
71
72
It is also possible to give list of types separated by `:', like
73
74
		fs=ext2:vfat
75
		    - or -
76
		fs=udf:iso9660
77
 
78
79
* dev=<block-device>			[no default, mandatory]
80
81
	Specify the block device on which the subfs is to be mounted.
82
83
84
* tray_lock={always,onwrite,never}	[default is "onwrite"]
85
86
	Specify when supermount is to prevent media removal. `always' means
87
on every access (it was default in earlier versions), `onwrite' means only
88
for write access and `never' means never :) `onwrite' and `never' are the
89
same for ro media like CD-ROM. It is not clear when `never' is actually useful,
90
it is presented for completeness only.
91
92
* debug[=<bitmap>]			[default is no debug]
93
94
	Enable debugging code in the supermount filesystem, if
95
the debug option was enabled at compile time.  By default, debugging
96
code is compiled into the kernel but is disabled until a debug mount
97
option is seen. <bitmap> is the combination of debug flags, following
98
flags are possible:
99
100
	0x001 - "generic" debug (used by supermount_debug) - default
101
	0x002 - trace dentry.c
102
	0x004 - trace file.c
103
	0x008 - trace filemap.c
104
	0x010 - trace mediactl.c
105
	0x020 - trace namei.c
106
	0x040 - trace subfs.c
107
	0x080 - trace super.c
108
109
Trace flags turn on tracing of functions in correpsonding files.
110
"Generic" debug flag is tested in supermount_debug; for compatibility,
111
if no flags are specified, this flag is set.
112
113
114
* '--'
115
116
	All options after the option string '--' will be passed
117
directly to the subfilesystem when it gets mounted.
118
119
Errors
120
------
121
122
In addition to "normal" errors during file operations supermount may
123
return following error codes:
124
125
* No medium found
126
127
	You attempt to access supermounted filesystem when there is no
128
medium inserted
129
130
* Wrong medium type
131
132
	(Not really generated by supermount) You attempt to mount CD
133
without data tracks
134
135
* Stale NFS file handle
136
137
	You attempt to use file handle after medium has been changed.
138
139
* No such device or address
140
141
	(Not really generated by supermount) device specified in
142
dev=<device> option does not exist. Also some drivers return this
143
error instead of "No medium found", one example being floppy driver.
144
145
* Device or resource busy
146
147
	(Not really generated by supermount) device is already mounted.
148
Supermount prevents double mount even if kernel otherwise would make it
149
possible.
150
151
* No such file or directory
152
153
	(Not really generated by supermount) file name specified by
154
dev=<device> option does not exist
155
156
* Operation not permitted
157
158
	You attempt to access subfs that is currently disabled
159
160
/proc support
161
-------------
162
163
If kernel has been compiled with procfs support, supermount will provide
164
/proc interface to read subfs status and to control some aspects of subfs.
165
The following files are created under /proc/fs/supermount:
166
167
* version (ro)
168
	Shows supermount version.
169
170
* subfs (rw)
171
172
	Reading this file returns list of all subfs status. One line for
173
every subfs is returned; the format is
174
	
175
	<devname> disabled
176
		- or -
177
	<devname> unmounted
178
		- or -
179
	<devname> mounted readcount writecount
180
181
where <devname> is the string passed in `dev=' parameter during mount.
182
`readcount' is number of current subfs "users" needing ro access; `writecount'
183
is the number of "users" needing rw mode. It is mostly the number of open
184
files, but inode operations also add to these counts. Those operations
185
are normally short-lived to be seen.
186
187
	Writing this file changes subfs status; the following commands are
188
suported:
189
190
	<devname> [disable|enable] [release [force]]
191
192
`disable' will disable subfs (i.e. any futher attempt to mount is rejected).
193
Subfs must be unmounted; use `disable release' or `disable release force' to
194
unmount and disable at the same time.
195
196
`enable' will enable disabled subfs, it has no effect if subfs is already
197
enabled.
198
199
`release' will unmount subfs unless it is busy (opencount > 0). To unmount
200
busy subfs add `force'; the effect is very much as if media change has been
201
detected (with the difference that subfs will be cleanly unmounted).
202
203
Some basic sanity checks are performed, i.e. it is impossible to specify
204
both `enable' and `disable' or `force' without `release'.
205
206
Internals/Locking
207
-----------------
208
209
THIS SECTION IS PROBABLY INCOMPLETE. CORRECTIONS ARE WELCOME.
210
211
Supermount itself is using two locks and relies on two more locking rules
212
as implemented by kernel.
213
214
* supermount_proc_sem
215
216
	Global mutex used to protect list of sbi during access to
217
/proc/fs/supermount/subfs
218
219
* sbi->sem
220
221
	Per-filesystem mutex that protects subfs state (mounted/unmounted).
222
Any changes to subfs state (mounting, unmouting, adding or removing file,
223
dentry or inode) happen under this mutex.
224
225
* inode->i_sem (see Documentation/filesystem/Locking)
226
227
	Per-inode mutex used by VFS to serialize inode unlink operation.
228
Supermount relies on the fact that link/unlink for an inode are mutually
229
locked and thus inode->i_nlink is atomic inside of fs method.
230
231
* BKL
232
233
	Used to protect device usage count. It is changed in open/release
234
and referenced in ioctl all of which run under BKL. Supermount adds mediactl
235
and internally wraps it in BKL as well.
236
237
Caveats/BUGS
238
------------
239
240
Inode times are believed to be correctly updated; still it is possible that
241
I missed some point.
242
243
If subfs is not yet mounted, find /mnt/cdrom fails with "find: /mnt/cdrom
244
changed during execution of find". It is unlikely it can be fixed in
245
supermount; much more simple is to provide wrapper that will check if subfs
246
is mounted and do simple "touch  /mnt/cdrom" if not to make sure it is.
247
248
Supermount attempts to check for changed media at every operation and
249
invalidate and umount old subfs to avoid new media corruption in rw case.
250
Still it is possible that kernel will write out stale information and
251
it is outside of supermount control.
252
253
By default cdrom driver does not check media type i.e. supermount will
254
try all configured fs types in turn that may be quite time consuming.
255
Use sysctl -w dev.cdrom.check_media=1 to enable it. Comments in cdrom.c
256
indicate that some (non conforming) software may have problems with this
257
settings. YMMV
258
(-)linux-2.6.25.4.orig/drivers/cdrom/cdrom.c (-9 / +51 lines)
Lines 280-285 Link Here
280
#include <linux/fcntl.h>
280
#include <linux/fcntl.h>
281
#include <linux/blkdev.h>
281
#include <linux/blkdev.h>
282
#include <linux/times.h>
282
#include <linux/times.h>
283
#include <linux/supermount_media.h>
283
284
284
#include <asm/uaccess.h>
285
#include <asm/uaccess.h>
285
286
Lines 344-350 Link Here
344
#define CDROM_DEF_TIMEOUT	(7 * HZ)
345
#define CDROM_DEF_TIMEOUT	(7 * HZ)
345
346
346
/* Not-exported routines. */
347
/* Not-exported routines. */
347
static int open_for_data(struct cdrom_device_info * cdi);
348
static int open_for_data(struct cdrom_device_info * cdi, struct block_device *bdev);
348
static int check_for_audio_disc(struct cdrom_device_info * cdi,
349
static int check_for_audio_disc(struct cdrom_device_info * cdi,
349
			 struct cdrom_device_ops * cdo);
350
			 struct cdrom_device_ops * cdo);
350
static void sanitize_format(union cdrom_addr *addr, 
351
static void sanitize_format(union cdrom_addr *addr, 
Lines 1007-1013 Link Here
1007
	if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
1008
	if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
1008
		ret = cdi->ops->open(cdi, 1);
1009
		ret = cdi->ops->open(cdi, 1);
1009
	} else {
1010
	} else {
1010
		ret = open_for_data(cdi);
1011
		ret = open_for_data(cdi, ip->i_bdev);
1011
		if (ret)
1012
		if (ret)
1012
			goto err;
1013
			goto err;
1013
		cdrom_mmc3_profile(cdi);
1014
		cdrom_mmc3_profile(cdi);
Lines 1043-1049 Link Here
1043
}
1044
}
1044
1045
1045
static
1046
static
1046
int open_for_data(struct cdrom_device_info * cdi)
1047
int open_for_data(struct cdrom_device_info * cdi, struct block_device *bdev)
1047
{
1048
{
1048
	int ret;
1049
	int ret;
1049
	struct cdrom_device_ops *cdo = cdi->ops;
1050
	struct cdrom_device_ops *cdo = cdi->ops;
Lines 1128-1134 Link Here
1128
		cdinfo(CD_OPEN, "open device failed.\n"); 
1129
		cdinfo(CD_OPEN, "open device failed.\n"); 
1129
		goto clean_up_and_return;
1130
		goto clean_up_and_return;
1130
	}
1131
	}
1131
	if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
1132
	if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK) &&
1133
	    supermount_usage_count(bdev, cdi->use_count) > 0) {
1132
			cdo->lock_door(cdi, 1);
1134
			cdo->lock_door(cdi, 1);
1133
			cdinfo(CD_OPEN, "door locked.\n");
1135
			cdinfo(CD_OPEN, "door locked.\n");
1134
	}
1136
	}
Lines 1220-1226 Link Here
1220
		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
1222
		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
1221
		cdrom_dvd_rw_close_write(cdi);
1223
		cdrom_dvd_rw_close_write(cdi);
1222
1224
1223
		if ((cdo->capability & CDC_LOCK) && !keeplocked) {
1225
		if (!supermount_usage_count(fp ? fp->f_dentry->d_inode->i_bdev : 0, cdi->use_count) &&
1226
		    (cdo->capability & CDC_LOCK) && !keeplocked) {
1224
			cdinfo(CD_CLOSE, "Unlocking door!\n");
1227
			cdinfo(CD_CLOSE, "Unlocking door!\n");
1225
			cdo->lock_door(cdi, 0);
1228
			cdo->lock_door(cdi, 0);
1226
		}
1229
		}
Lines 1494-1499 Link Here
1494
		tracks->cdi, tracks->xa);
1497
		tracks->cdi, tracks->xa);
1495
}	
1498
}	
1496
1499
1500
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1501
/*
1502
 * MEDIA_LOCK, MEDIA_UNLOCK
1503
 *   optarg == 0 - do not adjust usage count (compatibility)
1504
 *   optarg == 1 - adjust usage count
1505
 */
1506
int cdrom_mediactl(struct cdrom_device_info *cdi, struct block_device *bdev, int op, int optarg)
1507
{
1508
	struct cdrom_device_ops *cdo = cdi->ops;
1509
1510
	switch (op) {
1511
	case MEDIA_LOCK:
1512
	case MEDIA_UNLOCK:
1513
		if (op == MEDIA_UNLOCK && optarg) {
1514
			cdi->use_count--;
1515
		if (cdi->use_count < 0)
1516
			cdi->use_count = 0;
1517
		}
1518
		if (cdo->capability & ~cdi->mask & CDC_LOCK &&
1519
		    cdi->options & CDO_LOCK &&
1520
			supermount_usage_count(bdev, cdi->use_count) == 0)
1521
			cdo->lock_door(cdi, (op == MEDIA_LOCK));
1522
		if (op == MEDIA_LOCK && optarg)
1523
			cdi->use_count++;
1524
		break;
1525
	default:
1526
		return -EINVAL;
1527
	}
1528
	return 0;
1529
}
1530
#endif
1531
1497
/* Requests to the low-level drivers will /always/ be done in the
1532
/* Requests to the low-level drivers will /always/ be done in the
1498
   following format convention:
1533
   following format convention:
1499
1534
Lines 2237-2250 Link Here
2237
	return 0;
2272
	return 0;
2238
}
2273
}
2239
2274
2240
static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
2275
static int cdrom_ioctl_eject(struct cdrom_device_info *cdi, struct inode *ip)
2241
{
2276
{
2242
	cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
2277
	cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
2243
2278
2244
	if (!CDROM_CAN(CDC_OPEN_TRAY))
2279
	if (!CDROM_CAN(CDC_OPEN_TRAY))
2245
		return -ENOSYS;
2280
		return -ENOSYS;
2246
	if (cdi->use_count != 1 || keeplocked)
2281
//	if (cdi->use_count != 1 || keeplocked)
2247
		return -EBUSY;
2282
//		return -EBUSY;
2283
		if (keeplocked ||
2284
		    (supermount_usage_count(ip->i_bdev,cdi->use_count) != 1))
2285
                     return -EBUSY;
2286
2248
	if (CDROM_CAN(CDC_LOCK)) {
2287
	if (CDROM_CAN(CDC_LOCK)) {
2249
		int ret = cdi->ops->lock_door(cdi, 0);
2288
		int ret = cdi->ops->lock_door(cdi, 0);
2250
		if (ret)
2289
		if (ret)
Lines 2713-2719 Link Here
2713
	case CDROMMULTISESSION:
2752
	case CDROMMULTISESSION:
2714
		return cdrom_ioctl_multisession(cdi, argp);
2753
		return cdrom_ioctl_multisession(cdi, argp);
2715
	case CDROMEJECT:
2754
	case CDROMEJECT:
2716
		return cdrom_ioctl_eject(cdi);
2755
		return cdrom_ioctl_eject(cdi,ip);
2717
	case CDROMCLOSETRAY:
2756
	case CDROMCLOSETRAY:
2718
		return cdrom_ioctl_closetray(cdi);
2757
		return cdrom_ioctl_closetray(cdi);
2719
	case CDROMEJECT_SW:
2758
	case CDROMEJECT_SW:
Lines 3270-3275 Link Here
3270
EXPORT_SYMBOL(cdrom_release);
3309
EXPORT_SYMBOL(cdrom_release);
3271
EXPORT_SYMBOL(cdrom_ioctl);
3310
EXPORT_SYMBOL(cdrom_ioctl);
3272
EXPORT_SYMBOL(cdrom_media_changed);
3311
EXPORT_SYMBOL(cdrom_media_changed);
3312
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3313
EXPORT_SYMBOL(cdrom_mediactl);
3314
#endif
3273
EXPORT_SYMBOL(cdrom_number_of_slots);
3315
EXPORT_SYMBOL(cdrom_number_of_slots);
3274
EXPORT_SYMBOL(cdrom_mode_select);
3316
EXPORT_SYMBOL(cdrom_mode_select);
3275
EXPORT_SYMBOL(cdrom_mode_sense);
3317
EXPORT_SYMBOL(cdrom_mode_sense);
(-)linux-2.6.25.4.orig/drivers/ide/ide-cd.c (-2 / +57 lines)
Lines 40-49 Link Here
40
#include <linux/bcd.h>
40
#include <linux/bcd.h>
41
41
42
#include <scsi/scsi.h>	/* For SCSI -> ATAPI command conversion */
42
#include <scsi/scsi.h>	/* For SCSI -> ATAPI command conversion */
43
44
#include <asm/irq.h>
43
#include <asm/irq.h>
45
#include <asm/io.h>
44
#include <asm/io.h>
46
#include <asm/byteorder.h>
45
#include <asm/byteorder.h>
46
#include <linux/supermount_media.h>
47
#include <asm/uaccess.h>
47
#include <asm/uaccess.h>
48
#include <asm/unaligned.h>
48
#include <asm/unaligned.h>
49
49
Lines 2106-2111 Link Here
2106
	struct gendisk *disk = inode->i_bdev->bd_disk;
2106
	struct gendisk *disk = inode->i_bdev->bd_disk;
2107
	struct cdrom_info *info = ide_cd_g(disk);
2107
	struct cdrom_info *info = ide_cd_g(disk);
2108
2108
2109
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2110
	/*
2111
	 * This is the same sort of clockload as use in blkdev_get.
2112
	 * We need information whether device is supermounted inside
2113
	 * of cdrom_release to decide if tray must be unlocked.
2114
	 * This information so far is available only by looking
2115
	 * up superblock but it needs struct *bdev and it is not
2116
	 * available in cdrom_release anymore
2117
	 */
2118
	struct dentry t_dentry;
2119
	struct file t_file;
2120
2121
	if (!file) {
2122
		t_file.f_dentry = &t_dentry;
2123
		t_dentry.d_inode = inode;
2124
		file = &t_file;
2125
	}
2126
#endif
2127
2109
	cdrom_release (&info->devinfo, file);
2128
	cdrom_release (&info->devinfo, file);
2110
2129
2111
	ide_cd_put(info);
2130
	ide_cd_put(info);
Lines 2190-2195 Link Here
2190
2209
2191
	return  0;
2210
	return  0;
2192
}
2211
}
2212
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2213
/*
2214
MADGUS: AJJJJ PLEASE READ DTHE LKML ABOUT NEW STUFFS
2215
static int idecd_mediactl(struct block_device *bdev, int op, int arg)
2216
{
2217
	struct gendisk *disk = bdev->bd_disk;
2218
	ide_drive_t *drive = disk->private_data;
2219
	struct cdrom_info *info = drive->driver_data;
2220
	return cdrom_mediactl(&info->devinfo, bdev, op, arg);
2221
	
2222
	struct cdrom_info *info = drive->driver_data;
2223
	
2224
	CDROM_STATE_FLAGS (drive)->media_changed = 1;
2225
	CDROM_STATE_FLAGS (drive)->toc_valid = 0;
2226
	info->nsectors_buffered = 0;
2227
2228
}*/
2229
static int idecd_mediactl(struct block_device *bdev, int op, int arg)
2230
{
2231
	//struct gendisk *disk = bdev->bd_disk; //this def works
2232
	return 0;
2233
	/*
2234
	FIXME: some of this two defs, goes into Page Faults
2235
	There are a lot of controls over CD_ROM disabling for a while
2236
	
2237
	ide_drive_t *drive = disk->private_data;
2238
			    //info->drive;
2239
	struct cdrom_info *info = drive->driver_data;
2240
	return cdrom_mediactl(&info->devinfo, bdev, op, arg);
2241
	*/
2242
}
2243
#endif
2193
2244
2194
static struct block_device_operations idecd_ops = {
2245
static struct block_device_operations idecd_ops = {
2195
	.owner		= THIS_MODULE,
2246
	.owner		= THIS_MODULE,
Lines 2197-2203 Link Here
2197
	.release	= idecd_release,
2248
	.release	= idecd_release,
2198
	.ioctl		= idecd_ioctl,
2249
	.ioctl		= idecd_ioctl,
2199
	.media_changed	= idecd_media_changed,
2250
	.media_changed	= idecd_media_changed,
2200
	.revalidate_disk= idecd_revalidate_disk
2251
	.revalidate_disk= idecd_revalidate_disk,
2252
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2253
	.mediactl	= idecd_mediactl,
2254
#endif
2255
2201
};
2256
};
2202
2257
2203
/* options */
2258
/* options */
(-)linux-2.6.25.4.orig/drivers/ide/ide-floppy.c (-5 / +43 lines)
Lines 36-41 Link Here
36
36
37
#include <scsi/scsi_ioctl.h>
37
#include <scsi/scsi_ioctl.h>
38
38
39
#include <linux/supermount_media.h>
40
39
#include <asm/byteorder.h>
41
#include <asm/byteorder.h>
40
#include <linux/irq.h>
42
#include <linux/irq.h>
41
#include <linux/uaccess.h>
43
#include <linux/uaccess.h>
Lines 1439-1445 Link Here
1439
1441
1440
	floppy->openers++;
1442
	floppy->openers++;
1441
1443
1442
	if (floppy->openers == 1) {
1444
	if (supermount_usage_count(inode->i_bdev, floppy->openers) == 1) {
1443
		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
1445
		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
1444
		/* Just in case */
1446
		/* Just in case */
1445
1447
Lines 1493-1499 Link Here
1493
1495
1494
	debug_log("Reached %s\n", __func__);
1496
	debug_log("Reached %s\n", __func__);
1495
1497
1496
	if (floppy->openers == 1) {
1498
 	if (supermount_usage_count(inode->i_bdev, floppy->openers) == 1) {
1497
		/* IOMEGA Clik! drives do not support lock/unlock commands */
1499
		/* IOMEGA Clik! drives do not support lock/unlock commands */
1498
		if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
1500
		if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
1499
			idefloppy_create_prevent_cmd(&pc, 0);
1501
			idefloppy_create_prevent_cmd(&pc, 0);
Lines 1522-1530 Link Here
1522
}
1524
}
1523
1525
1524
static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc,
1526
static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc,
1527
			       struct block_device *bdev,
1525
			       unsigned long arg, unsigned int cmd)
1528
			       unsigned long arg, unsigned int cmd)
1526
{
1529
{
1527
	if (floppy->openers > 1)
1530
	if (supermount_usage_count(bdev, floppy->openers) > 1)
1528
		return -EBUSY;
1531
		return -EBUSY;
1529
1532
1530
	/* The IOMEGA Clik! Drive doesn't support this command -
1533
	/* The IOMEGA Clik! Drive doesn't support this command -
Lines 1610-1616 Link Here
1610
	case CDROMEJECT:
1613
	case CDROMEJECT:
1611
		/* fall through */
1614
		/* fall through */
1612
	case CDROM_LOCKDOOR:
1615
	case CDROM_LOCKDOOR:
1613
		return ide_floppy_lockdoor(floppy, &pc, arg, cmd);
1616
		return ide_floppy_lockdoor(floppy, &pc, bdev, arg, cmd);
1614
	case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
1617
	case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
1615
		return 0;
1618
		return 0;
1616
	case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
1619
	case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
Lines 1662-1667 Link Here
1662
	set_capacity(disk, idefloppy_capacity(floppy->drive));
1665
	set_capacity(disk, idefloppy_capacity(floppy->drive));
1663
	return 0;
1666
	return 0;
1664
}
1667
}
1668
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1669
static int idefloppy_mediactl (struct block_device *bdev, int op, int optarg)
1670
{
1671
	ide_drive_t *drive = bdev->bd_disk->private_data;
1672
	idefloppy_floppy_t *floppy = drive->driver_data;
1673
	idefloppy_pc_t pc;
1674
1675
     switch (op) {
1676
             case MEDIA_LOCK:
1677
             case MEDIA_UNLOCK:
1678
                     if (op == MEDIA_UNLOCK && optarg) {
1679
                             floppy->openers--;
1680
                             if (floppy->openers < 0)
1681
                                     floppy->openers = 0;
1682
                     }
1683
                     /* IOMEGA Clik! drives do not support lock/unlock commands */
1684
                     if ((floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)
1685
                         && supermount_usage_count(bdev, floppy->openers) == 0) {
1686
                             idefloppy_create_prevent_cmd(&pc, (op == MEDIA_LOCK));
1687
                             (void) idefloppy_queue_pc_tail(drive, &pc);
1688
                     }
1689
                     if (op == MEDIA_LOCK && optarg)
1690
                             floppy->openers++;
1691
                     break;
1692
             default:
1693
                     return -EINVAL;
1694
     }
1695
     return 0;
1696
}
1697
#endif
1698
1699
1665
1700
1666
static struct block_device_operations idefloppy_ops = {
1701
static struct block_device_operations idefloppy_ops = {
1667
	.owner		= THIS_MODULE,
1702
	.owner		= THIS_MODULE,
Lines 1670-1676 Link Here
1670
	.ioctl		= idefloppy_ioctl,
1705
	.ioctl		= idefloppy_ioctl,
1671
	.getgeo		= idefloppy_getgeo,
1706
	.getgeo		= idefloppy_getgeo,
1672
	.media_changed	= idefloppy_media_changed,
1707
	.media_changed	= idefloppy_media_changed,
1673
	.revalidate_disk= idefloppy_revalidate_disk
1708
	.revalidate_disk= idefloppy_revalidate_disk,
1709
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1710
	.mediactl	= idefloppy_mediactl,
1711
#endif
1674
};
1712
};
1675
1713
1676
static int ide_floppy_probe(ide_drive_t *drive)
1714
static int ide_floppy_probe(ide_drive_t *drive)
(-)linux-2.6.25.4.orig/drivers/scsi/sr.c (+33 lines)
Lines 488-493 Link Here
488
{
488
{
489
	int ret;
489
	int ret;
490
	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
490
	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
491
	
492
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
493
	/*
494
	 * This is the same sort of clockload as use in blkdev_get.
495
	 * We need information whether device is supermounted inside
496
	 * of cdrom_release to decide if tray must be unlocked.
497
	 * This information so far is available only by looking
498
	 * up superblock but it needs struct *bdev and it is not
499
	 * available in cdrom_release anymore
500
	 */
501
	struct dentry t_dentry;
502
	struct file t_file;
503
504
	if (!file) {
505
		t_file.f_dentry = &t_dentry;
506
		t_dentry.d_inode = inode;
507
		file = &t_file;
508
	}
509
#endif
510
	
511
	
491
	ret = cdrom_release(&cd->cdi, file);
512
	ret = cdrom_release(&cd->cdi, file);
492
	if(ret)
513
	if(ret)
493
		return ret;
514
		return ret;
Lines 537-542 Link Here
537
	return cdrom_media_changed(&cd->cdi);
558
	return cdrom_media_changed(&cd->cdi);
538
}
559
}
539
560
561
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
562
static int sr_block_mediactl(struct block_device *bdev, int op, int arg)
563
{
564
	struct gendisk *disk = bdev->bd_disk;
565
	struct scsi_cd *cd = scsi_cd(disk);
566
	return cdrom_mediactl(&cd->cdi, bdev, op, arg);
567
}
568
#endif
569
540
static struct block_device_operations sr_bdops =
570
static struct block_device_operations sr_bdops =
541
{
571
{
542
	.owner		= THIS_MODULE,
572
	.owner		= THIS_MODULE,
Lines 544-549 Link Here
544
	.release	= sr_block_release,
574
	.release	= sr_block_release,
545
	.ioctl		= sr_block_ioctl,
575
	.ioctl		= sr_block_ioctl,
546
	.media_changed	= sr_block_media_changed,
576
	.media_changed	= sr_block_media_changed,
577
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
578
	.mediactl	= sr_block_mediactl,
579
#endif
547
	/* 
580
	/* 
548
	 * No compat_ioctl for now because sr_block_ioctl never
581
	 * No compat_ioctl for now because sr_block_ioctl never
549
	 * seems to pass arbitary ioctls down to host drivers.
582
	 * seems to pass arbitary ioctls down to host drivers.
(-)linux-2.6.25.4.orig/fs/block_dev.c (+35 lines)
Lines 881-891 Link Here
881
	struct gendisk *disk = bdev->bd_disk;
881
	struct gendisk *disk = bdev->bd_disk;
882
	struct block_device_operations * bdops = disk->fops;
882
	struct block_device_operations * bdops = disk->fops;
883
883
884
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
885
	struct super_block *sb = NULL;
886
	int supermounted = 0;
887
#endif
888
884
	if (!bdops->media_changed)
889
	if (!bdops->media_changed)
885
		return 0;
890
		return 0;
886
	if (!bdops->media_changed(bdev->bd_disk))
891
	if (!bdops->media_changed(bdev->bd_disk))
887
		return 0;
892
		return 0;
888
893
894
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
895
	sb = get_super(bdev);
896
	if (sb) {
897
		atomic_set(&sb->s_media_changed, 1);
898
		supermounted = sb->s_flags & MS_SUPERMOUNTED;
899
		drop_super(sb);
900
	}
901
902
	/*
903
	 * Supermount used to did invalidate_device followed by
904
	 * destroy_buffers. invalidate_device hardly does anything
905
	 * useful here as it won't really invalidate "busy" inodes
906
	 * and every inode in subfs is busy (at least one reference
907
	 * from superfs exists). So now it just flushes
908
	 * buffers so they do not accidentally overwrite newly
909
	 * inserted media
910
	 *
911
	 * FIXME unfortunately during umount VFS may write on its
912
	 * own, like write_super. Those writes will go to a wrong
913
	 * media thus corrupting it :(
914
	 *
915
	 * There is no error print because supermount warns user
916
	 * itself.
917
	 */
918
919
	if (supermounted) {
920
		invalidate_bdev(bdev);
921
	} else
922
#endif
923
889
	if (__invalidate_device(bdev))
924
	if (__invalidate_device(bdev))
890
		printk("VFS: busy inodes on changed media.\n");
925
		printk("VFS: busy inodes on changed media.\n");
891
926
(-)linux-2.6.25.4.orig/fs/ext2/super.c (+6 lines)
Lines 424-429 Link Here
424
	{Opt_usrquota, "usrquota"},
424
	{Opt_usrquota, "usrquota"},
425
	{Opt_reservation, "reservation"},
425
	{Opt_reservation, "reservation"},
426
	{Opt_noreservation, "noreservation"},
426
	{Opt_noreservation, "noreservation"},
427
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
428
	/* Silently ignore NLS options */
429
	{Opt_ignore, "iocharset"},
430
	{Opt_ignore, "codepage"},
431
	{Opt_ignore, "umask"},
432
#endif
427
	{Opt_err, NULL}
433
	{Opt_err, NULL}
428
};
434
};
429
435
(-)linux-2.6.25.4.orig/fs/isofs/inode.c (+4 lines)
Lines 345-350 Link Here
345
	{Opt_ignore, "conv=auto"},
345
	{Opt_ignore, "conv=auto"},
346
	{Opt_ignore, "conv=a"},
346
	{Opt_ignore, "conv=a"},
347
	{Opt_nocompress, "nocompress"},
347
	{Opt_nocompress, "nocompress"},
348
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
349
	{Opt_ignore, "codepage=%s"},
350
	{Opt_ignore, "umask=%s"},
351
#endif
348
	{Opt_err, NULL}
352
	{Opt_err, NULL}
349
};
353
};
350
354
(-)linux-2.6.25.4.orig/fs/Kconfig (+2 lines)
Lines 867-872 Link Here
867
867
868
menu "Pseudo filesystems"
868
menu "Pseudo filesystems"
869
869
870
source "fs/supermount/Kconfig"
871
870
config PROC_FS
872
config PROC_FS
871
	bool "/proc file system support" if EMBEDDED
873
	bool "/proc file system support" if EMBEDDED
872
	default y
874
	default y
(-)linux-2.6.25.4.orig/fs/Makefile (+1 lines)
Lines 116-121 Link Here
116
obj-$(CONFIG_BEFS_FS)		+= befs/
116
obj-$(CONFIG_BEFS_FS)		+= befs/
117
obj-$(CONFIG_HOSTFS)		+= hostfs/
117
obj-$(CONFIG_HOSTFS)		+= hostfs/
118
obj-$(CONFIG_HPPFS)		+= hppfs/
118
obj-$(CONFIG_HPPFS)		+= hppfs/
119
obj-$(CONFIG_SUPERMOUNT)	+= supermount/
119
obj-$(CONFIG_DEBUG_FS)		+= debugfs/
120
obj-$(CONFIG_DEBUG_FS)		+= debugfs/
120
obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
121
obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
121
obj-$(CONFIG_GFS2_FS)           += gfs2/
122
obj-$(CONFIG_GFS2_FS)           += gfs2/
(-)linux-2.6.25.4.orig/fs/namespace.c (+9 lines)
Lines 1438-1443 Link Here
1438
	if (retval)
1438
	if (retval)
1439
		goto dput_out;
1439
		goto dput_out;
1440
1440
1441
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1442
	if (!(flags & (MS_REMOUNT | MS_MOVE)) &&
1443
	    (nd.path.mnt->mnt_sb->s_type->fs_flags & FS_NO_SUBMNT)) {
1444
		retval = -EPERM;
1445
		path_put(&nd.path);
1446
		return retval;
1447
	}
1448
#endif
1449
1441
	if (flags & MS_REMOUNT)
1450
	if (flags & MS_REMOUNT)
1442
		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
1451
		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
1443
				    data_page);
1452
				    data_page);
(-)linux-2.6.25.4.orig/fs/super.c (-1 / +29 lines)
Lines 90-95 Link Here
90
		s->s_qcop = sb_quotactl_ops;
90
		s->s_qcop = sb_quotactl_ops;
91
		s->s_op = &default_op;
91
		s->s_op = &default_op;
92
		s->s_time_gran = 1000000000;
92
		s->s_time_gran = 1000000000;
93
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)           
94
		atomic_set(&s->s_media_changed, 0);                             
95
#endif		
93
	}
96
	}
94
out:
97
out:
95
	return s;
98
	return s;
Lines 618-623 Link Here
618
	return 0;
621
	return 0;
619
}
622
}
620
623
624
#ifdef CONFIG_SUPERMOUNT_MODULE
625
EXPORT_SYMBOL(do_remount_sb);
626
#endif
627
621
static void do_emergency_remount(unsigned long foo)
628
static void do_emergency_remount(unsigned long foo)
622
{
629
{
623
	struct super_block *sb;
630
	struct super_block *sb;
Lines 750-756 Link Here
750
		goto error_s;
757
		goto error_s;
751
758
752
	if (s->s_root) {
759
	if (s->s_root) {
753
		if ((flags ^ s->s_flags) & MS_RDONLY) {
760
		if (((flags ^ s->s_flags) & MS_RDONLY)
761
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
762
		/* disallow double mounting for supermounted device */
763
		    || ((flags | s->s_flags) & MS_SUPERMOUNTED)
764
#endif
765
		   )
766
		{
754
			up_write(&s->s_umount);
767
			up_write(&s->s_umount);
755
			deactivate_super(s);
768
			deactivate_super(s);
756
			error = -EBUSY;
769
			error = -EBUSY;
Lines 866-871 Link Here
866
		return ERR_PTR(-ENODEV);
879
		return ERR_PTR(-ENODEV);
867
880
868
	error = -ENOMEM;
881
	error = -ENOMEM;
882
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
883
	/* sanity checks; supermount relies on these assumptions */
884
	if (flags & MS_SUPERMOUNTED) {
885
		error = -EINVAL;
886
		if (type->fs_flags & FS_RENAME_DOES_D_MOVE)
887
			goto out;
888
		if (!(type->fs_flags & FS_REQUIRES_DEV))
889
			goto out;
890
		error = -ENOMEM;
891
	}
892
#endif
869
	mnt = alloc_vfsmnt(name);
893
	mnt = alloc_vfsmnt(name);
870
	if (!mnt)
894
	if (!mnt)
871
		goto out;
895
		goto out;
Lines 945-951 Link Here
945
	put_filesystem(type);
969
	put_filesystem(type);
946
	return mnt;
970
	return mnt;
947
}
971
}
972
#ifdef CONFIG_SUPERMOUNT_MODULE
973
EXPORT_SYMBOL(do_kern_mount);
974
#else
948
EXPORT_SYMBOL_GPL(do_kern_mount);
975
EXPORT_SYMBOL_GPL(do_kern_mount);
976
#endif
949
977
950
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
978
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
951
{
979
{
(-)linux-2.6.25.4.orig/fs/supermount/changelog (+462 lines)
Line 0 Link Here
1
* ? ? ? Andrey Borzenkov <arvidjaar@mail.ru> ?.?.?
2
3
* Sun 18 Jan 2004 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.4
4
5
  - yet another attempt to fix detection of USB drive removale
6
    (explicitly check for SDVE_DEL state in sd.c:sd_media_changed)
7
8
  - fixed i18n patch for ext2 and udf (ignored options)
9
10
  - ->nopage prototype changed; it makes it incompatible with
11
    kernel < 2.6.1 (I wonder how it compiled - or did I miss
12
    warning). Add comments about ->populate and why it won't be
13
    implemented
14
15
  - fix "auto" option. Simplification of option processing turned
16
    out to be a mess :( Reported by Bart
17
18
* Mon 12 Jan 2004 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.3b
19
20
  - Fix compilation problem in subfs.c with older GCC - declaration
21
    after statement in clear_inodes(bug 875009). Pointed by Adrian Punga.
22
23
* Wed 07 Jan 2004 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.3a
24
25
  - fix Oops during options parsing if no subfs option is
26
    given after "--" (bug 869863)
27
28
* Mon 29 Dec 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.3
29
30
  - move test for device offline in sd.c to the top in attempt
31
    to fix USB removale problem
32
33
  - simplify options procesing
34
35
  - remove cdrom "open failed" message (it is now under
36
    CDROM_OPEN flag like all others in cdrom_open).
37
38
  - rewrote option parsing to use new lib/parse library
39
40
* Sun 26 Oct 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.2a
41
42
  - remove some obsolete files that are not used anymore from CVS
43
    (i.e. from patch)
44
45
  - isofs needs extra ignored options now. It rurns out it silently
46
    ignored any unknown option before new and shiny option parsing
47
    code
48
49
  - consistently use "kernel 2.6" in version print
50
51
  - updates for -test8. Change ext2/udf patches to match new options
52
    parsing code.
53
54
* Wed 10 Sep 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.2
55
56
  - NODEV is gone, use MKDEV(UNNAMED_MAJOR, 0) instead, it is just
57
    as good as anything else
58
59
* Sat 23 Aug 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.1d
60
61
  - rediff against 2.6.0-test4
62
63
* Mon 18 Aug 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.1c
64
65
  - fix compilation without CONFIG_SUPERMOUNT. Reported by
66
    Igor Strygin
67
68
* Sun 10 Aug 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.1b
69
70
  - /proc/fs/supermount/version is read-only, do not set permissions to
71
    rw
72
73
  - remove generic_unplug_queue from ide_do_drive_cmd, apparently
74
    it is redundant now (fixes bug 785691)
75
76
  - rediff for 2.6.0-test3
77
78
* Sun 27 Jul 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.1a
79
80
  - rediff for 2.6.0-test2
81
82
* Sun 13 Jul 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.1
83
84
  - hush most unused variables warnings with CONFIG_DEBUG (idea
85
    suggested by Jeff Garzik)
86
87
  - replace ugly SUPERMOUNT_TARCE_{ENTER,LEAVE}[_ARGS] with ENTER/LEAVE
88
    Use %p throughout for pointer output.
89
90
  - send DN_CREATE for root on mount
91
92
  - allow open and readdir on mountpoint even if subfs is unmounted.
93
    This provides for active monitoring by FAM/dnotify and is overall
94
    less surprising - ls /mnt/cdrom just returns empty directory now
95
    instead of error. For technical reasons ->flush and ->permissions
96
    need be aware about it too.
97
98
    Files opened while subfs is unmounted are NOT usable for anything
99
    except readdir even AFTER subfs gets mounted. So application
100
    has to reopen directory to rescan it. AFAIK all of them do it :)
101
102
* Sat 12 Jul 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.0a
103
104
  - add struct nameidata * goes into d_revalidate as well
105
106
  - add struct nameidata * to some inode methods (introduced in
107
    2.5.75). Currently it is just passed along - it is not clear if
108
    local subfs-specific nameidata has to be constructed. Apparently
109
    it existed in follow_link all the time without any evil done.
110
111
  - fix small races in supermount_getattr - do not attempt to
112
    get subdent if prevent_umount failed
113
114
* Mon 23 Jun 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.0
115
116
  - added ->getattr; it never fails on both unmounted mountpoint
117
    and stale open files - to ensure fuser -m /mnt/cdrom still finds them
118
119
  - merge 2.5.73; update sd.c to new refcount interface in sd.c
120
121
  - fix SUPERMOUNT_BUG_ON_LOCKED without SUPERMOUNT_DEBUG
122
123
  - add media management to ide-floppy and those CD-ROM drivers that
124
    are using standard cdrom_* calls (cdu31a, cm206, mcd, mcdx, sbpcd).
125
    Testdrive revealed that none of them builds for other reasons :)
126
127
  - add (un)mark_media_supermounted; mark after mount, unmark
128
    before umount. These functions just manipulate bd_disk->scount
129
130
  - add scount to struct gendisk to serve as count of total
131
    supermounted partitions; use everywhere to check if device
132
    is supermounted
133
134
* Tue 17 Jun 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.0test2
135
136
  - update kernel patch for 2.5.72 (there was a reject in
137
    drivers/ide/ide-io.c)
138
139
  - move init_inode_info into alloc_inode; use iget_locked
140
    instead of iget to skip ->read_inode with intent to move
141
    inode init under if (inode->i_state & I_NEW)
142
143
  - polish dentry.c a bit while I am on it
144
145
  - ->d_compare is not run under dcache_lock anymore. Pointed by
146
    Maneesh Soni. As we can't sleep in d_compare, use rwlock to
147
    protect against races with supermount_clean_dentries until
148
    I find better solution.
149
150
  - remove new_subfs_dentry - it is not used anymore and comments
151
    there were wrong anyway
152
153
* Sun 01 Jun 2003 Andrey Borzenkov <arvidjaar@mail.ru> 2.0.0test1
154
155
  - add sr and sd support
156
157
  - update sb s_blocksize and s_blocksize_bits on subfs mount
158
159
  - use BKL around chek_disk_change; it is not garanteed by VFS now
160
161
  - llseek no more updates file readahead pointer
162
163
  - used bdev not gendisk in mediactl - it needs it for
164
    supermount_usage_count. It probably needs redesign. Also some minor
165
    changes on the way.
166
167
  - 2.5 changes. supermount_get_sb, inode alloc/dealloc, use bdev instead
168
    of dev, Makefile change, add CONFIG_SUPERMOUNT_DEBUG, do_remount_sb
169
    prototype change, mknod prototype change, UPDATE_ATIME dead,
170
    dnotify_parent is now true function
171
172
* Tue 27 May 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.7
173
174
  - (re-)set root inode flags after unmounting subfs
175
176
  - fix mounting of ro media on rw filesystem. It was broken  by fix
177
    in 1.2.4. Remove saved s_mflags and just use real sb->s_flags.
178
    Reported by Con Kolivas
179
    
180
  - do not use MS_MGC_VAL in subfs_real_mount - it is not used anywhere
181
    in kernel and all lower bits are already taken in 2.5
182
183
  - configure help from Marc-Christian Petersen
184
185
  - use subsb->s_bdev instead of looking up using s_dev. This also
186
    fixes problem with O(1) patch (bug 737783)
187
188
* Wed 14 May 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.6
189
190
  - check for correct inode in attach_subfs_inode - if super inode
191
    has subinode attached it must be the same as is currently
192
    resuested. Else it is a bug.
193
194
  - use lookup_one_len to lookup subfs dentry in cache; check if
195
    subfs did not change name and lookup "real" dentry in parent
196
    cache in this case. This finally puts an end to the attempt to
197
    control subfs dcache. The only thing we rely upon now is that
198
    nothing can change directory contents while in lookup method.
199
200
  - implement d_hash and d_compare to properly support case-
201
    insensitive filesystems (vfat & Co).
202
  
203
  - reset super inode i_mapping so it does not point to freed
204
    subinode mapping when unmounting subfs
205
206
  - send dnotify_parent on dentry cleanup, not on inode
207
208
  - use write_inode_now in ->write_inode. Reading intricated flags
209
    manipulations in fs/inode.c was just too intimidating. It is not as
210
    much overhead as it looks like - it is called from sync_one only
211
    so all dirty pages are scheduled to be flushed anyway.
212
213
* Sun 04 May 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.5
214
215
  - enable dentries caching; properly use d_add when dentry is first
216
    looked up and d_instantiate when inode is finally available.
217
218
  - first stab at sending notifications on media umount/mount
219
220
  - more caveats :(
221
222
* Sat 26 Apr 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.4
223
224
  - fix write_inode/prepare_inode deadlock. It looked like
225
  	set I_LOCK
226
			down(&sbi->sem);
227
			iget4 -> wait_on_inode
228
	down(&sbi->sem)
229
230
  - MS_ACTIVE was reset on subfs remount
231
232
  - print process PID in trace
233
234
  - adjust directory structure to make patch generation easier
235
236
* Sun 20 Apr 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.3
237
238
  - dummy version due to script problems
239
240
* Sun 20 Apr 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.2
241
  
242
  - remove #ifdef CONFIG_PROC_FS from init.c, it already exists in
243
    supermount.h
244
245
  - no_tray_lock -> TRAY_LOCK_NEVER. Just to make sure it remains
246
    compatible (even if it is very unlikely anybody is using it).
247
248
  - backout kernel stat patch; remove getattr alltogether. It fixed
249
    fuser -m for stale files. getattr remains uniplemented because
250
    it does not seem to be used anywhere in kernel at all so I am not
251
    actually sure how to implement it
252
253
    It also backouts 10_readlik and 30_lseek as they are not used
254
    anymore for a long time.
255
256
  - remove bogus check for sub- and superinodes i_count. i_count is
257
    outside of supermount control; the only thing that we must be
258
    sure in - inode is free on umount.
259
260
  - reset root inode attributes and operations on umount. This fixes
261
    the problem of attempt to mount media on ls -l /mnt after subfs
262
    has been mounted once.
263
264
  - remove ->stale. For all practical purposes an entity is stale iff
265
    it does not (yet) have associated subfs entity. Creating yet another
266
    field that just mirrors this condition does not add a single bit
267
    of useful information.
268
269
  - subfs_is_busy iff subfs mnt_count > 1
270
271
* Sat 05 Apr 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.1
272
273
  - fixed stupid thinko in mediactl methods (the effect was it was
274
    impossible to manually eject ro media). It was exposed by recent
275
    changes. No changes in supermount itself only in driver code
276
277
  - replace no_tray_lock with tray_lock={never,onwrite,always} with
278
    "onwrite" being default. I stil do not quite like resulting code
279
    but it will do for now.
280
281
  - simplified subfs_(get|put)_(write|read) interface; merge both
282
    read/write in one function; remove subfs_get_atime. To my surprise
283
    it resulted on more clean interface in the rest of supermount even
284
    if subfs_(get|put)_access does look a bit weird.
285
286
* Sun 30 Mar 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.2.0
287
288
  - changed proc command format to
289
    <devname> [enable|disable] [release [force]]
290
291
  - add /proc/fs/supermount/version; printk version on starup only
292
    if procfs is not configured.
293
294
  - unify media lock rules for thosed drivers using implementing
295
    mediactl (cdrom, sd, ide-floppy as of this writing). Lock
296
    media for both manual and software eject; do not unlock media
297
    that is in used by something else.
298
299
  - added show_options method to super.c
300
301
  - implemented /proc/fs/supermount/subfs read as seq_file
302
303
* Sat 29 Mar 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.1.4
304
305
  - supermount_rename leftover - it does not need new_subfs_dentry.
306
    It still worked because new dentry was destroyed immediately, but
307
    let's do it the right way. Also mark target rw if exists
308
309
  - propagate S_IMMUTABLE, S_NOATIME and S_APPEND flags from subfs
310
    to super inode. Filesystems usually rely on VFS to check these
311
    flags which means it was possible to overwrite immutable file. Also
312
    needed for atime management (to be added).
313
314
  - added atime management. It is based on grep UPDATE_ATIME so it may
315
    be incomplete; still it gives right results in most obvious cases :)
316
    It respects no(dir)atime mount flag.
317
318
  - Make sure super inode times and sizes are updated to reflect subfs
319
    inode. Done in preparation to remove stat kernel patch. Only those
320
    fields needed by stat are updated.
321
322
  - remove assertion subi->i_count == 1 from clear_inode. Subfs icache
323
    is managed independently and there is no lock (as opposed to dentry
324
    case where we never do cached lookup for subfs).
325
326
  - use inode cache for supermount inodes to avoid linear search. This
327
    moves almost the whole inode creation task into read_inode2 - the
328
    only place where inode needs to be created is root inode.
329
330
    We use inode numbers from subfs; root inode is never cached until
331
    subfs has been mounted. Stale inodes are removed from cache in
332
    clean_inodes (just like dentries are in clean_dentries) so aliasing
333
    problem is solved.
334
335
  - add "disabled" state - prevent any attempt to mount media
336
337
  - add procfs support. Reading /proc/fs/supermount/subfs will return
338
    list of subfs and their status. Writing into it allows you to
339
    control status of subfs (mounted/unmounted, enabled/dusabled)
340
341
  - fix race in clear_inode. It was possible that subfs was umounted
342
    after inode has been removed from list but before its access
343
    counters were cleared. The code that checkes for that exists only
344
    for debugging still I'd like it to be useful.
345
346
* Sun 16 Mar 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.1.3
347
348
  - add CVS verion Id's to files
349
350
  - finally get rid of ugly generation number. It is enough to just
351
    mark entity obsolete; we do not care actually when it happened.
352
    Now every entity starts out stale; stale flag is reset when subfs
353
    object is attached; stale flag is set again for the rest of life
354
    in subfs_umount
355
356
  - as a side effect read/write count is associated with inodes
357
    exclusively
358
359
  - clear_inode and d_iput need prevent/allow umount to avoid "stealing"
360
    subfs while holding active entities. File release is safe as VFS does
361
    nou put mnt until _release is finished.
362
363
  - subfs_prevent_umount does not need validator. The worst thing that
364
    can happen is that newly mounted subfs is accessed. That does not
365
    matter, access to subfs object is checked for validity separately in
366
    every case.
367
368
  - finally clarify dcache management. As we cannot garantee coherency
369
    between sub- and super- fs caches we ignore subfs cache entirely.
370
    Super dentry is instantiated in supermount_lookup and passed around
371
    with subfs dentry attached. It does not matter if it is positive or
372
    negative. Currently dentries are forced to be deleted in
373
    supermount_d_delete but I believe it is not really needed.
374
375
  - print version number on registering filesystem to facilitate debugging
376
377
  - umount subfs as soon as possible in check_disk_change. This eliminates
378
    zombie state (mounted but inactive due to media change detected).
379
380
  - kill subfs_is_active, it is the same as subfs_is_mounted now.
381
382
  - kill translations.c it does not do anything special now; move functions
383
    in file/dentry/namei
384
385
  - fix stupid bug in get_supermount_inode again - super inode must
386
    be inited and attached just once not every time.
387
    Praise assertions again :)
388
389
* 10 Mar 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.1.2
390
391
  - allow fs=type1:type2:...
392
393
  - remove supermount_drop_dentries (no more used)
394
395
  - add some more assertions to subfs_umount
396
397
* 10 Mar 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.1.1
398
399
  - fix stupid bug in subfs inode refcounting. It was visible with
400
    hardlinks only so CD-ROM users would not ever see it.
401
402
  - fix even more stupid bug in unlink - subi was used instead of superi
403
404
* 8 Mar 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.1.0
405
406
  - files cannot use inode obsolete flag - it does not work for
407
    root inodes
408
409
  - make file system structure exact mirror of subfs - now there
410
    is 1-to-1 correspondence between super- and subfs files, dentries
411
    and inodes. This is needed to properly manage write access without
412
    too much locking
413
414
  - finally realized that subfs cannot be obsolete; use either file
415
    or inode pointer in all calls into subfs.c to check for freshness
416
417
  - debug is now per-mount; added trace of all functions
418
  
419
  - move setting of SUPERMOUNT_DEBUG to Makefile instead of supermount_i.h
420
421
* 1 Mar 2003 Andrey Borzenkov <arvidjaar@mail.ru> 1.0.0
422
423
  - make sure it is always possible umount subfs. It does it by
424
    keeping list of opened files (in addition to inodes) and closing
425
    them if media change is detected.
426
427
  - make sure subfs can't go away while it is being in use. For
428
    files it get_file for subfile to ensure subfs mnt is not freed. For
429
    inode operation it increments usage counter of submnt for duration
430
    of operation.
431
432
  - make sure supermounted device can't be mounted twice (that is
433
    allowed by kernel) because it relies on being the only "owner" of
434
    subfs. It does it by checking for MS_SUPERMOUNTED flag on mount.
435
436
  - make sure you can't mount over supermounted directory. Allowing
437
    it is a nightmare and I cannot see any reason for it (if you can
438
    provide valid one - I may reconsider this part). It does so by
439
    adding fstype flag and checking it on mounting.
440
441
  - reject mount -o remount for the time being (until we can deal
442
    with it properly)
443
444
  - completely change implementation of individual inode methods.
445
    Instead of calling VFS recursively it calls subfs methods directly.
446
    It is to ensure we are in full control of subfs (assuming it behaves
447
    properly :)
448
449
  - properly implement VM methods. Currently changing media would
450
    leave you with vm_area pointing to no more existing inode ...
451
452
  - remove many obsolete pieces like flags that just duplicate
453
    existing information.
454
455
  - ensure coherency between super- and subfs dentries. Either we
456
    have both active in dcache or do not have them at all.
457
458
  - fixe the problem with media ejection after direct access to CD-ROM
459
460
  - add "just disc change" to all operations to detect media change
461
    as soon as possible. It is possible to add option to do it just
462
    for writable media or to completely turn it off.
(-)linux-2.6.25.4.orig/fs/supermount/dentry.c (+282 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/dentry.c
3
 *
4
 *  Original version:
5
 *      Copyright (C) 1995
6
 *      Stephen Tweedie (sct@dcs.ed.ac.uk)
7
 *
8
 *  Rewriten for kernel 2.2 & 2.4. (C) 1999, 2000 Alexis Mikhailov
9
 *                                    (alexis@abc.cap.ru)
10
 *  Rewritten for kernel 2.4.21 (C) 2003 Andrey Borzenkov
11
 *                                       (arvidjaar@mail.ru)
12
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
13
 *                                       (arvidjaar@mail.ru)
14
 *
15
 *  $Id: dentry.c,v 1.9.2.3 2003/07/13 14:52:43 bor Exp $
16
 */
17
18
#define S_DBG_TRACE_CURRENT S_DBG_TRACE_DENTRY
19
#include "supermount.h"
20
21
int
22
init_dentry_info(struct dentry *dentry)
23
{
24
	struct super_block *sb = dentry->d_sb;
25
	struct supermount_dentry_info *sdi;
26
	int rc;
27
28
	ENTER(sb, "dentry=%s", dentry->d_name.name);
29
30
	rc = 1;
31
	sdi = kmalloc(sizeof(*sdi), GFP_KERNEL);
32
	if (!sdi)
33
		goto out;
34
35
	memset(sdi, 0, sizeof(*sdi));
36
37
	INIT_LIST_HEAD(&sdi->list);
38
	sdi->dentry = 0;
39
	sdi->host = dentry;
40
	
41
	dentry->d_fsdata = sdi;
42
	dentry->d_op = &supermount_dops;
43
44
	rc = 0;
45
out:
46
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
47
48
	return rc;
49
50
}
51
52
void
53
attach_subfs_dentry(struct dentry *dentry, struct dentry *subdent)
54
{
55
	struct super_block *sb = dentry->d_sb;
56
	struct supermount_sb_info *sbi = supermount_sbi(sb);
57
	struct supermount_dentry_info *sdi;
58
59
	ENTER(sb, "dentry=%s subd=%p", dentry->d_name.name, subdent);
60
61
	sdi = supermount_d(dentry);
62
	SUPERMOUNT_BUG_LOCKED_ON(sb, sdi->dentry);
63
	sdi->dentry = dget(subdent);
64
	list_add(&sdi->list, &sbi->s_dentries);
65
66
	LEAVE(sb, "dentry=%s", dentry->d_name.name);
67
}
68
69
70
struct dentry *
71
get_subfs_dentry(struct dentry *dentry)
72
{
73
	struct super_block *sb = dentry->d_sb;
74
	struct dentry *err;
75
	struct supermount_dentry_info *sdi = supermount_d(dentry);
76
77
	ENTER(sb, "dentry=%s", dentry->d_name.name);
78
79
	subfs_lock(sb);
80
81
	err = ERR_PTR(-ENOMEDIUM);
82
	if (!subfs_is_mounted(sb))
83
		goto out;
84
85
	err = ERR_PTR(-ESTALE);
86
	if (is_dentry_obsolete(dentry))
87
		goto out;
88
89
	err = dget(sdi->dentry);
90
	SUPERMOUNT_BUG_LOCKED_ON(sb, !err);
91
	SUPERMOUNT_BUG_LOCKED_ON(sb, (dentry->d_inode == 0) ^ (err->d_inode == 0));
92
93
out:
94
	subfs_unlock(sb);
95
96
	LEAVE(sb, "dentry=%s subd=%p", dentry->d_name.name, err);
97
98
	return err;
99
}
100
101
static int
102
supermount_d_revalidate(struct dentry *dentry, struct nameidata *nd)
103
{
104
	struct super_block *sb = dentry->d_sb;
105
	struct dentry *subd;
106
	int rc;
107
	struct vfsmount *mnt;
108
109
	ENTER(sb, "dentry=%s", dentry->d_name.name);
110
111
	rc = 0;
112
	mnt = subfs_prevent_umount(sb);
113
	if (!mnt)
114
		goto out;
115
	
116
	subd = get_subfs_dentry(dentry);
117
118
	if (IS_ERR(subd))
119
		goto allow_umount;
120
121
	rc = 1;
122
	/* FIXME do we need to build proper subfs nd? */
123
	if (subd->d_op && subd->d_op->d_revalidate)
124
		rc = subd->d_op->d_revalidate(subd, nd);
125
126
	dput(subd);
127
allow_umount:
128
	subfs_allow_umount(sb, mnt);
129
out:
130
131
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
132
133
	return rc;
134
}
135
136
static int
137
supermount_d_hash(struct dentry *dentry, struct qstr *name)
138
{
139
	struct super_block *sb = dentry->d_sb;
140
	struct dentry *subd;
141
	int rc;
142
	struct vfsmount *mnt;
143
144
	ENTER(sb, "dentry=%s name=%s", dentry->d_name.name, name->name);
145
146
	rc = -ENOMEDIUM;
147
	mnt = subfs_prevent_umount(sb);
148
	if (!mnt)
149
		goto out;
150
	
151
	subd = get_subfs_dentry(dentry);
152
	rc = PTR_ERR(subd);
153
	if (IS_ERR(subd))
154
		goto allow_umount;
155
156
	rc = 0;
157
	if (subd->d_op && subd->d_op && subd->d_op->d_hash)
158
		rc = subd->d_op->d_hash(subd, name);
159
160
	dput(subd);
161
allow_umount:
162
	subfs_allow_umount(sb, mnt);
163
out:
164
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
165
166
	return rc;
167
}
168
169
170
rwlock_t d_compare_lock = RW_LOCK_UNLOCKED;
171
172
static int
173
supermount_d_compare(struct dentry *dentry, struct qstr *name1, struct qstr *name2)
174
{
175
	struct super_block *sb = dentry->d_sb;
176
	struct supermount_dentry_info *sdi;
177
	struct dentry *subd;
178
	int rc;
179
180
	ENTER(sb, "dentry=%s name1=%s name2=%s", dentry->d_name.name, name1->name, name2->name);
181
182
	rc = 1; /* fail by default */
183
	sdi = dentry->d_fsdata;
184
	SUPERMOUNT_BUG_ON(!sdi);
185
186
	/*
187
	 * HACK - FIXME
188
	 * this protects against races with supermount_clean_dentries
189
	 * I cannot use blocking calls (i.e. sbi->sem) here and it is not
190
	 * protected by dcache_lock anymore
191
	 */
192
	read_lock(&d_compare_lock);
193
	subd = sdi->dentry;
194
	if (!subd) {
195
		read_unlock(&d_compare_lock);
196
		goto out;
197
	}
198
199
	if (subd->d_op && subd->d_op->d_compare)
200
		rc = subd->d_op->d_compare(subd, name1, name2);
201
	else { /* based on fs/dcache.c:d_lookup */
202
		if (name1->len == name2->len)
203
		     rc = memcmp(name1->name, name2->name, name1->len);
204
	}
205
	read_unlock(&d_compare_lock);
206
207
out:
208
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
209
	return rc;
210
}
211
212
static inline void
213
handle_subdent(struct dentry *dentry)
214
{
215
	struct super_block *sb = dentry->d_sb;
216
	struct vfsmount *mnt;
217
	struct supermount_dentry_info *sdi = supermount_d(dentry);
218
	struct dentry *subd = 0;
219
220
	mnt = subfs_prevent_umount(sb);
221
	if (!mnt)
222
		goto out;
223
224
	subfs_lock(sb);
225
	if (sdi) {
226
		subd = sdi->dentry;
227
		list_del_init(&sdi->list);
228
		sdi->dentry = 0;
229
	}
230
	subfs_unlock(sb);
231
232
	if (subd)
233
		dput(subd);
234
235
	subfs_allow_umount(sb, mnt);
236
out:
237
	return;
238
}
239
240
/*
241
 * in case of active dentry we must be sure subfs dentry is released
242
 * before subfs inode to correctly maintain write state
243
 */
244
static void
245
supermount_d_iput(struct dentry *dentry, struct inode *inode)
246
{
247
	struct super_block *sb = dentry->d_sb;
248
249
	ENTER(sb, "dentry=%s inode=%p", dentry->d_name.name, inode);
250
251
	handle_subdent(dentry);
252
	iput(inode);
253
254
	LEAVE(sb, "dentry=%s", dentry->d_name.name);
255
}
256
	
257
258
/*
259
 * this duplicated code is due to the lack of common "destroy" method
260
 * for both negative and positive dentries
261
 */
262
static void
263
supermount_d_release(struct dentry *dentry)
264
{
265
	struct super_block *sb = dentry->d_sb;
266
	struct supermount_dentry_info *sdi = supermount_d(dentry);
267
268
	ENTER(sb, "dentry=%s", dentry->d_name.name);
269
270
	handle_subdent(dentry);
271
	kfree(sdi);
272
273
	LEAVE(sb, "dentry=%s", dentry->d_name.name);
274
}
275
276
struct dentry_operations supermount_dops = {
277
	.d_revalidate	= supermount_d_revalidate,
278
	.d_hash		= supermount_d_hash,
279
	.d_compare	= supermount_d_compare,
280
	.d_iput		= supermount_d_iput,
281
	.d_release	= supermount_d_release,
282
};
(-)linux-2.6.25.4.orig/fs/supermount/file.c (+690 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/file.c
3
 *
4
 *  Original version:
5
 *      Copyright (C) 1995, 1997
6
 *      Stephen Tweedie (sct@dcs.ed.ac.uk)
7
 *
8
 *      from
9
 *
10
 *      linux/fs/minix/dir.c
11
 *      Copyright (C) 1991, 1992  Linus Torvalds
12
 *
13
 *      and
14
 *
15
 *      linux/fs/ext2/dir.c
16
 *      Copyright (C) 1992, 1993, 1994, 1995  Remy Card
17
 *
18
 *  Rewriten for kernel 2.2 & 2.4. (C) 1999, 2000 Alexis Mikhailov
19
 *                                    (alexis@abc.cap.ru)
20
 *  Rewriten for kernel 2.4. (C) 2001 MandrakeSoft Inc.
21
 *                                    Juan Quintela (quintela@mandrakesoft.com)
22
 *  Rewritten for kernel 2.4.21 (C) 2003 Andrey Borzenkov
23
 *                                       (arvidjaar@mail.ru)
24
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
25
 *                                       (arvidjaar@mail.ru)
26
 *
27
 *  $Id: file.c,v 1.13.4.4 2003/07/13 14:52:43 bor Exp $
28
 */
29
30
#define S_DBG_TRACE_CURRENT S_DBG_TRACE_FILE
31
#include "supermount.h"
32
33
#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
34
35
static inline int
36
init_file_info(struct file *file, unsigned int fake)
37
{
38
	struct super_block *sb = file->f_dentry->d_sb;
39
	struct supermount_file_info *sfi;
40
	int rc;
41
42
	ENTER(sb, "file=%p fake=%d", file, fake);
43
44
	rc = 1;
45
	sfi = kmalloc(sizeof(*sfi), GFP_KERNEL);
46
	if (!sfi)
47
		goto out;
48
49
	memset(sfi, 0, sizeof(*sfi));
50
51
	INIT_LIST_HEAD(&sfi->list);
52
	sfi->host = file;
53
	sfi->owner = current->pid;
54
	sfi->vm_ops = 0;
55
	sfi->file = 0;
56
	sfi->fake = fake;
57
	
58
	file->f_supermount = sfi;
59
60
	rc = 0;
61
out:
62
	LEAVE(sb, "file=%p fake=%d rc=%d", file, fake, rc);
63
64
	return rc;
65
}
66
67
static inline void
68
attach_subfs_file(struct file *file, struct file *subfile)
69
{
70
	struct super_block *sb = file->f_dentry->d_sb;
71
	struct supermount_sb_info *sbi = supermount_sbi(sb);
72
	struct supermount_file_info *sfi;
73
74
	ENTER(sb, "file=%p subfile=%p", file, subfile);
75
76
	sfi = supermount_f(file);
77
	sfi->file = subfile;
78
	list_add(&sfi->list, &sbi->s_files);
79
80
	LEAVE(sb, "file=%p subfile=%p", file, subfile);
81
}
82
83
static inline int
84
prepare_file(struct file *file, struct file *subfile)
85
{
86
	struct super_block *sb = file->f_dentry->d_sb;
87
	int rc;
88
89
	ENTER(sb, "file=%p subfile=%p", file, subfile);
90
91
	subfs_lock(sb);
92
93
	rc = -ENOMEDIUM;
94
	if (!subfs_is_mounted(sb))
95
		goto out;
96
97
	rc = -ESTALE;
98
	if (is_dentry_obsolete(file->f_dentry))
99
		goto out;
100
101
	rc = -ENOMEM;
102
	if (init_file_info(file, 0))
103
		goto out;
104
105
	attach_subfs_file(file, subfile);
106
	rc = 0;
107
108
out:
109
	subfs_unlock(sb);
110
111
	LEAVE(sb, "file=%p subfile=%p", file, subfile);
112
113
	return rc;
114
}
115
116
struct file *
117
get_subfs_file(struct file *file)
118
{
119
	struct super_block *sb = file->f_dentry->d_sb;
120
	struct supermount_file_info *sfi = supermount_f(file);
121
	struct file *err;
122
123
	ENTER(sb, "file=%p", file);
124
125
	subfs_lock(sb);
126
	
127
	err = ERR_PTR(-ENOMEDIUM);
128
	if (!subfs_is_mounted(sb))
129
		goto out;
130
131
	err = ERR_PTR(-ESTALE);
132
	if (is_file_fake(file) || is_file_obsolete(file))
133
		goto out;
134
135
	err = sfi->file;
136
	SUPERMOUNT_BUG_LOCKED_ON(sb, !err->f_dentry);
137
	SUPERMOUNT_BUG_LOCKED_ON(sb, !err->f_dentry->d_inode);
138
	get_file(err);
139
140
out:
141
	subfs_unlock(sb);
142
143
	LEAVE(sb, "file=%p subfile=%p", file, err);
144
145
	return err;
146
}
147
148
static loff_t
149
supermount_llseek(struct file *file, loff_t offset, int origin)
150
{
151
	struct super_block *sb = file->f_dentry->d_sb;
152
	struct file *subfile;
153
	loff_t rc;
154
155
	ENTER(sb, "file=%p offset=%lld origin=%d", file, offset, origin);
156
157
	rc = -ESTALE;
158
	if (subfs_check_disk_change(sb))
159
		goto out;
160
161
	subfile = get_subfs_file(file);
162
	rc = PTR_ERR(subfile);
163
	if (IS_ERR(subfile))
164
		goto out;
165
166
	if (subfile->f_op && subfile->f_op->llseek)
167
		rc = subfile->f_op->llseek(subfile, offset, origin);
168
	else
169
		rc = default_llseek(subfile, offset, origin);
170
	file->f_pos = subfile->f_pos;
171
	file->f_version = subfile->f_version;
172
173
	fput(subfile);
174
out:
175
	LEAVE(sb, "file=%p rc=%lld", file, rc);
176
177
	return rc;
178
}
179
180
static ssize_t
181
supermount_read(struct file *file, char *buf, size_t count, loff_t * ppos)
182
{
183
	struct super_block *sb = file->f_dentry->d_sb;
184
	struct inode *inode = file->f_dentry->d_inode;
185
	struct file *subfile;
186
	int write_on = NEED_WRITE_ATIME(inode);
187
	int rc;
188
189
	ENTER(sb, "file=%p", file);
190
191
	rc = -ESTALE;
192
	if (subfs_check_disk_change(sb))
193
		goto out;
194
195
	subfile = get_subfs_file(file);
196
	rc = PTR_ERR(subfile);
197
	if (IS_ERR(subfile))
198
		goto out;
199
200
	rc = -EINVAL;
201
	if (!subfile->f_op || !subfile->f_op->read)
202
		goto put_subfile;
203
204
	rc = subfs_get_access(inode, write_on);
205
	if (rc)
206
		goto put_subfile;
207
208
	rc = subfile->f_op->read(subfile, buf, count, ppos);
209
	subfs_put_access(inode, write_on);
210
	if (rc < 0)
211
		goto put_subfile;
212
213
	inode->i_atime = subfile->f_dentry->d_inode->i_atime;
214
215
	if (rc > 0)
216
		file->f_pos = subfile->f_pos = *ppos;
217
218
put_subfile:
219
	fput(subfile);
220
out:
221
	LEAVE(sb, "file=%p rc=%d", file, rc);
222
223
	return rc;
224
}
225
226
static ssize_t
227
supermount_write(struct file *file, const char *buf,
228
		 size_t count, loff_t * ppos)
229
{
230
	struct super_block *sb = file->f_dentry->d_sb;
231
	struct file *subfile;
232
	int rc;
233
234
	ENTER(sb, "file=%p", file);
235
236
	rc = -ESTALE;
237
	if (subfs_check_disk_change(sb))
238
		goto out;
239
240
	subfile = get_subfs_file(file);
241
	rc = PTR_ERR(subfile);
242
	if (IS_ERR(subfile))
243
		goto out;
244
245
	rc = 0;
246
	if (subfile->f_op && subfile->f_op->write)
247
		rc = subfile->f_op->write(subfile, buf, count, ppos);
248
	if (rc > 0) {
249
		struct inode *subinode = subfile->f_dentry->d_inode;
250
251
		file->f_pos = subfile->f_pos = *ppos;
252
		file->f_mode = subfile->f_mode;
253
		file->f_dentry->d_inode->i_size = subinode->i_size;
254
		file->f_dentry->d_inode->i_blocks = subinode->i_blocks;
255
		file->f_dentry->d_inode->i_mode = subinode->i_mode;
256
		file->f_dentry->d_inode->i_ctime = subinode->i_ctime;
257
		file->f_dentry->d_inode->i_mtime = subinode->i_mtime;
258
	}
259
260
	fput(subfile);
261
out:
262
	LEAVE(sb, "file=%p rc=%d", file, rc);
263
264
	return rc;
265
}
266
267
int
268
supermount_readdir(struct file *file, void *buf, filldir_t fill_fn)
269
{
270
	struct super_block *sb = file->f_dentry->d_sb;
271
	struct inode *inode = file->f_dentry->d_inode;
272
	struct file *subfile;
273
	int write_on = NEED_WRITE_ATIME(inode);
274
	int fake_readdir = 1;
275
	int rc;
276
277
	ENTER(sb, "file=%p", file);
278
279
	rc = -ESTALE;
280
	if (subfs_check_disk_change(sb))
281
		goto out;
282
283
	subfile = get_subfs_file(file);
284
	rc = PTR_ERR(subfile);
285
	if (IS_ERR(subfile))
286
		goto out;
287
288
	rc = -ENOTDIR;
289
	if (!subfile->f_op || !subfile->f_op->readdir)
290
		goto put_subfile;
291
292
	rc = subfs_get_access(inode, write_on);
293
	if (rc)
294
		goto put_subfile;
295
296
	/* FIXME should it go before get_access? */
297
	fake_readdir = 0;
298
	rc = subfile->f_op->readdir(subfile, buf, fill_fn);
299
	subfs_put_access(inode, write_on);
300
	if (rc)
301
		goto put_subfile;
302
303
	inode->i_atime = subfile->f_dentry->d_inode->i_atime;
304
	file->f_pos = subfile->f_pos;
305
306
put_subfile:
307
	fput(subfile);
308
out:
309
	if (fake_readdir && is_file_fake(file)) {
310
		/* cf. supermount_open */
311
		rc = 0;
312
	}
313
	LEAVE(sb, "file=%p rc=%d fpos=%lld", file, rc, file->f_pos);
314
315
	return rc;
316
}
317
318
static unsigned int
319
supermount_poll(struct file *file, struct poll_table_struct *table)
320
{
321
	struct super_block *sb = file->f_dentry->d_sb;
322
	struct file *subfile;
323
	int rc;
324
325
	ENTER(sb, "file=%p", file);
326
327
	rc = -ESTALE;
328
	if (subfs_check_disk_change(sb))
329
		goto out;
330
331
	subfile = get_subfs_file(file);
332
	rc = PTR_ERR(subfile);
333
	if (IS_ERR(subfile))
334
		goto out;
335
336
	rc = DEFAULT_POLLMASK;
337
	if (subfile->f_op && subfile->f_op->poll)
338
		rc = subfile->f_op->poll(subfile, table);
339
340
	fput(subfile);
341
out:
342
	LEAVE(sb, "file=%p rc=%d", file, rc);
343
344
	return rc;
345
}
346
347
static int
348
supermount_ioctl(struct inode *inode, struct file *file,
349
		 unsigned int cmd, unsigned long arg)
350
{
351
	struct super_block *sb = file->f_dentry->d_sb;
352
	struct file *subfile;
353
	struct inode *subinode;
354
	int rc;
355
356
	ENTER(sb, "file=%p cmd=%u arg=%lu", file, cmd, arg);
357
358
	rc = -ESTALE;
359
	if (subfs_check_disk_change(sb))
360
		goto out;
361
362
	subfile = get_subfs_file(file);
363
	rc = PTR_ERR(subfile);
364
	if (IS_ERR(subfile))
365
		goto out;
366
367
	rc = -ENOTTY;
368
	subinode = subfile->f_dentry->d_inode;
369
	if (subfile->f_op && subfile->f_op->ioctl)
370
		rc = subfile->f_op->ioctl(subinode, subfile, cmd, arg);
371
372
	/* flags may have been changed by ioctl */
373
	if (!rc)
374
		set_inode_flags(file->f_dentry->d_inode, subinode);
375
376
	fput(subfile);
377
out:
378
	LEAVE(sb, "file=%p rc=%d", file, rc);
379
380
	return rc;
381
}
382
383
int
384
supermount_open(struct inode *inode, struct file *file)
385
{
386
	struct super_block *sb = inode->i_sb;
387
	struct dentry *subdent;
388
	struct file *subfile = 0;
389
	struct vfsmount *submnt;
390
	int write_on = file->f_mode & FMODE_WRITE;
391
	int fake_open = 1;
392
	int rc;
393
394
	ENTER(sb, "inode=%p file=%p", inode, file);
395
396
	rc = -ESTALE;
397
	if (subfs_check_disk_change(sb))
398
		goto out;
399
400
	submnt = subfs_get_mnt(sb);
401
	if (!submnt)
402
		goto out;
403
404
	subdent = get_subfs_dentry(file->f_dentry);
405
	rc = PTR_ERR(subdent);
406
	if (IS_ERR(subdent))
407
		goto put_submnt;
408
	
409
	rc = subfs_get_access(inode, write_on);
410
	if (rc)
411
		goto put_subdent;
412
413
	/*
414
	 * the following is used to simplify error processing. dentry_open
415
	 * automatically does mntput and dput in error case, this may result
416
	 * in subfs being destroyed
417
	 * We just make sure we need to do mntput exactly once here;
418
	 * additionally it guards against accidental remounting of subfs
419
	 * until we has cleaned up
420
	 */
421
	submnt = mntget(submnt);
422
	subdent = dget(subdent);
423
424
	subfile = dentry_open(subdent, submnt, file->f_flags);
425
	rc = PTR_ERR(subfile);
426
	if (IS_ERR(subfile))
427
		goto put_access;
428
	/*
429
	 * no need to do extra mntput and dput, it is done automatically in
430
	 * dentry_open on error
431
	 */
432
433
	rc = prepare_file(file, subfile);
434
	if (rc)
435
		goto put_subfile;
436
437
	subfile->f_mode = file->f_mode;
438
	/*
439
	 * this is needed for mmap to work. In current model vm_area
440
	 * is associated with superfile; we never explicitly call
441
	 * any vm method with subfile as pointer. But many drivers
442
	 * attach private structures to this field and mmap of special
443
	 * files on supermount fs won't work without it
444
	 */
445
	file->private_data = subfile->private_data;
446
	/*
447
	 * we have real subfile now, do not fake anything
448
	 */
449
	fake_open = 0;
450
451
	/*
452
	 * Now get rid of extra mntget and dget
453
	 */
454
	goto put_subdent;
455
456
	/*
457
	 * error cleanup
458
	 */
459
460
put_subfile:
461
	fput(subfile);
462
	subfile = 0;
463
put_access:
464
	subfs_put_access(inode, write_on);
465
put_subdent:
466
	dput(subdent);
467
put_submnt:
468
	mntput(submnt);
469
out:
470
	if (fake_open && inode == sb->s_root->d_inode) {
471
		/*
472
		 * always appear to succeed for root open. It allows active
473
		 * monitoring of mountpoint using FAM/dnotify and also is less
474
		 * surprising for other programs
475
		 */
476
		rc = init_file_info(file, 1);
477
		if (rc)
478
			rc = -ENOMEM;
479
	}
480
	LEAVE(sb, "inode=%p file=%p rc=%d subfile=0x%p", inode, file, rc, subfile);
481
482
	return rc;
483
}
484
485
static int
486
supermount_flush(struct file *file, fl_owner_t id)
487
{
488
	struct super_block *sb = file->f_dentry->d_sb;
489
	struct file *subfile;
490
	int fake_flush = 1;
491
	int rc;
492
493
	ENTER(sb, "file=%p", file);
494
495
	rc = -ESTALE;
496
	if (subfs_check_disk_change(sb))
497
		goto out;
498
499
	subfile = get_subfs_file(file);
500
	rc = PTR_ERR(subfile);
501
	if (IS_ERR(subfile))
502
		goto out;
503
504
	rc = 0;
505
	fake_flush = 0;
506
	if (subfile->f_op && subfile->f_op->flush)
507
		rc = subfile->f_op->flush(subfile,id);
508
509
	fput(subfile);
510
out:
511
	if (fake_flush && is_file_fake(file)) {
512
		/* cf. supermount_open */
513
		rc = 0;
514
	}
515
	LEAVE(sb, "file=%p rc=%d fake=%d", file, rc, fake_flush);
516
517
	return rc;
518
}
519
520
/*
521
 * if subfile is NULL it has already been released in supermount_clean_files
522
 * together with adjusting open/write counters. Else we do it here.
523
 *
524
 * The reason is, it may be called long after media has been changed
525
 * and we definitely do not want this function to mess up the
526
 * new subfs state.
527
 */
528
static int
529
supermount_release(struct inode *inode, struct file *file)
530
{
531
	struct file *subfile = 0;
532
	struct super_block *sb = inode->i_sb;
533
	struct supermount_file_info *sfi = file->f_supermount;
534
535
	ENTER(sb, "inode=%p file=%p", inode, file);
536
537
	subfs_lock(sb);
538
	/*
539
	 * FIXME
540
	 * this sucks. But there does not seem to be any way
541
	 * to distinguish between ENOMEM on _open (legitimate
542
	 * case) and anything else (plain bug)
543
	 */
544
	if (sfi) {
545
		list_del(&sfi->list);
546
		subfile = sfi->file;
547
		sfi->file = 0;
548
	} else
549
		supermount_warning(sb, "no supermount file info attached");
550
	subfs_unlock(sb);
551
552
	if (subfile) {
553
		int bug = atomic_read(&subfile->f_count) != 1;
554
		fput(subfile);
555
		subfs_put_access(inode, file->f_mode & FMODE_WRITE);
556
		SUPERMOUNT_BUG_ON(bug);
557
	}
558
559
	if (sfi)
560
		kfree(sfi);
561
562
	LEAVE(sb, "inode=%p file=%p", inode, file);
563
564
	return 0;
565
566
}
567
568
static int
569
supermount_fsync(struct file *file, struct dentry *dentry, int datasync)
570
{
571
	struct super_block *sb = file->f_dentry->d_sb;
572
	struct file *subfile;
573
	int rc;
574
575
	ENTER(sb, "file=%p dentry=%s sync=%d", file, dentry->d_name.name, datasync);
576
577
	rc = -ESTALE;
578
	if (subfs_check_disk_change(sb))
579
		goto out;
580
581
	subfile = get_subfs_file(file);
582
	rc = PTR_ERR(subfile);
583
	if (IS_ERR(subfile))
584
		goto out;
585
586
	rc = -EINVAL;
587
	if (subfile->f_op && subfile->f_op->fsync)
588
		rc = subfile->f_op->fsync(subfile, subfile->f_dentry, datasync);
589
590
	fput(subfile);
591
out:
592
	ENTER(sb, "file=%p dentry=%s rc=%d", file, dentry->d_name.name, rc);
593
594
	return rc;
595
}
596
597
static int
598
supermount_fasync(int fd, struct file *file, int on)
599
{
600
	struct super_block *sb = file->f_dentry->d_sb;
601
	struct file *subfile;
602
	int rc;
603
604
	ENTER(sb, "fd=%d file=%p on=%d", fd, file, on);
605
606
	rc = -ESTALE;
607
	if (subfs_check_disk_change(sb))
608
		goto out;
609
610
	subfile = get_subfs_file(file);
611
	rc = PTR_ERR(subfile);
612
	if (IS_ERR(subfile))
613
		goto out;
614
615
	rc = -EINVAL;
616
	if (subfile->f_op && subfile->f_op->fasync)
617
		rc = subfile->f_op->fasync(fd, subfile, on);
618
619
	fput(subfile);
620
out:
621
	LEAVE(sb, "fd=%d file=%p rc=%d", fd, file, rc);
622
623
	return rc;
624
}
625
626
static int
627
supermount_lock(struct file *file, int cmd, struct file_lock *fl)
628
{
629
	struct super_block *sb = file->f_dentry->d_sb;
630
	struct file *subfile;
631
	struct file_lock *fl_tmp;
632
	int rc;
633
634
	ENTER(sb, "file=%p cmd=%d", file, cmd);
635
636
	rc = -ESTALE;
637
	if (subfs_check_disk_change(sb))
638
		goto out;
639
640
	subfile = get_subfs_file(file);
641
	rc = PTR_ERR(subfile);
642
	if (IS_ERR(subfile))
643
		goto out;
644
645
	rc = 0;
646
	if (subfile->f_op && subfile->f_op->lock)
647
		rc = subfile->f_op->lock(subfile, cmd, fl);
648
	else if (cmd == F_GETLK)
649
		posix_test_lock(file, fl);
650
651
	fput(subfile);
652
out:
653
	LEAVE(sb, "file=%p rc=%d", file, rc);
654
655
	return rc;
656
}
657
658
/* Fixme:
659
 * readv: easy, export churnk from vfs
660
 * writev: easy, export churnk from vfs
661
 * sendpage: only used for networking, not needed
662
 * get_unmmapped_area: only used for devices, not needed
663
 */
664
665
struct file_operations supermount_dir_operations = {
666
	.llseek		= supermount_llseek,
667
	.read		= supermount_read,
668
	.readdir	= supermount_readdir,
669
	.ioctl		= supermount_ioctl,
670
	.open		= supermount_open,
671
	.flush		= supermount_flush,
672
	.release	= supermount_release,
673
	.fsync		= supermount_fsync,
674
	.fasync		= supermount_fasync,
675
};
676
677
struct file_operations supermount_file_operations = {
678
	.llseek		= supermount_llseek,
679
	.read		= supermount_read,
680
	.write		= supermount_write,
681
	.poll		= supermount_poll,
682
	.ioctl		= supermount_ioctl,
683
	.mmap		= supermount_file_mmap, /* from filemap.c */
684
	.open		= supermount_open,
685
	.flush		= supermount_flush,
686
	.release	= supermount_release,
687
	.fsync		= supermount_fsync,
688
	.fasync		= supermount_fasync,
689
	.lock		= supermount_lock,
690
};
(-)linux-2.6.25.4.orig/fs/supermount/filemap.c (+182 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/filemap.c
3
 *
4
 *  Initial version for kernel 2.4.21 (C) 2003 Andrey Borzenkov
5
 *                                             (arvidjaar@mail.ru)
6
 *
7
 *  $Id: filemap.c,v 1.4.4.2 2004/01/14 20:28:01 bor Exp $
8
 */
9
10
#define S_DBG_TRACE_CURRENT S_DBG_TRACE_FILEMAP
11
#include "supermount.h"
12
13
/*
14
 * Some rationale and justification for this file
15
 *
16
 * We play dirty tricks with mm management for mmaped files on supermount.
17
 * Address space points to subinode but vm area is associated with superfile.
18
 * When media change is detected, subinode together with all associated
19
 * pages goes away as well (at least, I hope so ...) Now we must prevent
20
 * any attempt to access no more existing address space. To do so we save
21
 * original vm_ops in private field and replace them with vm_ops in this file.
22
 * They check if file is stale, if yes, they try to return sensible error.
23
 * There is some doubt about possibility to block here ... OTOH any write
24
 * lock on subfs is hold in context where no mm lock is expected.
25
 */
26
static void
27
supermount_vm_open(struct vm_area_struct *area)
28
{
29
	struct file *file = area->vm_file, *subfile;
30
	struct super_block *sb = file->f_dentry->d_sb;
31
	struct supermount_file_info *sfi;
32
33
	ENTER(sb, "vm=%p", area);
34
35
	if (subfs_check_disk_change(sb))
36
		goto out;
37
38
	subfile = get_subfs_file(file);
39
	if (IS_ERR(subfile))
40
		goto out;
41
42
	sfi = supermount_f(file);
43
	if (sfi->vm_ops && sfi->vm_ops->open)
44
		sfi->vm_ops->open(area);
45
46
	fput(subfile);
47
out:
48
	LEAVE(sb, "vm=%p", area);
49
50
	return;
51
}
52
53
static void
54
supermount_vm_close(struct vm_area_struct *area)
55
{
56
	struct file *file = area->vm_file, *subfile;
57
	struct super_block *sb = file->f_dentry->d_sb;
58
	struct supermount_file_info *sfi;
59
60
	ENTER(sb, "vm=%p", area);
61
	
62
	if (subfs_check_disk_change(sb))
63
		goto out;
64
65
	subfile = get_subfs_file(file);
66
	if (IS_ERR(subfile))
67
		goto out;
68
69
	sfi = supermount_f(file);
70
	if (sfi->vm_ops && sfi->vm_ops->close)
71
		sfi->vm_ops->close(area);
72
73
	fput(subfile);
74
out:
75
	LEAVE(sb, "vm=%p", area);
76
77
	return;
78
}
79
80
static struct page *
81
supermount_vm_nopage(struct vm_area_struct *area, unsigned long address, int *type)
82
{
83
	struct file *file = area->vm_file, *subfile;
84
	struct super_block *sb = file->f_dentry->d_sb;
85
	struct supermount_file_info *sfi;
86
	struct page *page = 0;
87
88
	ENTER(sb, "vm=%p addr=%lx", area, address);
89
	
90
	/*
91
	 * this is called with mm semaphore down read and pagetable
92
	 * spinlock released. So it _appears_ safe to sleep ...
93
	 */
94
	if (subfs_check_disk_change(sb))
95
		goto out;
96
97
	subfile = get_subfs_file(file);
98
	if (IS_ERR(subfile))
99
		goto out;
100
101
	sfi = supermount_f(file);
102
	page = sfi->vm_ops->nopage(area, address, type);
103
104
	fput(subfile);
105
out:
106
	LEAVE(sb, "vm=%p page=%p", area, page);
107
108
	return page;
109
}
110
111
int
112
supermount_file_mmap(struct file *file, struct vm_area_struct *vma)
113
{
114
115
	struct super_block *sb = file->f_dentry->d_sb;
116
	struct inode *inode = file->f_dentry->d_inode;
117
	struct supermount_file_info *sfi;
118
	struct file *subfile;
119
	int write_on = NEED_WRITE_ATIME(inode);
120
	int rc;
121
122
	ENTER(sb, "file=%p vm=%p", file, vma);
123
	
124
	rc = -ESTALE;
125
	if (subfs_check_disk_change(sb))
126
		goto out;
127
128
	subfile = get_subfs_file(file);
129
	rc = PTR_ERR(subfile);
130
	if (IS_ERR(subfile))
131
		goto out;
132
133
	sfi = supermount_f(file);
134
135
	rc = -ENODEV;
136
	if (!subfile->f_op || !subfile->f_op->mmap)
137
		goto put_subfile;
138
139
	rc = subfs_get_access(inode, write_on);
140
	if (rc)
141
		goto put_subfile;
142
143
	rc = subfile->f_op->mmap(subfile, vma);
144
	subfs_put_access(inode, write_on);
145
	if (rc)
146
		goto put_subfile;
147
	/*
148
	 * we cannot deal with anonymous mapping
149
	 */
150
	if (!vma->vm_ops || !vma->vm_ops->nopage) {
151
		rc = -ENOSYS;
152
		goto put_subfile;
153
	}
154
155
	/*
156
	 * now do the nasty trick
157
	 */
158
	sfi->vm_ops = vma->vm_ops;
159
	vma->vm_ops = &supermount_vm_ops;
160
161
put_subfile:
162
	fput(subfile);
163
out:
164
	LEAVE(sb, "file=%p vm=%p rc=%d", file, vma, rc);
165
166
	return rc;
167
}
168
169
/*
170
 * ->populate:	to properly implement it it should call do_no_page if
171
 *  		subfs does not provide its own ->populate. Unfortunately
172
 *  		populate gets different parameters. Translating them into
173
 *  		what ->nopage expects just does not worth it - currently
174
 *  		supermount is slow enough to bother about this imaginary
175
 *  		speed up even if it was possible (which probably is not
176
 *  		due to how locking is done; see mm/memory.c).
177
 */
178
struct  vm_operations_struct supermount_vm_ops = {
179
	.open		= supermount_vm_open,
180
	.close		= supermount_vm_close,
181
	.nopage		= supermount_vm_nopage,
182
};
(-)linux-2.6.25.4.orig/fs/supermount/init.c (+48 lines)
Line 0 Link Here
1
/* 
2
 * linux/fs/supermount/init.c
3
 *
4
 *  (C) Copyright 2001-2002 Juan Quintela <quintela@mandrakesoft.com>
5
 *      Released unde GPL v2.
6
 *  Rewritten for kernel 2.4.21 (C) 2003 Andrey Borzenkov
7
 *                                       (arvidjaar@mail.ru)
8
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
9
 *                                       (arvidjaar@mail.ru)
10
 *
11
 *  $Id: init.c,v 1.6.4.4 2003/10/26 16:21:25 bor Exp $
12
 */
13
14
#include "supermount.h"
15
16
struct file_system_type supermount_fs_type = {
17
        .owner          = THIS_MODULE,
18
        .name           = "supermount",
19
        .get_sb         = supermount_get_sb,
20
        .kill_sb        = kill_anon_super,
21
        .fs_flags       = FS_NO_SUBMNT,
22
};
23
24
static int __init
25
init_supermount_fs(void)
26
{
27
	int rc = register_filesystem(&supermount_fs_type);
28
	
29
	if (!rc) {
30
		printk(KERN_INFO "Supermount version %s for kernel 2.6\n", SUPERMOUNT_VERSION);
31
		supermount_proc_register();
32
	}
33
34
	return rc;
35
}
36
37
static void __exit
38
exit_supermount_fs(void)
39
{
40
	supermount_proc_unregister();
41
	unregister_filesystem(&supermount_fs_type);
42
}
43
44
MODULE_AUTHOR("Stephen Tweedie, Alexis Mikhailov, Juan Quintela, Andrey Borzenkov and others");
45
MODULE_DESCRIPTION("Transparent removable media support");
46
MODULE_LICENSE("GPL");
47
module_init(init_supermount_fs);
48
module_exit(exit_supermount_fs);
(-)linux-2.6.25.4.orig/fs/supermount/Kconfig (+26 lines)
Line 0 Link Here
1
config SUPERMOUNT
2
	tristate "Supermount removable media support"
3
	help
4
	  Supermount gives you the ability to access CD-ROMs and Floppies
5
	  without mounting/unmounting them every time you want to access
6
	  a different disk/floppy. Just eject the media, insert a new one
7
	  and you are able to access it.
8
9
	  Read Documentation/filesystems/supermount.txt for more information.
10
11
	  If you want to compile the Supermount support as a module ( = code
12
	  which can be inserted in and removed from the running kernel whenever
13
	  you want), say M here and read Documentation/modules.txt. The module
14
	  will be called supermount.o.
15
16
	  If unsure, say N.
17
18
config SUPERMOUNT_DEBUG
19
	bool "Enable supermount debug code"
20
	depends on SUPERMOUNT
21
	help
22
	  If you set this to Y, additional debug code will be compiled in.
23
	  Debug output is controlled with debug=N mount option. Possible
24
	  values are listed in Documentation/filesystems/supermount.txt.
25
26
	  If unsure, say Y.
(-)linux-2.6.25.4.orig/fs/supermount/Makefile (+15 lines)
Line 0 Link Here
1
#
2
# Makefile for the linux supermounting routines.
3
#
4
5
supermount-objs :=	dentry.o \
6
			file.o \
7
			filemap.o \
8
			init.o \
9
			mediactl.o \
10
			namei.o \
11
			proc.o \
12
			subfs.o \
13
			super.o 
14
15
obj-$(CONFIG_SUPERMOUNT) += supermount.o
(-)linux-2.6.25.4.orig/fs/supermount/mediactl.c (+69 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/mediactl.c
3
 *
4
 *  Original version:
5
 *      Copyright (C) 1995, 1997
6
 *      Stephen Tweedie (sct@dcs.ed.ac.uk)
7
 *
8
 *  Rewriten for kernel 2.2, 2.4. (C) 1999, 2000 Alexis Mikhailov
9
 *                                    (alexis@abc.cap.ru)
10
 *  Rewritten for kernel 2.4.21 (C) 2003 Andrey Borzenkov
11
 *                                       (arvidjaar@mail.ru)
12
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
13
 *                                       (arvidjaar@mail.ru)
14
 *
15
 *  $Id: mediactl.c,v 1.5.2.5 2003/07/13 19:15:20 bor Exp $
16
 */
17
18
#define S_DBG_TRACE_CURRENT S_DBG_TRACE_MEDIACTL
19
#include "supermount.h"
20
21
/* 
22
 * Try to lock the drive door.  This is not guaranteed to work on all
23
 * hardware, but we try any tricks we know of anyway.  
24
 */
25
void
26
supermount_mediactl(struct super_block *sb, int operation, int opt)
27
{
28
	struct block_device *bdev;
29
	struct super_block *subsb;
30
	struct block_device_operations *fops = 0;
31
32
	if (!subfs_is_mounted(sb))
33
		return;
34
35
	subsb = subfs_sb(sb);
36
	bdev = subsb->s_bdev;
37
	if (!bdev->bd_disk)
38
		return;
39
40
	/* FIXME is it enough to use bd_sem here? */
41
	switch (operation) {
42
		case SUPERMOUNT_INC_COUNT:
43
			lock_kernel();
44
			SUPERMOUNT_BUG_ON(bdev->bd_disk->scount < 0);
45
			bdev->bd_disk->scount++;
46
			unlock_kernel();
47
			return;
48
		case SUPERMOUNT_DEC_COUNT:
49
			lock_kernel();
50
			SUPERMOUNT_BUG_ON(bdev->bd_disk->scount <= 0);
51
			bdev->bd_disk->scount--;
52
			unlock_kernel();
53
			return;
54
	}
55
56
	fops = bdev->bd_disk->fops;
57
	if (!fops || !fops->mediactl)
58
		return;
59
	/*
60
	 * tray is (un-)locked in open (BKL for bdev), release (BKL for bdev)
61
	 * and ioctl (BKL). We are in good company.
62
	 * This must be changed if block devices ever stop using BKL
63
	 * for open/release. Unfortunately, using just bdev->bd_sem is not
64
	 * enough due to ioctl.
65
	 */
66
	lock_kernel();
67
	fops->mediactl(bdev, operation, opt);
68
	unlock_kernel();
69
}
(-)linux-2.6.25.4.orig/fs/supermount/namei.c (+1145 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/namei.c
3
 *
4
 *  Original version:
5
 *      Copyright (C) 1995
6
 *      Stephen Tweedie (sct@dcs.ed.ac.uk)
7
 *
8
 *      from
9
 *
10
 *      linux/fs/minix/namei.c
11
 *      Copyright (C) 1991, 1992  Linus Torvalds
12
 *
13
 *      and
14
 *
15
 *      linux/fs/ext2/namei.c
16
 *      Copyright (C) 1992, 1993, 1994, 1995  Remy Card
17
 *
18
 *  Rewriten for kernel 2.2 & 2.4. (C) 1999, 2000 Alexis Mikhailov
19
 *                                    (alexis@abc.cap.ru)
20
 *  Rewritten for kernel 2.4.21 (C) 2003 Andrey Borzenkov
21
 *                                       (arvidjaar@mail.ru)
22
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
23
 *                                       (arvidjaar@mail.ru)
24
 *
25
 *  $Id: namei.c,v 1.21.2.11 2004/01/04 15:05:03 bor Exp $
26
 */
27
28
#define S_DBG_TRACE_CURRENT S_DBG_TRACE_NAMEI
29
#include "supermount.h"
30
31
/**
32
 * Attach super dentry to sub dentry 
33
 *
34
 * @dentry:	super dentry that is being created
35
 * @subd:	subfs dentry that just has been found
36
 *
37
 * It checks whether subfs is still valid using @dentry->d_parent;
38
 * new supermount_dentry_info is created and set to point to @subd.
39
 *
40
 * It is possible that @subd actually has different name (ntfs, vfat or
41
 * in general any case-insensitive filesystems). Search @dentry->d_parent
42
 * for a child matching == @subd->d_name. If found, discard @dentry and child
43
 * (after some validity checks) is returned. Check that child actually points
44
 * to @subd
45
 *
46
 * d_lookup relies on the fact that hash is properly initialized in
47
 * @subd->d_name and that superfs is using the same compare method as subfs.
48
 *
49
 * About ref counting. @subd is dput in supermount_lookup. I.e. in case of
50
 * error or if we find out it is already connected to superfs the excessive
51
 * counter gets decremented. @dentry is finally dput in caller of ->lookup
52
 * if ->lookup returns something != 0.
53
 */
54
55
static struct dentry *
56
prepare_dentry(struct dentry *dentry, struct dentry *subd)
57
{
58
	struct super_block *sb = dentry->d_sb;
59
	struct dentry *rc;
60
61
	ENTER(sb, "dentry=%s subd=%s", dentry->d_name.name, subd->d_name.name);
62
63
	subfs_lock(sb);
64
65
	SUPERMOUNT_BUG_LOCKED_ON(sb, !subd);
66
	SUPERMOUNT_BUG_LOCKED_ON(sb, dentry->d_fsdata);
67
68
	rc = ERR_PTR(-ENOMEDIUM);
69
	if (!subfs_is_mounted(sb))
70
		goto out;
71
72
	rc = ERR_PTR(-ESTALE);
73
	if (is_dentry_obsolete(dentry->d_parent))
74
		goto out;
75
76
	rc = d_lookup(dentry->d_parent, &subd->d_name);
77
	if (IS_ERR(rc))
78
		goto out;
79
80
	if (rc) {
81
		SUPERMOUNT_BUG_LOCKED_ON(sb, !rc->d_fsdata);
82
		SUPERMOUNT_BUG_LOCKED_ON(sb,
83
		((struct supermount_dentry_info *)rc->d_fsdata)->dentry != subd);
84
	} else {
85
		/*
86
		 * this is theoretically possible. We cannot garantee full
87
		 * coherency between subfs and superfs cache; i.e. entry
88
		 * may have been left in one cache but removed from another
89
		 */
90
		rc = ERR_PTR(-ENOMEM);
91
		if (init_dentry_info(dentry))
92
			goto out;
93
		attach_subfs_dentry(dentry, subd);
94
		d_add(dentry, 0);
95
		rc = 0;
96
	}
97
98
out:
99
	subfs_unlock(sb);
100
101
	LEAVE(sb, "dentry=%p subd=%p rc=%p", dentry, subd, rc);
102
103
	return rc;
104
	/*
105
	 * subdent is implicitly freed on return if we skip dget here
106
	 */
107
}
108
109
110
/**
111
 * Attach superfs inode to subfs inode 
112
 *
113
 * @dentry:	superfs dentry
114
 * @subd:	subfs dentry
115
 *
116
 * This is expected to be called only in cointext that requires
117
 * negative dentry.
118
 *
119
 * FIXME
120
 * Holding sbi->sem during iget4 creates deadlock with write_inode -
121
 * write_inode sets I_LOCK abd calls supermount_write_inode at the
122
 * same moment as iget4 sleeps waiting for I_LOCK to be cleared. So
123
 * it first acquires inode and then checks if subfs is still valid.
124
 */
125
126
static int
127
prepare_inode(struct dentry *dentry, struct dentry *subd)
128
{
129
	struct super_block *sb = dentry->d_sb;
130
	struct inode *inode = dentry->d_inode;
131
	struct inode *subi = subd->d_inode;
132
	int rc;
133
134
	ENTER(sb, "dentry=%s", dentry->d_name.name);
135
136
	SUPERMOUNT_BUG_ON(inode);
137
	SUPERMOUNT_BUG_ON(!subi);
138
139
	rc = -ENOMEM;
140
	inode = iget_locked(sb, subi->i_ino);
141
	if (!inode)
142
		goto out;
143
	else if (inode->i_state & I_NEW)
144
		unlock_new_inode(inode);
145
146
	rc = 0;
147
148
	subfs_lock(sb);
149
	if (!subfs_is_mounted(sb))
150
		rc = -ENOMEDIUM;
151
	else if (is_dentry_obsolete(dentry))
152
		rc = -ESTALE;
153
	else {
154
		attach_subfs_inode(inode, subi);
155
		d_instantiate(dentry, inode);
156
	}
157
	subfs_unlock(sb);
158
159
	if (rc)
160
		iput(inode);
161
162
out:
163
	LEAVE(sb, "dentry=%s inode=%p rc=%d", dentry->d_name.name, inode, rc);
164
165
	return rc;
166
}
167
168
struct inode *
169
get_subfs_inode(struct inode *inode)
170
{
171
	struct super_block *sb = inode->i_sb;
172
	struct inode *err;
173
	struct supermount_inode_info *sii = supermount_i(inode);
174
175
	ENTER(sb, "inode=%p", inode);
176
177
	subfs_lock(sb);
178
179
	err = ERR_PTR(-ENOMEDIUM);
180
	if (!subfs_is_mounted(sb))
181
		goto out;
182
183
	err = ERR_PTR(-ESTALE);
184
	if (is_inode_obsolete(inode))
185
		goto out;
186
187
	err = igrab(sii->inode);
188
	SUPERMOUNT_BUG_LOCKED_ON(sb, !err);
189
190
out:
191
	subfs_unlock(sb);
192
193
	LEAVE(sb, "inode=%p subi=%p", inode, err);
194
195
	return err;
196
}
197
198
/* inode methods */
199
200
static int
201
supermount_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
202
{
203
	struct super_block *sb = dir->i_sb;
204
	struct dentry *subdent;
205
	struct inode *subdir;
206
	int rc;
207
	struct vfsmount *mnt;
208
209
	ENTER(sb, "dir=%p dentry=%s", dir, dentry->d_name.name);
210
211
	mnt = subfs_go_online(sb);
212
	rc = PTR_ERR(mnt);
213
	if (IS_ERR(mnt))
214
		goto out;
215
216
	subdir = get_subfs_inode(dir);
217
	rc = PTR_ERR(subdir);
218
	if (IS_ERR(subdir))
219
		goto go_offline;
220
221
	rc = -EACCES;
222
	if (!subdir->i_op || !subdir->i_op->create)
223
		goto put_subdir;
224
	
225
	subdent = get_subfs_dentry(dentry);
226
	rc = PTR_ERR(subdent);
227
	if (IS_ERR(subdent))
228
		goto put_subdir;
229
230
	rc = subfs_get_access(dir, 1);
231
	if (rc)
232
		goto put_subdent;
233
234
	/* FIXME build proper nd struct */
235
	rc = subdir->i_op->create(subdir, subdent, mode, nd);
236
	subfs_put_access(dir, 1);
237
	if (rc)
238
		goto put_subdent;
239
240
	rc = prepare_inode(dentry, subdent);
241
	if (rc)
242
		goto put_subdent;
243
244
	dir->i_mtime = subdir->i_mtime;
245
	dir->i_ctime = subdir->i_ctime;
246
	dir->i_nlink = subdir->i_nlink;
247
	dir->i_size = subdir->i_size;
248
	dir->i_blocks = subdir->i_blocks;
249
250
put_subdent:
251
	dput(subdent);
252
put_subdir:
253
	iput(subdir);
254
go_offline:
255
	subfs_go_offline(sb, mnt);
256
out:
257
	LEAVE(sb, "dir=%p dentry=%s rc=%d", dir, dentry->d_name.name, rc);
258
259
	return rc;
260
}
261
262
/**
263
 * Search directory for a matching name
264
 *
265
 * @dir:	directory that is being searched
266
 * @dentry:	name to search for (in dentry->d_name)
267
 *
268
 * This is (currently :) the only method where we do not call subfs
269
 * directly. The reason is coherency between subfs and superfs dentry
270
 * caches. It is impossible to ensure it without modifying the very
271
 * guts of fs/dcache.c; so we check cache before doing actual lookup.
272
 * lookup_one_len just avoids duplicating of code.
273
 *
274
 * Supermount is in exclusive control of subfs so it is garanteed that
275
 * dentry cannot magically appear in the middle of lookup.
276
 *
277
 * There are filesystems that support multiple forms of file name, like
278
 * case-insensitive or short-long names on NTFS. In this case cache lookup
279
 * fails but filesystem may return dentry for different name. In this case
280
 * we check if dentry with matching name exists in parent and reuse it.
281
 */
282
static struct dentry *
283
supermount_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
284
{
285
	struct super_block *sb = dir->i_sb;
286
	struct dentry *rc, *subdent, *subparent;
287
	struct inode *subdir;
288
	struct vfsmount *mnt;
289
	int ret;
290
291
	ENTER(sb, "dir=%p dentry=%s", dir, dentry->d_name.name);
292
293
	mnt = subfs_go_online(sb);
294
	rc = (struct dentry *)mnt;
295
	if (IS_ERR(mnt))
296
		goto out;
297
298
	subdir = get_subfs_inode(dir);
299
	rc = (struct dentry *)subdir;
300
	if (IS_ERR(subdir))
301
		goto go_offline;
302
303
	subparent = get_subfs_dentry(dentry->d_parent);
304
	rc = subparent;
305
	if (IS_ERR(subparent))
306
		goto put_subdir;
307
308
	ret = subfs_get_access(dir, 0);
309
	rc = ERR_PTR(ret);
310
	if (ret)
311
		goto put_subparent;
312
313
	SUPERMOUNT_BUG_ON(subparent->d_inode != subdir);
314
315
	/* FIXME usually lookup_one_len is called under i_sem */
316
	/* FIXME what to do with nd? */
317
	subdent = lookup_one_len(dentry->d_name.name, subparent,
318
				 dentry->d_name.len);
319
320
	subfs_put_access(dir, 0);
321
	rc = subdent;
322
	if (IS_ERR(rc))
323
		goto put_subparent;
324
325
	rc = prepare_dentry(dentry, subdent);
326
	if (IS_ERR(rc))
327
		goto put_subdent;
328
329
	if (!rc && subdent->d_inode) {
330
		ret = prepare_inode(dentry, subdent);
331
		if (ret < 0)
332
			rc = ERR_PTR(ret);
333
	}
334
335
put_subdent:
336
	dput(subdent);
337
put_subparent:
338
	dput(subparent);
339
put_subdir:
340
	iput(subdir);
341
go_offline:
342
	subfs_go_offline(sb, mnt);
343
out:
344
	LEAVE(sb, "dir=%p dentry=%s rc=%p", dir, dentry->d_name.name, rc);
345
346
	return rc;
347
}
348
349
static int
350
supermount_link(struct dentry *old_dentry, struct inode *dir,
351
		struct dentry *new_dentry)
352
{
353
	struct super_block *sb = dir->i_sb;
354
	struct dentry *old_subdent, *new_subdent;
355
	struct inode *subdir;
356
	int rc;
357
	struct vfsmount *mnt;
358
359
	ENTER(sb, "from=%s dir=%p to=%s", old_dentry->d_name.name, dir, new_dentry->d_name.name);
360
361
	SUPERMOUNT_BUG_ON(new_dentry->d_inode);
362
363
	mnt = subfs_go_online(sb);
364
	rc = PTR_ERR(mnt);
365
	if (IS_ERR(mnt))
366
		goto out;
367
368
	subdir = get_subfs_inode(dir);
369
	rc = PTR_ERR(subdir);
370
	if (IS_ERR(subdir))
371
		goto go_offline;
372
373
	rc = -EPERM;
374
	if (!subdir->i_op || !subdir->i_op->link)
375
		goto put_subdir;
376
377
	old_subdent = get_subfs_dentry(old_dentry);
378
	rc = PTR_ERR(old_subdent);
379
	if (IS_ERR(old_subdent))
380
		goto put_subdir;
381
382
	new_subdent = get_subfs_dentry(new_dentry);
383
	rc = PTR_ERR(new_subdent);
384
	if (IS_ERR(new_subdent))
385
		goto put_old_subdent;
386
387
	rc = subfs_get_access(dir, 1);
388
	if (rc)
389
		goto put_new_subdent;
390
391
	rc = subdir->i_op->link(old_subdent, subdir, new_subdent);
392
	subfs_put_access(dir, 1);
393
	if (rc)
394
		goto put_new_subdent;
395
396
	rc = prepare_inode(new_dentry, new_subdent);
397
	if (rc)
398
		goto put_new_subdent;
399
400
	dir->i_mtime = subdir->i_mtime;
401
	dir->i_ctime = subdir->i_ctime;
402
	dir->i_nlink = subdir->i_nlink;
403
	dir->i_size = subdir->i_size;
404
	dir->i_blocks = subdir->i_blocks;
405
406
put_new_subdent:
407
	dput(new_subdent);
408
put_old_subdent:
409
	dput(old_subdent);
410
put_subdir:
411
	iput(subdir);
412
go_offline:
413
	subfs_go_offline(sb, mnt);
414
out:
415
	LEAVE(sb, "from=%s dir=%p to=%s rc=%d", old_dentry->d_name.name, dir, new_dentry->d_name.name, rc);
416
417
	return rc;
418
}
419
420
static int
421
supermount_unlink(struct inode *dir, struct dentry *dentry)
422
{
423
	struct super_block *sb = dir->i_sb;
424
	struct dentry *subdent;
425
	struct inode *subdir;
426
	int rc;
427
	struct vfsmount *mnt;
428
429
	ENTER(sb, "dir=%p dentry=%s", dir, dentry->d_name.name);
430
431
	mnt = subfs_go_online(sb);
432
	rc = PTR_ERR(mnt);
433
	if (IS_ERR(mnt))
434
		goto out;
435
436
	subdir = get_subfs_inode(dir);
437
	rc = PTR_ERR(subdir);
438
	if (IS_ERR(subdir))
439
		goto go_offline;
440
441
	rc = -EPERM;
442
	if (!subdir->i_op || !subdir->i_op->unlink)
443
		goto put_subdir;
444
445
	subdent = get_subfs_dentry(dentry);
446
	rc = PTR_ERR(subdent);
447
	if (IS_ERR(subdent))
448
		goto put_subdir;
449
450
	/*
451
	 * below is not a typo. We have to mark _deleted_ inode
452
	 * for possible later delete in clear_inode
453
	 */
454
	rc = subfs_get_access(dentry->d_inode, 1);
455
	if (rc)
456
		goto put_subdent;
457
458
	rc = subdir->i_op->unlink(subdir, subdent);
459
	if (rc)
460
		goto put_write_access;
461
462
	dir->i_mtime = subdir->i_mtime;
463
	dir->i_ctime = subdir->i_ctime;
464
	dir->i_nlink = subdir->i_nlink;
465
	dir->i_size = subdir->i_size;
466
	dir->i_blocks = subdir->i_blocks;
467
468
	dentry->d_inode->i_nlink = subdent->d_inode->i_nlink;
469
	dentry->d_inode->i_ctime = subdent->d_inode->i_ctime;
470
471
put_write_access:
472
	/*
473
	 * we can't put write access if there are pending deletes
474
	 * so we leave it on and let it be put in clear_inode for
475
	 * i_nlink == 0
476
	 *
477
	 * While i_nlink is believed to be atomic here i_count not,
478
	 * so we cannot check && i_count == 0. It is expected that
479
	 * deleted files are kept open only rarely.
480
	 */
481
	if (dentry->d_inode->i_nlink)
482
		subfs_put_access(dentry->d_inode, 1);
483
put_subdent:
484
	dput(subdent);
485
put_subdir:
486
	iput(subdir);
487
go_offline:
488
	subfs_go_offline(sb, mnt);
489
out:
490
	LEAVE(sb, "dir=%p dentry=%s rc=%d", dir, dentry->d_name.name, rc);
491
492
	return rc;
493
}
494
495
static int
496
supermount_symlink(struct inode *dir, struct dentry *dentry,
497
		   const char *symname)
498
{
499
	struct super_block *sb = dir->i_sb;
500
	struct dentry *subdent;
501
	struct inode *subdir;
502
	int rc;
503
	struct vfsmount *mnt;
504
505
	ENTER(sb, "dir=%p dentry=%s", dir, dentry->d_name.name);
506
507
	mnt = subfs_go_online(sb);
508
	rc = PTR_ERR(mnt);
509
	if (IS_ERR(mnt))
510
		goto out;
511
512
	subdir = get_subfs_inode(dir);
513
	rc = PTR_ERR(subdir);
514
	if (IS_ERR(subdir))
515
		goto go_offline;
516
517
	rc = -EPERM;
518
	if (!subdir->i_op || !subdir->i_op->symlink)
519
		goto put_subdir;
520
521
	subdent = get_subfs_dentry(dentry);
522
	rc = PTR_ERR(subdent);
523
	if (IS_ERR(subdent))
524
		goto put_subdir;
525
526
	rc = subfs_get_access(dir, 1);
527
	if (rc)
528
		goto put_subdent;
529
530
	rc = subdir->i_op->symlink(subdir, subdent, symname);
531
	subfs_put_access(dir, 1);
532
	if (rc)
533
		goto put_subdent;
534
535
	rc = prepare_inode(dentry, subdent);
536
	if (rc)
537
		goto put_subdent;
538
539
	dir->i_mtime = subdir->i_mtime;
540
	dir->i_ctime = subdir->i_ctime;
541
	dir->i_nlink = subdir->i_nlink;
542
	dir->i_size = subdir->i_size;
543
	dir->i_blocks = subdir->i_blocks;
544
545
put_subdent:
546
	dput(subdent);
547
put_subdir:
548
	iput(subdir);
549
go_offline:
550
	subfs_go_offline(sb, mnt);
551
out:
552
	LEAVE(sb, "dir=%p dentry=%s rc=%d", dir, dentry->d_name.name, rc);
553
554
	return rc;
555
}
556
557
static int
558
supermount_mkdir(struct inode *dir, struct dentry *dentry, int mode)
559
{
560
	struct super_block *sb = dir->i_sb;
561
	struct dentry *subdent;
562
	struct inode *subdir;
563
	int rc;
564
	struct vfsmount *mnt;
565
566
	ENTER(sb, "dir=%p dentry=%s", dir, dentry->d_name.name);
567
568
	mnt = subfs_go_online(sb);
569
	rc = PTR_ERR(mnt);
570
	if (IS_ERR(mnt))
571
		goto out;
572
573
	subdir = get_subfs_inode(dir);
574
	rc = PTR_ERR(subdir);
575
	if (IS_ERR(subdir))
576
		goto go_offline;
577
578
	rc = -EPERM;
579
	if (!subdir->i_op || !subdir->i_op->mkdir)
580
		goto put_subdir;
581
582
	subdent = get_subfs_dentry(dentry);
583
	rc = PTR_ERR(subdent);
584
	if (IS_ERR(subdent))
585
		goto put_subdir;
586
587
	rc = subfs_get_access(dir, 1);
588
	if (rc)
589
		goto put_subdent;
590
591
	rc = subdir->i_op->mkdir(subdir, subdent, mode);
592
	subfs_put_access(dir, 1);
593
	if (rc)
594
		goto put_subdent;
595
596
	rc = prepare_inode(dentry, subdent);
597
	if (rc)
598
		goto put_subdent;
599
600
	dir->i_mtime = subdir->i_mtime;
601
	dir->i_ctime = subdir->i_ctime;
602
	dir->i_nlink = subdir->i_nlink;
603
	dir->i_size = subdir->i_size;
604
	dir->i_blocks = subdir->i_blocks;
605
606
put_subdent:
607
	dput(subdent);
608
put_subdir:
609
	iput(subdir);
610
go_offline:
611
	subfs_go_offline(sb, mnt);
612
out:
613
	LEAVE(sb, "dir=%p dentry=%s rc=%d", dir, dentry->d_name.name, rc);
614
615
	return rc;
616
}
617
618
static int
619
supermount_rmdir(struct inode *dir, struct dentry *dentry)
620
{
621
	struct super_block *sb = dir->i_sb;
622
	struct dentry *subdent;
623
	struct inode *subdir;
624
	int rc;
625
	struct vfsmount *mnt;
626
627
	ENTER(sb, "dir=%p dentry=%s", dir, dentry->d_name.name);
628
629
	mnt = subfs_go_online(sb);
630
	rc = PTR_ERR(mnt);
631
	if (IS_ERR(mnt))
632
		goto out;
633
634
	subdir = get_subfs_inode(dir);
635
	rc = PTR_ERR(subdir);
636
	if (IS_ERR(subdir))
637
		goto go_offline;
638
639
	rc = -EPERM;
640
	if (!subdir->i_op || !subdir->i_op->rmdir)
641
		goto put_subdir;
642
643
	subdent = get_subfs_dentry(dentry);
644
	rc = PTR_ERR(subdent);
645
	if (IS_ERR(subdent))
646
		goto put_subdir;
647
648
	/* cf. supermount_unlink */
649
	rc = subfs_get_access(dentry->d_inode, 1);
650
	if (rc)
651
		goto put_subdent;
652
653
	rc = subdir->i_op->rmdir(subdir, subdent);
654
	if (rc)
655
		goto put_write_access;
656
657
	dir->i_mtime = subdir->i_mtime;
658
	dir->i_ctime = subdir->i_ctime;
659
	dir->i_nlink = subdir->i_nlink;
660
	dir->i_size = subdir->i_size;
661
	dir->i_blocks = subdir->i_blocks;
662
663
	/* hmm ... hard links to directories are not allowed, are they? */
664
	dentry->d_inode->i_nlink = subdent->d_inode->i_nlink;
665
	dentry->d_inode->i_ctime = subdent->d_inode->i_ctime;
666
667
put_write_access:
668
	/* cf. supermount_unlink */
669
	if (dentry->d_inode->i_nlink)
670
		subfs_put_access(dentry->d_inode, 1);
671
put_subdent:
672
	dput(subdent);
673
put_subdir:
674
	iput(subdir);
675
go_offline:
676
	subfs_go_offline(sb, mnt);
677
out:
678
	LEAVE(sb, "dir=%p dentry=%s rc=%d", dir, dentry->d_name.name, rc);
679
680
	return rc;
681
}
682
683
static int
684
supermount_mknod(struct inode *dir, struct dentry *dentry, int
685
		 mode, dev_t dev)
686
{
687
	struct super_block *sb = dir->i_sb;
688
	struct dentry *subdent;
689
	struct inode *subdir;
690
	int rc;
691
	struct vfsmount *mnt;
692
693
	ENTER(sb, "dir=%p dentry=%s", dir, dentry->d_name.name);
694
695
	mnt = subfs_go_online(sb);
696
	rc = PTR_ERR(mnt);
697
	if (IS_ERR(mnt))
698
		goto out;
699
700
	subdir = get_subfs_inode(dir);
701
	rc = PTR_ERR(subdir);
702
	if (IS_ERR(subdir))
703
		goto go_offline;
704
705
	rc = -EPERM;
706
	if (!subdir->i_op || !subdir->i_op->mknod)
707
		goto put_subdir;
708
709
	subdent = get_subfs_dentry(dentry);
710
	rc = PTR_ERR(subdent);
711
	if (IS_ERR(subdent))
712
		goto put_subdir;
713
714
	rc = subfs_get_access(dir, 1);
715
	if (rc)
716
		goto put_subdent;
717
718
	rc = subdir->i_op->mknod(subdir, subdent, mode, dev);
719
	subfs_put_access(dir, 1);
720
	if (rc)
721
		goto put_subdent;
722
723
	rc = prepare_inode(dentry, subdent);
724
	if (rc)
725
		goto put_subdent;
726
727
	dir->i_mtime = subdir->i_mtime;
728
	dir->i_ctime = subdir->i_ctime;
729
	dir->i_nlink = subdir->i_nlink;
730
	dir->i_size = subdir->i_size;
731
	dir->i_blocks = subdir->i_blocks;
732
733
put_subdent:
734
	dput(subdent);
735
put_subdir:
736
	iput(subdir);
737
go_offline:
738
	subfs_go_offline(sb, mnt);
739
out:
740
	LEAVE(sb, "dir=%p dentry=%s rc=%d", dir, dentry->d_name.name, rc);
741
742
	return rc;
743
}
744
745
static int
746
supermount_rename(struct inode *olddir, struct dentry *olddentry,
747
		  struct inode *newdir, struct dentry *newdentry)
748
{
749
	struct super_block *sb = olddir->i_sb;
750
	struct dentry *oldsubdent, *newsubdent;
751
	struct inode *oldsubdir, *newsubdir;
752
	int rc;
753
	struct vfsmount *mnt;
754
755
	ENTER(sb, "olddir=%p olddentry=%s newdir=%p newdentry=%s", olddir, olddentry->d_name.name, newdir, newdentry->d_name.name);
756
757
	mnt = subfs_go_online(sb);
758
	rc = PTR_ERR(mnt);
759
	if (IS_ERR(mnt))
760
		goto out;
761
762
	oldsubdir = get_subfs_inode(olddir);
763
	rc = PTR_ERR(oldsubdir);
764
	if (IS_ERR(oldsubdir))
765
		goto go_offline;
766
767
	rc = -EPERM;
768
	if (!oldsubdir->i_op || !oldsubdir->i_op->rename)
769
		goto put_old_subdir;
770
771
	oldsubdent = get_subfs_dentry(olddentry);
772
	rc = PTR_ERR(oldsubdent);
773
	if (IS_ERR(oldsubdent))
774
		goto put_old_subdir;
775
776
	newsubdir = get_subfs_inode(newdir);
777
	rc = PTR_ERR(newsubdir);
778
	if (IS_ERR(newsubdir))
779
		goto put_old_subdent;
780
781
	newsubdent = get_subfs_dentry(newdentry);
782
	rc = PTR_ERR(newsubdent);
783
	if (IS_ERR(newsubdent))
784
		goto put_new_subdir;
785
786
	/*
787
	 * If new file exists it will be implcitly unlinked so
788
	 * behave like in unlink case.
789
	 * If it does not exist we have two write accesses - for
790
	 * both old and new directory, I guess it does not matter
791
	 * which one is used in this case
792
	 */
793
	if (newdentry->d_inode)
794
		rc = subfs_get_access(newdentry->d_inode, 1);
795
	else
796
		rc = subfs_get_access(olddir, 1);
797
	if (rc)
798
		goto put_new_subdent;
799
800
	rc = oldsubdir->i_op->rename(oldsubdir, oldsubdent,
801
				     newsubdir, newsubdent);
802
	if (rc)
803
		goto put_write_access;
804
805
	/*
806
	 * this is strictly speaking conditional on FS_RENAME_DOES_D_MOVE
807
	 * flag, but as of this writing this flag is set only
808
	 * for NFS or intermezzo and it hopefully goes away sometimes ...
809
	 *
810
	 * Supermount patch adds code to do_kern_mount that checks
811
	 * for this flag and refuses mounting
812
	 */
813
	d_move(oldsubdent, newsubdent);
814
815
	olddir->i_mtime = oldsubdir->i_mtime;
816
	olddir->i_ctime = oldsubdir->i_ctime;
817
	olddir->i_nlink = oldsubdir->i_nlink;
818
	olddir->i_size = oldsubdir->i_size;
819
	olddir->i_blocks = oldsubdir->i_blocks;
820
821
	newdir->i_mtime = newsubdir->i_mtime;
822
	newdir->i_ctime = newsubdir->i_ctime;
823
	newdir->i_nlink = newsubdir->i_nlink;
824
	newdir->i_size = newsubdir->i_size;
825
	newdir->i_blocks = newsubdir->i_blocks;
826
827
	olddentry->d_inode->i_nlink = oldsubdent->d_inode->i_nlink;
828
	olddentry->d_inode->i_ctime = oldsubdent->d_inode->i_ctime;
829
830
	if (newdentry->d_inode) {
831
		newdentry->d_inode->i_nlink = newsubdent->d_inode->i_nlink;
832
		newdentry->d_inode->i_ctime = newsubdent->d_inode->i_ctime;
833
	}
834
835
put_write_access:
836
	if (newdentry->d_inode) {
837
		/* cf. supermount_unlink */
838
		if (newdentry->d_inode->i_nlink)
839
			subfs_put_access(newdentry->d_inode, 1);
840
	} else
841
		subfs_put_access(olddir, 1);
842
put_new_subdent:
843
	dput(newsubdent);
844
put_new_subdir:
845
	iput(newsubdir);
846
put_old_subdent:
847
	dput(oldsubdent);
848
put_old_subdir:
849
	iput(oldsubdir);
850
go_offline:
851
	subfs_go_offline(sb, mnt);
852
out:
853
	LEAVE(sb, "olddentry=%s newdentry=%s rc=%d", olddentry->d_name.name, newdentry->d_name.name, rc);
854
855
	return rc;
856
}
857
858
static int 
859
supermount_readlink(struct dentry *dentry, char *buffer , int buflen)
860
{
861
	struct super_block *sb = dentry->d_sb;
862
	struct inode *inode = dentry->d_inode;
863
	struct dentry *subdent;
864
	int write_on = NEED_WRITE_ATIME(inode);
865
	int rc;
866
	struct vfsmount *mnt;
867
868
	ENTER(sb, "dentry=%s", dentry->d_name.name);
869
870
	mnt = subfs_go_online(sb);
871
	rc = PTR_ERR(mnt);
872
	if (IS_ERR(mnt))
873
		goto out;
874
875
	subdent = get_subfs_dentry(dentry);
876
	rc = PTR_ERR(subdent);
877
	if (IS_ERR(subdent))
878
		goto go_offline;
879
880
	rc = -EINVAL;
881
	if (!subdent->d_inode->i_op || !subdent->d_inode->i_op->readlink)
882
		goto put_subdent;
883
884
	rc = subfs_get_access(inode, write_on);
885
	if (rc)
886
		goto put_subdent;
887
888
	//update_atime(subdent->d_inode);
889
	touch_atime(mnt,subdent);
890
	rc = subdent->d_inode->i_op->readlink(subdent, buffer, buflen);
891
	subfs_put_access(inode, write_on);
892
	inode->i_atime = subdent->d_inode->i_atime;
893
894
put_subdent:
895
	dput(subdent);
896
go_offline:
897
	subfs_go_offline(sb, mnt);
898
out:
899
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
900
901
	return rc;
902
}
903
904
static int
905
supermount_follow_link(struct dentry *dentry, struct nameidata *nd)
906
{
907
	struct super_block *sb = dentry->d_sb;
908
	struct inode *inode = dentry->d_inode;
909
	struct dentry *subdent;
910
	int write_on = NEED_WRITE_ATIME(inode);
911
	int rc;
912
	struct vfsmount *mnt;
913
	
914
	ENTER(sb, "dentry=%s", dentry->d_name.name);
915
916
	mnt = subfs_go_online(sb);
917
	rc = PTR_ERR(mnt);
918
	if (IS_ERR(mnt))
919
		goto out;
920
921
	subdent = get_subfs_dentry(dentry);
922
	rc = PTR_ERR(subdent);
923
	if (IS_ERR(subdent))
924
		goto go_offline;
925
926
	rc = subfs_get_access(inode, write_on);
927
	if (rc)
928
		goto put_subdent;
929
930
	//update_atime(subdent->d_inode);
931
	touch_atime(mnt,subdent);
932
	/* FIXME do we need proper subfs nd here? */
933
	rc = subdent->d_inode->i_op->follow_link(subdent, nd);
934
	subfs_put_access(inode, write_on);
935
	inode->i_atime = subdent->d_inode->i_atime;
936
937
put_subdent:
938
	dput(subdent);	
939
go_offline:
940
	subfs_go_offline(sb, mnt);
941
out:
942
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
943
944
	return rc;
945
}
946
947
static int
948
supermount_permission(struct inode *inode, int mask, struct nameidata *nd)
949
{
950
	struct super_block *sb = inode->i_sb;
951
	struct inode *subi;
952
	int rc;
953
	int write_on = !IS_RDONLY(inode) && (mask & MAY_WRITE);
954
	struct vfsmount *mnt;
955
	int fake_permissions = 1;
956
957
	ENTER(sb, "inode=%p", inode);
958
959
	mnt = subfs_go_online(sb);
960
	rc = PTR_ERR(mnt);
961
	if (IS_ERR(mnt))
962
		goto out;
963
964
	subi = get_subfs_inode(inode);
965
	rc = PTR_ERR(subi);
966
	if (IS_ERR(subi))
967
		goto go_offline;
968
969
	rc = subfs_get_access(inode, write_on);
970
	if (rc)
971
		goto put_subi;
972
973
	fake_permissions = 0;
974
	/* FIXME do we need proper subfs nd here */
975
	if (subi->i_op && subi->i_op->permission)
976
		rc = subi->i_op->permission(subi, mask, nd);
977
	else
978
		rc = generic_permission(subi, mask, NULL);
979
980
	subfs_put_access(inode, write_on);
981
982
put_subi:
983
	iput(subi);
984
go_offline:
985
	subfs_go_offline(sb, mnt);
986
out:
987
	if (fake_permissions && inode == sb->s_root->d_inode) {
988
		/* cf. file.c:supermount_open() */
989
		rc = generic_permission(inode, mask, NULL);
990
	}
991
992
	LEAVE(sb, "inode=%p rc=%d fake=%d", inode, rc, fake_permissions);
993
994
	return rc;
995
}
996
997
static int
998
supermount_setattr(struct dentry *dentry, struct iattr *attr)
999
{
1000
	struct super_block *sb = dentry->d_sb;
1001
	struct inode *subi;
1002
	struct dentry *subdent;
1003
	int rc;
1004
	struct vfsmount *mnt;
1005
1006
	ENTER(sb, "dentry=%s", dentry->d_name.name);
1007
1008
	mnt = subfs_go_online(sb);
1009
	rc = PTR_ERR(mnt);
1010
	if (IS_ERR(mnt))
1011
		goto out;
1012
1013
	subdent = get_subfs_dentry(dentry);
1014
	rc = PTR_ERR(subdent);
1015
	if (IS_ERR(subdent))
1016
		goto go_offline;
1017
1018
	rc = subfs_get_access(dentry->d_inode, 1);
1019
	if (rc)
1020
		goto put_subdent;
1021
1022
	subi = subdent->d_inode;
1023
	if (subi->i_op && subi->i_op->setattr)
1024
		rc = subi->i_op->setattr(subdent, attr);
1025
	else {
1026
		rc = inode_change_ok(subi, attr);
1027
		/*
1028
		 * FIXME
1029
		 * What to do with quota?
1030
		 */
1031
		if (!rc)
1032
			rc = inode_setattr(subi, attr);
1033
	}
1034
	subfs_put_access(dentry->d_inode, 1);
1035
	if (rc)
1036
		goto put_subdent;
1037
1038
	/* 
1039
	 * If it worked, then we need to mark the modification
1040
	 * to the subfs, and we also need to propogate the
1041
	 * change up to the shadowing inode.  
1042
	 */
1043
	attr->ia_mode = subi->i_mode;
1044
	attr->ia_uid = subi->i_uid;
1045
	attr->ia_gid = subi->i_gid;
1046
	attr->ia_size = subi->i_size;
1047
	attr->ia_atime = subi->i_atime;
1048
	attr->ia_mtime = subi->i_mtime;
1049
	attr->ia_ctime = subi->i_ctime;
1050
	attr->ia_valid =
1051
	    ATTR_UID | ATTR_GID | ATTR_MODE | ATTR_SIZE |
1052
	    ATTR_ATIME | ATTR_MTIME | ATTR_CTIME;
1053
	inode_setattr(dentry->d_inode, attr);
1054
1055
put_subdent:
1056
	dput(subdent);
1057
go_offline:
1058
	subfs_go_offline(sb, mnt);
1059
out:
1060
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
1061
1062
	return rc;
1063
}
1064
1065
static int
1066
supermount_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1067
{
1068
	struct super_block *sb = dentry->d_sb;
1069
	struct vfsmount *submnt;
1070
        struct dentry *subdent = 0;
1071
        int rc;
1072
1073
	ENTER(sb, "dentry=%s", dentry->d_name.name);
1074
1075
	/*
1076
	 * do not use subfs_go_online - it will result in ls /mnt
1077
	 * attempting to mount all supermounted directories
1078
	 */
1079
	submnt = subfs_prevent_umount(sb);
1080
	if (submnt)
1081
		subdent = get_subfs_dentry(dentry);
1082
1083
	/*
1084
	 * do not fail stat for stale files - it is needed to
1085
	 * make sure fuser -m /mnt/cdrom lists all processes still
1086
	 * having any (obsolete) file open
1087
	 */
1088
        if (submnt && subdent && !IS_ERR(subdent)) {
1089
                rc = vfs_getattr(submnt, subdent, stat);
1090
		stat->dev = sb->s_dev;
1091
	} else {
1092
		subfs_lock(sb);
1093
		generic_fillattr(dentry->d_inode, stat);
1094
		subfs_unlock(sb);
1095
		rc = 0;
1096
	}
1097
1098
	if (subdent && !IS_ERR(subdent))
1099
		dput(subdent);
1100
	if (submnt)
1101
		subfs_allow_umount(sb, submnt);
1102
1103
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
1104
1105
	return rc;
1106
}
1107
1108
/*
1109
 * directories can handle most operations...  supermount/namei.c just
1110
 * passes them through to the underlying subfs, except for lookup().
1111
 */
1112
1113
/* truncate: is not necesary, handled with setattr
1114
 * revalidate: only needed by nfs
1115
 * ->getattr:	FIXME is not appeared to be used anywhere in kernel; so I am
1116
 *  		not sure how to implement it or what to return
1117
 * FIXME: implement accl functions
1118
 */
1119
1120
struct inode_operations supermount_dir_iops = {
1121
	.create		= supermount_create,
1122
	.lookup		= supermount_lookup,
1123
	.link		= supermount_link,
1124
	.unlink		= supermount_unlink,
1125
	.symlink	= supermount_symlink,
1126
	.mkdir		= supermount_mkdir,
1127
	.rmdir		= supermount_rmdir,
1128
	.mknod		= supermount_mknod,
1129
	.rename		= supermount_rename,
1130
	.permission	= supermount_permission,
1131
	.setattr	= supermount_setattr,
1132
	.getattr	= supermount_getattr,
1133
};
1134
1135
struct inode_operations supermount_symlink_iops = {
1136
	.readlink	= supermount_readlink,
1137
	.follow_link	= supermount_follow_link,
1138
	.setattr	= supermount_setattr,
1139
	.getattr	= supermount_getattr,
1140
};
1141
1142
struct inode_operations supermount_file_iops = {
1143
	.setattr	= supermount_setattr,
1144
	.getattr	= supermount_getattr,
1145
};
(-)linux-2.6.25.4.orig/fs/supermount/proc.c (+289 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/proc.c
3
 *
4
 *  Initial version for kernel 2.4.21 (C) 2003 Andrey Borzenkov
5
 *                                             (arvidjaar@mail.ru)
6
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
7
 *                                       (arvidjaar@mail.ru)
8
 *
9
 *  $Id: proc.c,v 1.7.4.4 2003/10/26 16:21:25 bor Exp $
10
 */
11
12
#include "supermount.h"
13
14
#ifdef CONFIG_PROC_FS
15
16
/*
17
 * we use semaphore because we have to lock subfs inside and it can
18
 * sleep. Unlocking procfs list would mean adding generic usage count
19
 * management to sbi and this is far too fetching
20
 */
21
22
static DECLARE_MUTEX(supermount_proc_sem);
23
static struct proc_dir_entry *supermount_proc_root;
24
static struct proc_dir_entry *supermount_proc_subfs;
25
static struct proc_dir_entry *supermount_proc_version;
26
static struct supermount_sb_info *supermount_list_head;
27
28
#define SKIP_BLANKS(s)	while(*s == ' ' || *s == '\t' || *s == '\n') s++
29
#define CHECK_COUNT do { \
30
	size += n; \
31
	count -= n; \
32
	if (count <= 0) { \
33
		subfs_unlock(sbi->host); \
34
		break; \
35
	} \
36
} while (0)
37
38
/* iterator; shamelessly copied over from pci.c */
39
static void *supermount_seq_start(struct seq_file *sf, loff_t *pos)
40
{
41
        struct supermount_sb_info *sbi;
42
        loff_t n = *pos;
43
44
	down(&supermount_proc_sem);
45
46
        sbi = supermount_list_head;
47
        while (n-- && sbi)
48
                sbi = sbi->next;
49
50
        return sbi;
51
}
52
53
static void *supermount_seq_next(struct seq_file *sf, void *v, loff_t *pos)
54
{
55
        struct supermount_sb_info *sbi = v;
56
        (*pos)++;
57
        return sbi->next;
58
}
59
60
static void supermount_seq_stop(struct seq_file *sf, void *v)
61
{
62
	up(&supermount_proc_sem);
63
}
64
65
66
static int
67
supermount_show_sbi(struct seq_file *sf, void *v)
68
{
69
	struct supermount_sb_info *sbi = v;
70
71
72
	subfs_lock(sbi->host);
73
	seq_puts(sf, sbi->devname);
74
	if (sbi->disabled)
75
		seq_puts(sf, " disabled\n");
76
	else if (subfs_is_mounted(sbi->host))
77
		seq_printf(sf, " mounted %d %d\n",
78
				sbi->readcount, sbi->writecount);
79
	else
80
		seq_puts(sf, " unmounted\n");
81
	subfs_unlock(sbi->host);
82
83
	return 0;
84
}
85
86
static struct seq_operations supermount_proc_subfs_op = {
87
        start:  supermount_seq_start,
88
        next:   supermount_seq_next,
89
        stop:   supermount_seq_stop,
90
        show:   supermount_show_sbi
91
};
92
93
static int supermount_proc_subfs_open(struct inode *inode, struct file *file)
94
{
95
        return seq_open(file, &supermount_proc_subfs_op);
96
}
97
98
/*
99
 * mostly copied over from drivers/scsi/scsi.c:proc_scsi_gen_write()
100
 */
101
static int
102
supermount_proc_subfs_write(struct file *file, const char *buf, size_t length, loff_t *offset)
103
{
104
	char *buffer, *s, *dev = 0;
105
	int disable = 0, enable = 0, release = 0, force = 0;
106
	struct supermount_sb_info *sbi;
107
	size_t rc;
108
109
	rc = -EINVAL;
110
	if (!buf || length > PAGE_SIZE)
111
		goto out;
112
113
	rc = -ENOMEM;
114
	if (!(s = buffer = (char *)__get_free_page(GFP_KERNEL)))
115
		goto out;
116
117
	rc =-EFAULT;
118
	if(copy_from_user(buffer, buf, length))
119
		goto free_buffer;
120
121
	rc = -EINVAL;
122
	if (length < PAGE_SIZE)
123
		buffer[length] = '\0';
124
	else if (buffer[PAGE_SIZE-1])
125
		goto free_buffer;
126
127
	/*
128
	 * echo "/dev/cdrom [enable|disable] [release [force]]" > \
129
	 * 				/proc/fs/supermount/subfs
130
	 */
131
132
	do {
133
		char *p;
134
135
		SKIP_BLANKS(s);
136
		p = strpbrk(s, " \t\n");
137
		if (p)
138
			*p++ = '\0';
139
		if (!dev)
140
			dev = s;
141
		else if (!strcmp(s, "disable"))
142
			disable = 1;
143
		else if (!strcmp(s, "enable"))
144
			enable = 1;
145
		else if (!strcmp(s, "release"))
146
			release = 1;
147
		else if (!strcmp(s, "force"))
148
			force = 1;
149
		else
150
			goto free_buffer;
151
152
		s = p;
153
	} while (s && *s);
154
155
	if ((enable && disable) || (force && !release))
156
		goto free_buffer;
157
158
	down(&supermount_proc_sem);
159
	for(sbi = supermount_list_head; sbi; sbi = sbi->next) {
160
		if (strcmp(sbi->devname, dev))
161
			continue;
162
163
		subfs_lock(sbi->host);
164
165
		rc = length;
166
		if (release && subfs_is_mounted(sbi->host)) {
167
			if (!subfs_is_busy(sbi->host) || force)
168
				subfs_umount(sbi->host, SUBFS_UMNT_USER);
169
			else
170
				rc = -EBUSY;
171
		}
172
		
173
		if (disable && subfs_is_mounted(sbi->host))
174
			rc = -EBUSY;
175
176
		if (rc >= 0) {
177
			if (disable)
178
				sbi->disabled = 1;
179
			else if (enable)
180
				sbi->disabled = 0;
181
		}
182
183
		subfs_unlock(sbi->host);
184
		break;
185
	}
186
	up(&supermount_proc_sem);
187
188
free_buffer:
189
	free_page((unsigned long)buffer);
190
out:
191
	return rc;
192
193
}
194
195
static struct file_operations supermount_proc_subfs_operations = {
196
        open:           supermount_proc_subfs_open,
197
        read:           seq_read,
198
        llseek:         seq_lseek,
199
        release:        seq_release,
200
	write:		supermount_proc_subfs_write,
201
};
202
203
static int
204
supermount_proc_version_read(char *page, char **start, off_t pos, int count, int *eof, void *data)
205
{
206
	int rc;
207
208
	rc = snprintf(page, count, "Supermount version %s for kernel 2.6\n",
209
				    SUPERMOUNT_VERSION);
210
	*eof = 1;
211
	return rc;
212
}
213
214
void
215
supermount_proc_register(void)
216
{
217
	supermount_proc_root = proc_mkdir("fs/supermount", 0);
218
	if (!supermount_proc_root) {
219
		printk(KERN_ERR "SUPERMOUNT failed to create /proc/fs/supermount");
220
		return;
221
	}
222
	supermount_proc_root->owner = THIS_MODULE;
223
224
	supermount_proc_version = create_proc_read_entry("version",
225
                                        S_IFREG | S_IRUGO,
226
                                        supermount_proc_root,
227
					supermount_proc_version_read,
228
					0);
229
230
	if (supermount_proc_version)
231
		supermount_proc_version->owner = THIS_MODULE;
232
	else
233
		printk(KERN_ERR
234
		"SUPERMOUNT failed to create /proc/fs/supermount/version");
235
236
	supermount_proc_subfs = create_proc_entry("subfs",
237
                                        S_IFREG | S_IRUGO | S_IWUSR,
238
                                        supermount_proc_root);
239
240
	if (supermount_proc_subfs) {
241
		supermount_proc_subfs->proc_fops =
242
			&supermount_proc_subfs_operations;
243
		supermount_proc_subfs->owner = THIS_MODULE;
244
	} else
245
		printk(KERN_ERR
246
		"SUPERMOUNT failed to create /proc/fs/supermount/subfs");
247
248
}
249
250
void
251
supermount_proc_unregister(void)
252
{
253
	remove_proc_entry("fs/supermount/subfs", 0);
254
	remove_proc_entry("fs/supermount/version", 0);
255
	remove_proc_entry("fs/supermount", 0);
256
}
257
258
void
259
supermount_proc_insert(struct supermount_sb_info *sbi)
260
{
261
262
	down(&supermount_proc_sem);
263
264
	sbi->next = supermount_list_head;
265
	supermount_list_head = sbi;
266
267
	up(&supermount_proc_sem);
268
}
269
270
void
271
supermount_proc_remove(struct supermount_sb_info *sbi)
272
{
273
	struct supermount_sb_info **p, *q;
274
275
	down(&supermount_proc_sem);
276
277
	for(p = &supermount_list_head, q = supermount_list_head;
278
			q; p = &q->next, q = q->next)
279
		if (q == sbi)
280
			break;
281
282
	if (q)
283
		*p = q->next;
284
285
	up(&supermount_proc_sem);
286
287
	SUPERMOUNT_BUG_ON(!q);
288
}
289
#endif /* CONFIG_PROC_FS */
(-)linux-2.6.25.4.orig/fs/supermount/subfs.c (+742 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/subfs.c
3
 *
4
 *  Original version:
5
 *      Copyright (C) 1995, 1997
6
 *      Stephen Tweedie (sct@dcs.ed.ac.uk)
7
 *
8
 *      from
9
 *
10
 *      linux/fs/minix/inode.c
11
 *      Copyright (C) 1991, 1992  Linus Torvalds
12
 *
13
 *      and
14
 *
15
 *      linux/fs/ext2/super.c
16
 *      Copyright (C) 1992, 1993, 1994, 1995  Remy Card
17
 *
18
 *  Rewriten for kernel 2.2, 2.4. (C) 1999, 2000 Alexis Mikhailov
19
 *                                    (alexis@abc.cap.ru)
20
 *  Rewritten for kernel 2.4.21 (C) 2003 Andrey Borzenkov
21
 *                                       (arvidjaar@mail.ru)
22
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
23
 *                                       (arvidjaar@mail.ru)
24
 *
25
 *  $Id: subfs.c,v 1.29.2.11 2004/01/14 19:24:10 bor Exp $
26
 */
27
28
#define S_DBG_TRACE_CURRENT S_DBG_TRACE_SUBFS
29
#include "supermount.h"
30
31
/*
32
 * close all open files on subfs
33
 */
34
static void
35
supermount_clean_files(struct super_block *sb)
36
{
37
	struct supermount_sb_info *sbi = supermount_sbi(sb);
38
	struct list_head *ptr, *n;
39
40
	ENTER(sb);
41
42
	list_for_each_safe(ptr, n, &sbi->s_files) {
43
		struct supermount_file_info *sfi;
44
		struct file *subfile;
45
46
		sfi = list_entry(ptr, struct supermount_file_info, list);
47
48
		subfile = sfi->file;
49
		sfi->file = 0;
50
		list_del_init(&sfi->list);
51
52
		SUPERMOUNT_BUG_LOCKED_ON(sb, !subfile);
53
54
		fput(subfile);
55
	}
56
57
	LEAVE(sb);
58
59
}
60
61
/*
62
 * close all open dentries on subfs
63
 */
64
static void
65
supermount_clean_dentries(struct super_block *sb)
66
{
67
	struct supermount_sb_info *sbi = supermount_sbi(sb);
68
	struct list_head *ptr, *n;
69
70
	ENTER(sb);
71
72
	list_for_each_safe(ptr, n, &sbi->s_dentries) {
73
		struct supermount_dentry_info *sdi;
74
		struct dentry *subdent;
75
76
		sdi = list_entry(ptr, struct supermount_dentry_info, list);
77
		/*
78
		 * HACK - FIXME
79
		 * see dentry.c:supermount_d_compare
80
		 */
81
		write_lock(&d_compare_lock);
82
		subdent = sdi->dentry;
83
		sdi->dentry = 0;
84
		write_unlock(&d_compare_lock);
85
86
		list_del_init(&sdi->list);
87
		d_drop(sdi->host);
88
		dnotify_parent(sdi->host, DN_DELETE);
89
90
		SUPERMOUNT_BUG_LOCKED_ON(sb, !subdent);
91
92
		dput(subdent);
93
	}
94
95
	LEAVE(sb);
96
97
}
98
99
/*
100
 * close all open inodes on subfs
101
 */
102
static void
103
supermount_clean_inodes(struct super_block *sb)
104
{
105
	struct supermount_sb_info *sbi = supermount_sbi(sb);
106
	struct list_head *ptr, *n;
107
108
	ENTER(sb);
109
110
	list_for_each_safe(ptr, n, &sbi->s_inodes) {
111
		struct supermount_inode_info *sii;
112
		struct inode *host;
113
		struct inode *subi;
114
115
		sii = list_entry(ptr, struct supermount_inode_info, list);
116
		host = &sii->vfs_inode;
117
118
		subi = sii->inode;
119
		sii->inode = NULL;
120
		list_del_init(&sii->list);
121
		remove_inode_hash(host);
122
		host->i_mapping = &host->i_data;
123
124
		/*
125
		 * it is possible to have no subi here. clear_inode does
126
		 * release lock after removing subi but before unlinking
127
		 * it
128
		 */
129
		if (subi)
130
			iput(subi);
131
132
		SUPERMOUNT_BUG_LOCKED_ON(sb, sii->writecount < 0);
133
		SUPERMOUNT_BUG_LOCKED_ON(sb, sii->readcount < 0);
134
		while (sii->writecount) {
135
			sii->writecount--;
136
			sbi->writecount--;
137
		}
138
		while (sii->readcount) {
139
			sii->readcount--;
140
			sbi->readcount--;
141
		}
142
	}
143
144
	LEAVE(sb);
145
}
146
147
/*
148
 * reason can be
149
 *   SUBFS_UMNT_NORMAL - normal umount, do not try to release subfs
150
 *   SUBFS_UMNT_MEDIA  - media change detected, release subfs,
151
 *   			 do not remount ro (as media is already gone)
152
 *   SUBFS_UMNT_USER   - user request, release subfs, remount ro before
153
 *   			 releasing tray lock
154
 *
155
 *   unlock_door is always needed to keep device usage count correct
156
 */
157
static int subfs_remount_ro(struct super_block *sb);
158
void
159
subfs_umount(struct super_block *sb, int reason)
160
{
161
	struct supermount_sb_info *sbi = supermount_sbi(sb);
162
	int writecount = sbi->writecount;
163
164
	ENTER(sb);
165
166
	if (reason != SUBFS_UMNT_NORMAL) {
167
		/*
168
		 * we used to did shrink_dcache here. It compicates locking
169
		 * (clear_inode is called under sbi->sem thus requiring either
170
		 * recursive lock or separate lock just for inode list).
171
		 * This is not needed any more to ensure subfs can be umounted
172
		 * so we let dentries die and rely on dentry_revalidate to
173
		 * reject stale dentries
174
		 */
175
176
		if (subfs_is_busy(sb))
177
			supermount_warning(sb, "opened files during media change");
178
179
		supermount_clean_files(sb);
180
		supermount_clean_dentries(sb);
181
		supermount_clean_inodes(sb);
182
183
		if (reason == SUBFS_UMNT_USER && writecount > 0)
184
			subfs_remount_ro(sb);
185
		if (sbi->lockcount > 0)
186
			supermount_unlock_door(sb);
187
		/*
188
		 * this is quite ugly but so far I have no idea how to
189
		 * do it cleanly
190
		 */
191
		sbi->lockcount = 0;
192
	}
193
194
	/*
195
	 * all files are expected to be closed
196
	 */
197
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->writecount);
198
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->readcount);
199
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->lockcount);
200
	SUPERMOUNT_BUG_LOCKED_ON(sb, !list_empty(&sbi->s_files));
201
	SUPERMOUNT_BUG_LOCKED_ON(sb, !list_empty(&sbi->s_dentries));
202
	SUPERMOUNT_BUG_LOCKED_ON(sb, !list_empty(&sbi->s_inodes));
203
204
	unmark_media_supermounted(sb);
205
	mntput(sbi->s_undermount);
206
	sbi->s_undermount = NULL;
207
	if (sbi->rw)
208
		sb->s_flags &= ~MS_RDONLY;
209
	sb->s_blocksize = 1024;
210
	sb->s_blocksize_bits = 10;
211
212
	/*
213
	 * FIXME
214
	 * again the problem of unmounting subfs from inside of put_super
215
	 */
216
	if (sb->s_root)
217
		supermount_init_root_inode(sb->s_root->d_inode);
218
219
	LEAVE(sb);
220
}
221
222
static int
223
subfs_remount_ro(struct super_block *sb)
224
{
225
	struct super_block *subsb = subfs_sb(sb);
226
	int rc;
227
228
	ENTER(sb);
229
230
	rc = do_remount_sb(subsb, subsb->s_flags | MS_RDONLY, NULL, 0);
231
232
	LEAVE(sb);
233
234
	return rc;
235
}
236
237
static int
238
subfs_remount_rw(struct super_block *sb)
239
{
240
	struct super_block *subsb = subfs_sb(sb);
241
	int rc;
242
243
	ENTER(sb);
244
245
	rc = do_remount_sb(subsb, subsb->s_flags & ~MS_RDONLY, NULL, 0);
246
247
	LEAVE(sb);
248
249
	return rc;
250
}
251
252
static struct vfsmount *
253
subfs_real_mount(struct super_block *sb, char *type)
254
{
255
	struct supermount_sb_info *sbi = supermount_sbi(sb);
256
	struct vfsmount *mnt;
257
	char *opts = NULL;
258
259
	ENTER(sb, "type=%s", type);
260
261
	if (sbi->s_data) {
262
		opts = strdup(sbi->s_data);
263
		if (!opts) {
264
			mnt = ERR_PTR(-ENOMEM);
265
			goto fail;
266
		}
267
	}
268
269
	mnt = do_kern_mount(type,
270
			    (sb->s_flags & MS_RMT_MASK) | MS_SUPERMOUNTED,
271
			    sbi->devname, opts);
272
	if (opts)
273
		kfree(opts);
274
275
fail:
276
	LEAVE(sb, "submnt=%p", mnt);
277
278
	return mnt;
279
}
280
281
static int
282
subfs_real_mount2(struct super_block *sb, char *type)
283
{
284
	struct supermount_sb_info *sbi = supermount_sbi(sb);
285
	struct vfsmount *mnt;
286
	struct super_block *subsb;
287
	int rc = 0;
288
289
	ENTER(sb, "type=%s", type);
290
291
	mnt = subfs_real_mount(sb, type);
292
293
	if (IS_ERR(mnt) && PTR_ERR(mnt) == -EROFS) {
294
		sb->s_flags |= MS_RDONLY;
295
		mnt = subfs_real_mount(sb, type);
296
	}
297
	rc = PTR_ERR(mnt);
298
	if (IS_ERR(mnt))
299
		goto out;
300
301
	/* paranoid check for double-mounting */
302
	SUPERMOUNT_BUG_LOCKED_ON(sb, atomic_read(&mnt->mnt_sb->s_active) != 1);
303
304
	sbi->s_undermount = mnt;
305
306
	if (!(sb->s_flags & MS_RDONLY)) {
307
		rc = subfs_remount_ro(sb);
308
		if (rc)
309
			goto mntput;
310
	}
311
312
	subsb = mnt->mnt_sb;
313
	sb->s_blocksize = subsb->s_blocksize;
314
	sb->s_blocksize_bits = subsb->s_blocksize_bits;
315
	attach_subfs_dentry(sb->s_root, mnt->mnt_root);
316
	attach_subfs_inode(sb->s_root->d_inode, mnt->mnt_root->d_inode);
317
	insert_inode_hash(sb->s_root->d_inode);
318
	dnotify_parent(sb->s_root, DN_CREATE);
319
	rc = 0;
320
	goto out;
321
322
	/*
323
	 * error clean up
324
	 */
325
mntput:
326
	sbi->s_undermount = 0;
327
	mntput(mnt);
328
out:
329
	LEAVE(sb, "type=%s rc=%d", type, rc);
330
331
	return rc;
332
}
333
334
/*
335
 * Error values from mount
336
 *   ENOENT     - no device file (quite possible with devfs)
337
 *   ENXIO      - device does not exist
338
 *   ENOMEDIUM  - no medium inserted (surprise, surprise :)
339
 *   EBUSY      - attempt to mount on already mounted device
340
 *                we specifically disallow it even when both
341
 *                file system and mode (ro/rw) are the same
342
 */
343
static int
344
subfs_mount(struct super_block *sb)
345
{
346
	struct supermount_sb_info *sbi = supermount_sbi(sb);
347
	int retval = -ENODEV;
348
	char *types = strdup(sbi->s_type);
349
350
	ENTER(sb);
351
352
	if (sbi->disabled)
353
		retval = -EPERM;
354
	else if (!types)
355
	       retval = -ENOMEM;
356
	else {
357
		char *p = types, *fs;
358
359
		while ((fs = strsep(&p, ":")) != NULL && retval
360
		       && retval != -ENXIO
361
		       && retval != -ENOMEDIUM
362
		       && retval != -ENOENT
363
		       && retval != -EBUSY)
364
			retval = subfs_real_mount2(sb, fs);
365
	}
366
367
	if (types)
368
		kfree(types);
369
370
	if (!retval)
371
		mark_media_supermounted(sb);
372
373
	LEAVE(sb, "rc=%d", retval);
374
375
	return retval;
376
}
377
378
static int
379
__subfs_check_disk_change(struct super_block *sb)
380
{
381
	struct super_block *subsb = subfs_sb(sb);
382
	int rc;
383
	struct block_device *dev = subsb->s_bdev;
384
385
	ENTER(sb);
386
387
	rc = atomic_read(&subsb->s_media_changed);
388
	if (!rc) {
389
		lock_kernel();
390
		rc = check_disk_change(dev);
391
		unlock_kernel();
392
	}
393
394
	if (rc)
395
		subfs_umount(sb, SUBFS_UMNT_MEDIA);
396
397
	LEAVE(sb, "rc=%d", rc);
398
399
	return rc;
400
}
401
402
/*
403
 * this must really be called subfs_active ...
404
 */
405
int
406
subfs_check_disk_change(struct super_block *sb)
407
{
408
	int rc;
409
410
	ENTER(sb);
411
412
	subfs_lock(sb);
413
	if (subfs_is_mounted(sb))
414
		rc = __subfs_check_disk_change(sb);
415
	else
416
		rc = 1;
417
	subfs_unlock(sb);
418
419
420
	LEAVE(sb, "rc=%d", rc);
421
422
	return rc;
423
}
424
425
static int
426
check_and_remount_subfs(struct super_block *sb)
427
{
428
	int rc;
429
430
	ENTER(sb);
431
432
	if (subfs_is_mounted(sb) && !__subfs_check_disk_change(sb)) {
433
		rc = 0;
434
		goto out;
435
	}
436
437
	rc = subfs_mount(sb);
438
439
out:
440
	LEAVE(sb, "rc=%d", rc);
441
442
	return rc;
443
}
444
445
static void
446
subfs_tray_lock(struct super_block *sb)
447
{
448
	struct supermount_sb_info *sbi = supermount_sbi(sb);
449
450
	ENTER(sb);
451
452
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->lockcount < 0);
453
454
	if (!sbi->lockcount++)
455
		supermount_lock_door(sb);
456
457
	LEAVE(sb);
458
}
459
460
static void
461
subfs_tray_unlock(struct super_block *sb)
462
{
463
	struct supermount_sb_info *sbi = supermount_sbi(sb);
464
465
	ENTER(sb);
466
467
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->lockcount <= 0);
468
469
	if (!--sbi->lockcount)
470
		supermount_unlock_door(sb);
471
472
	LEAVE(sb);
473
}
474
475
static void
476
subfs_get_read_access(struct super_block *sb)
477
{
478
	struct supermount_sb_info *sbi = supermount_sbi(sb);
479
480
	ENTER(sb);
481
482
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->readcount < 0);
483
484
	if (!sbi->readcount++ && sbi->tray_lock == TRAY_LOCK_ALWAYS)
485
		subfs_tray_lock(sb);
486
487
	LEAVE(sb);
488
}
489
490
static int
491
subfs_get_write_access(struct super_block *sb)
492
{
493
	struct supermount_sb_info *sbi = supermount_sbi(sb);
494
	int rc;
495
496
	ENTER(sb);
497
498
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->writecount < 0);
499
500
	rc = 0;
501
	if (!sbi->writecount) {
502
		if (sb->s_flags & MS_RDONLY)
503
			rc = -EROFS;
504
		else
505
			rc = subfs_remount_rw(sb);
506
	}
507
508
	if (!rc && !sbi->writecount++ && sbi->tray_lock != TRAY_LOCK_NEVER)
509
		subfs_tray_lock(sb);
510
511
	LEAVE(sb, "rc=%d", rc);
512
513
	return rc;
514
}
515
516
static void
517
subfs_put_read_access(struct super_block *sb)
518
{
519
	struct supermount_sb_info *sbi = supermount_sbi(sb);
520
521
	ENTER(sb);
522
523
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->readcount <= 0);
524
525
	if (!--sbi->readcount && sbi->tray_lock == TRAY_LOCK_ALWAYS)
526
		subfs_tray_unlock(sb);
527
528
	LEAVE(sb);
529
}
530
531
static void
532
subfs_put_write_access(struct super_block *sb)
533
{
534
	struct supermount_sb_info *sbi = supermount_sbi(sb);
535
536
	ENTER(sb);
537
538
	SUPERMOUNT_BUG_LOCKED_ON(sb, sbi->writecount <= 0);
539
540
	if (!--sbi->writecount) {
541
		/*
542
		 * no need to fsync, it is done automatically on remount
543
		 */
544
		int rc = subfs_remount_ro(sb);
545
		if (rc)
546
			supermount_error(sb, "failed to remount ro, error = %d", rc);
547
		if (sbi->tray_lock != TRAY_LOCK_NEVER)
548
			subfs_tray_unlock(sb);
549
	}
550
551
	LEAVE(sb);
552
}
553
554
int
555
subfs_get_access(struct inode *inode, int rw)
556
{
557
	struct super_block *sb = inode->i_sb;
558
	int rc = 0;
559
	
560
	ENTER(sb);
561
562
	subfs_lock(sb);
563
	if (is_inode_obsolete(inode))
564
		rc = -ESTALE;
565
	else {
566
		struct supermount_inode_info *sii = supermount_i(inode);
567
568
		if (rw) {
569
			SUPERMOUNT_BUG_LOCKED_ON(sb, sii->writecount < 0);
570
			rc = subfs_get_write_access(sb);
571
			if (!rc)
572
				sii->writecount++;
573
		} else {
574
			SUPERMOUNT_BUG_LOCKED_ON(sb, sii->readcount < 0);
575
			subfs_get_read_access(sb);
576
			sii->readcount++;
577
		}
578
	}
579
	subfs_unlock(sb);
580
581
	LEAVE(sb, "rc=%d", rc);
582
583
	return rc;
584
}
585
586
void
587
subfs_put_access(struct inode *inode, int rw)
588
{
589
	struct super_block *sb = inode->i_sb;
590
591
	ENTER(sb);
592
593
	subfs_lock(sb);
594
	if (!is_inode_obsolete(inode)) {
595
		struct supermount_inode_info *sii = supermount_i(inode);
596
597
		if (rw) {
598
			SUPERMOUNT_BUG_LOCKED_ON(sb, sii->writecount <= 0);
599
			sii->writecount--;
600
			subfs_put_write_access(sb);
601
		} else {
602
			SUPERMOUNT_BUG_LOCKED_ON(sb, sii->readcount <= 0);
603
			sii->readcount--;
604
			subfs_put_read_access(sb);
605
		}
606
607
	}
608
	subfs_unlock(sb);
609
610
	LEAVE(sb);
611
}
612
613
struct vfsmount *
614
subfs_go_online(struct super_block *sb)
615
{
616
	int rc;
617
	struct vfsmount *mnt;
618
619
	ENTER(sb);
620
621
	subfs_lock(sb);
622
623
	rc = check_and_remount_subfs(sb);
624
	mnt = ERR_PTR(rc);
625
	if (!rc)
626
		mnt = mntget(subfs_mnt(sb));
627
	subfs_unlock(sb);
628
629
	LEAVE(sb, "mnt=%p", mnt);
630
631
	return mnt;
632
}
633
634
void
635
subfs_go_offline(struct super_block *sb, struct vfsmount *mnt)
636
{
637
	ENTER(sb);
638
639
	SUPERMOUNT_BUG_ON(!mnt);
640
	mntput(mnt);
641
642
	LEAVE(sb);
643
644
}
645
646
struct vfsmount *
647
subfs_prevent_umount(struct super_block *sb)
648
{
649
	struct vfsmount *mnt;
650
651
	ENTER(sb);
652
653
	subfs_lock(sb);
654
	mnt = subfs_mnt(sb);
655
	if (mnt)
656
		mnt = mntget(mnt);
657
	subfs_unlock(sb);
658
659
	LEAVE(sb, "mnt=%p", mnt);
660
661
	return mnt;
662
}
663
664
void
665
subfs_allow_umount(struct super_block *sb, struct vfsmount *mnt)
666
{
667
	ENTER(sb);
668
669
	SUPERMOUNT_BUG_ON(!mnt);
670
	mntput(mnt);
671
672
	LEAVE(sb);
673
674
}
675
676
struct vfsmount *
677
subfs_get_mnt(struct super_block *sb)
678
{
679
	struct vfsmount *mnt = NULL;
680
681
	ENTER(sb);
682
683
	subfs_lock(sb);
684
	if (subfs_is_mounted(sb))
685
		mnt = mntget(subfs_mnt(sb));
686
	subfs_unlock(sb);
687
688
	LEAVE(sb, "mnt=%p", mnt);
689
690
	return mnt;
691
}
692
693
struct super_block *
694
subfs_get_sb(struct super_block *sb)
695
{
696
	struct super_block *subsb = NULL;
697
698
	ENTER(sb);
699
700
	subfs_lock(sb);
701
	if (subfs_is_mounted(sb))
702
		subsb = subfs_sb(sb);
703
	subfs_unlock(sb);
704
705
	LEAVE(sb, "subsb=%p", subsb);
706
707
	return subsb;
708
}
709
710
/*
711
 * contrary to its name this function deals with _supermount_ inode
712
 */
713
void
714
subfs_clear_inode(struct inode *inode)
715
{
716
	struct super_block *sb = inode->i_sb;
717
	struct supermount_inode_info *sii = supermount_i(inode);
718
719
	ENTER(sb, "inode=%p", inode);
720
721
	subfs_lock(sb);
722
723
	/*
724
	 * this is safe. If subfs has been unmounted, counters has been
725
	 * set to 0 already
726
	 */
727
	while(sii->writecount > 0) {
728
		sii->writecount--;
729
		subfs_put_write_access(sb);
730
	}
731
732
	while(sii->readcount > 0) {
733
		sii->readcount--;
734
		subfs_put_read_access(sb);
735
	}
736
737
	list_del(&sii->list);
738
739
	subfs_unlock(sb);
740
741
	LEAVE(sb, "inode=%p", inode);
742
}
(-)linux-2.6.25.4.orig/fs/supermount/super.c (+648 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/supermount/super.c
3
 *
4
 *  Original version:
5
 *      Copyright (C) 1995, 1997
6
 *      Stephen Tweedie (sct@@dcs.ed.ac.uk)
7
 *
8
 *      from
9
 *
10
 *      linux/fs/minix/inode.c
11
 *      Copyright (C) 1991, 1992  Linus Torvalds
12
 *
13
 *      and
14
 *
15
 *      linux/fs/ext2/super.c
16
 *      Copyright (C) 1992, 1993, 1994, 1995  Remy Card
17
 *
18
 *  Rewriten for kernel 2.2, 2.4. (C) 1999, 2000 Alexis Mikhailov
19
 *                                    (alexis@@abc.cap.ru)
20
 *  Rewritten for kernel 2.4.21 (C) 2003 Andrey Borzenkov
21
 *                                       (arvidjaar@@mail.ru)
22
 *  Rewritten for kernel 2.5.70 (C) 2003 Andrey Borzenkov
23
 *                                       (arvidjaar@@mail.ru)
24
 *
25
 *  $Id: super.c,v 1.25.2.11 2004/01/14 19:24:10 bor Exp $
26
 */
27
28
#define S_DBG_TRACE_CURRENT S_DBG_TRACE_SUPER
29
30
#include <linux/statfs.h>
31
#include <linux/parser.h>
32
#include "supermount.h"
33
34
/*
35
 * vfat and msdos do not have any valididty checks for superblock and must
36
 * be the last entries!
37
 */
38
39
static char *default_fs_types = "udf:iso9660:ext2:vfat:msdos";
40
41
static struct super_operations supermount_sops;
42
43
/* ========================= helpers ================================= */
44
45
static inline void
46
supermount_update_inode(struct inode *superi, struct inode *subi)
47
{
48
	struct super_block *sb = superi->i_sb;
49
50
	ENTER(sb, "superi=%p subi=%p", superi, subi);
51
52
	superi->i_ino = subi->i_ino;
53
	superi->i_mode = subi->i_mode;
54
	superi->i_uid = subi->i_uid;
55
	superi->i_gid = subi->i_gid;
56
	superi->i_nlink = subi->i_nlink;
57
	superi->i_size = subi->i_size;
58
	superi->i_atime = subi->i_atime;
59
	superi->i_ctime = subi->i_ctime;
60
	superi->i_mtime = subi->i_mtime;
61
	//superi->i_blksize = subi->i_blksize;
62
	superi->i_blocks = subi->i_blocks;
63
	superi->i_rdev = subi->i_rdev;
64
	superi->i_version++;
65
	set_inode_flags(superi, subi);
66
67
	if (S_ISDIR(superi->i_mode)) {
68
		superi->i_op = &supermount_dir_iops;
69
		superi->i_fop = &supermount_dir_operations;
70
	} else if (S_ISLNK(superi->i_mode)) {
71
		superi->i_op = &supermount_symlink_iops;
72
		superi->i_mapping = subi->i_mapping;
73
	} else {
74
		superi->i_op = &supermount_file_iops;
75
		superi->i_fop = &supermount_file_operations;
76
		superi->i_mapping = subi->i_mapping;
77
	}
78
79
	LEAVE(sb, "superi=%p subi=%p", superi, subi);
80
}
81
82
/* this is also called from subfs_mount to reinstantiate root inode */
83
void
84
attach_subfs_inode(struct inode *inode, struct inode *subi)
85
{
86
	struct super_block *sb = inode->i_sb;
87
	struct supermount_sb_info *sbi = supermount_sbi(sb);
88
	struct supermount_inode_info *sii;
89
90
	ENTER(sb, "inode=%p subi=%p", inode, subi);
91
92
	sii = supermount_i(inode);
93
	if (!sii->inode) {
94
		/*
95
		 * this can be run concurrently. It is executed under
96
		 * sbi->sem so only one task would actually instantate
97
		 * inode. See namei.c:prepare_inode
98
		 * Another user is subfs.c:subfs_real_mount2
99
		 */
100
		sii->inode = igrab(subi);
101
		supermount_update_inode(inode, subi);
102
		list_add(&sii->list, &sbi->s_inodes);
103
	} else
104
		SUPERMOUNT_BUG_LOCKED_ON(sb, sii->inode != subi);
105
106
	LEAVE(sb, "inode=%p subi=%p", inode, subi);
107
}
108
109
char *
110
strdup(const char *val)
111
{
112
	char *tmp;
113
	tmp = kmalloc(1 + strlen(val), GFP_KERNEL);
114
	if (tmp)
115
		strcpy(tmp, val);
116
	return tmp;
117
}
118
119
static struct supermount_sb_info *
120
create_sbi(struct super_block *sb)
121
{
122
	struct supermount_sb_info *sbi = kmalloc(sizeof (*sbi), GFP_KERNEL);
123
124
	if (!sbi)
125
		return NULL;
126
127
	memset(sbi, 0, sizeof (*sbi));
128
129
	sbi->s_undermount = NULL;
130
	sbi->s_type = sbi->devname = sbi->s_data = NULL;
131
	INIT_LIST_HEAD(&sbi->s_inodes);
132
	INIT_LIST_HEAD(&sbi->s_files);
133
	INIT_LIST_HEAD(&sbi->s_dentries);
134
	init_MUTEX(&sbi->sem);
135
	sbi->host = sb;
136
	sbi->tray_lock = TRAY_LOCK_ONWRITE;
137
	sbi->rw = !(sb->s_flags & MS_RDONLY);
138
139
	return sbi;
140
}
141
142
static void
143
free_sbi(struct supermount_sb_info *sbi)
144
{
145
	if (sbi->s_type && sbi->s_type != default_fs_types)
146
		kfree(sbi->s_type);
147
	if (sbi->devname)
148
		kfree(sbi->devname);
149
	if (sbi->s_data)
150
		kfree(sbi->s_data);
151
	kfree(sbi);
152
}
153
154
enum {
155
	Opt_fs, Opt_fs_auto, Opt_dev, Opt_debug, Opt_debug_old, Opt_subfsopts,
156
	Opt_tray_lock_always, Opt_tray_lock_never, Opt_tray_lock_onwrite,
157
	Opt_ignore, Opt_err
158
};
159
160
static match_table_t tokens = {
161
	{Opt_fs_auto, "fs=auto"},
162
	{Opt_fs, "fs=%s"},
163
	{Opt_dev, "dev=%s"},
164
	{Opt_debug, "debug=%u"},
165
	{Opt_debug_old, "debug"},
166
	{Opt_subfsopts, "--"},
167
	{Opt_tray_lock_always, "tray_lock=always"},
168
	{Opt_tray_lock_never, "tray_lock=never"},
169
	{Opt_tray_lock_onwrite, "tray_lock=onwrite"},
170
	{Opt_ignore, "no_tray_lock"},
171
	{Opt_ignore, "fail_statfs_until_mount"},
172
	{Opt_err, NULL}
173
};
174
175
static int
176
parse_options(char *options, struct super_block *sb)
177
{
178
	struct supermount_sb_info *sbi = supermount_sbi(sb);
179
	int rc;
180
	char *p;
181
182
	if (!options)
183
		return 0;
184
185
	while ((p = strsep(&options, ",")) != NULL) {
186
		int token;
187
		substring_t args[MAX_OPT_ARGS];
188
		int n;
189
190
		/* empty option means start of subfs options */
191
		if (!*p)
192
			goto copy_subfs_options;
193
194
		token = match_token(p, tokens, args);
195
		switch(token) {
196
		case Opt_fs:
197
			sbi->s_type = match_strdup(&args[0]);
198
			if (!sbi->s_type)
199
				return -ENOMEM;
200
			break;
201
		case Opt_fs_auto:
202
			sbi->s_type = default_fs_types;
203
			break;
204
		case Opt_dev:
205
			sbi->devname = match_strdup(&args[0]);
206
			if (!sbi->devname)
207
				return -ENOMEM;
208
			break;
209
		case Opt_debug:
210
			if ((rc = match_int(&args[0], &n)))
211
				return rc;
212
			sbi->s_debug = n;
213
			break;
214
		case Opt_debug_old:
215
			sbi->s_debug = S_DBG_DEBUG;
216
			break;
217
		case Opt_tray_lock_always:
218
			sbi->tray_lock = TRAY_LOCK_ALWAYS;
219
			break;
220
		case Opt_tray_lock_onwrite:
221
			sbi->tray_lock = TRAY_LOCK_ONWRITE;
222
			break;
223
		case Opt_tray_lock_never:
224
			sbi->tray_lock = TRAY_LOCK_NEVER;
225
			break;
226
		case Opt_subfsopts:
227
copy_subfs_options:
228
			/* mount may have removed options after -- */
229
			if (options && *options) {
230
				sbi->s_data = strdup(options);
231
				if (!sbi->s_data)
232
					return -ENOMEM;
233
			}
234
			return 0;
235
			break;
236
		case Opt_ignore:
237
			break;
238
		default:
239
			supermount_error(sb, "Unrecognized mount option \"%s\"",
240
					 p);
241
			return -EINVAL;
242
			break;
243
		}
244
	}
245
246
	return 0;
247
}
248
249
void
250
supermount_init_root_inode(struct inode *inode)
251
{
252
	inode->i_mode = 0777 | S_IFDIR;
253
	inode->i_uid = current->fsuid;
254
	inode->i_gid = current->fsgid;
255
	//inode->i_blksize = inode->i_sb->s_blocksize;
256
	inode->i_rdev = MKDEV(UNNAMED_MAJOR, 0);
257
	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
258
	inode->i_size = 0;
259
	inode->i_blocks = 0;
260
	inode->i_ino = 0;
261
	inode->i_nlink = 0;
262
263
	set_inode_flags(inode, 0);
264
265
	inode->i_op = &supermount_dir_iops;
266
	inode->i_fop = &supermount_dir_operations;
267
}
268
269
static struct inode *
270
supermount_root_inode(struct super_block *sb)
271
{
272
	struct inode *inode = new_inode(sb);
273
274
	ENTER(sb);
275
276
	if (inode) {
277
		inode->i_version = 0;
278
		supermount_init_root_inode(inode);
279
	}
280
281
	LEAVE(sb, "inode=%p", inode);
282
283
	return inode;
284
}
285
286
/* ========================== used in fstype declaration ================*/
287
288
/* read_super: the main mount() entry point into the VFS layer. */
289
static int
290
supermount_read_super(struct super_block *sb, void *data, int silent)
291
{
292
	struct inode *root_inode;
293
	struct dentry *root;
294
	struct supermount_sb_info *sbi = create_sbi(sb);
295
	int rc = -ENOMEM;
296
297
	if (!sbi)
298
		goto fail_no_memory;
299
300
	sb->s_fs_info = sbi;
301
302
	rc = parse_options((char *) data, sb);
303
	if (rc)
304
		goto fail_parsing;
305
306
	rc = -EINVAL;
307
	if (!sbi->devname) {
308
		supermount_error(sb, "no dev=<device> option");
309
		goto fail_parsing;
310
	}
311
312
	if (!sbi->s_type) {
313
		sbi->s_type = default_fs_types;
314
		supermount_warning(sb, "no fs=<filesystem> option, assuming fs=auto");
315
	}
316
317
	rc = -ENOMEM;
318
319
	sb->s_blocksize = 1024;
320
	sb->s_blocksize_bits = 10;
321
	sb->s_magic = SUPERMOUNT_SUPER_MAGIC;
322
	sb->s_op = &supermount_sops;
323
324
	root_inode = supermount_root_inode(sb);
325
	if (!root_inode)
326
		goto fail_allocating_root_inode;
327
328
	root = d_alloc_root(root_inode);
329
	if (!root)
330
		goto fail_allocating_root_dentry;
331
	if (init_dentry_info(root))
332
		goto fail_init_root_info;
333
334
	sb->s_root = root;
335
336
	supermount_proc_insert(sbi);
337
338
	return 0;
339
340
fail_init_root_info:
341
	dput(root);
342
fail_allocating_root_dentry:
343
	iput(root_inode);
344
fail_parsing:
345
fail_allocating_root_inode:
346
	free_sbi(sbi);
347
348
fail_no_memory:
349
	return rc;
350
}
351
352
struct super_block *supermount_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt)
353
{
354
        return get_sb_nodev(fs_type, flags, data, supermount_read_super,mnt);
355
}
356
357
/* ======================= super_operations methods ==================== */
358
359
static struct inode *
360
supermount_alloc_inode(struct super_block *sb)
361
{
362
	struct supermount_inode_info *sii = kmalloc(sizeof(*sii), GFP_KERNEL);
363
	struct inode *inode = 0;
364
365
	ENTER(sb);
366
367
	if (sii) {
368
		INIT_LIST_HEAD(&sii->list);
369
		sii->inode = 0;
370
		sii->readcount = 0;
371
		sii->writecount = 0;
372
		inode = &sii->vfs_inode;
373
		inode_init_once(inode);
374
	}
375
376
	LEAVE(sb, "inode=%p", inode);
377
378
	return inode;
379
}
380
381
static void
382
supermount_destroy_inode(struct inode *inode)
383
{
384
	struct super_block *sb = inode->i_sb;
385
	struct supermount_inode_info *sii = supermount_i(inode);
386
387
	ENTER(sb, "inode=%p", inode);
388
389
	kfree(sii);
390
391
	ENTER(sb, "inode=%p", inode);
392
}
393
394
/*
395
 * FIXME
396
 * I am still unsure if (or why) this functions is needed; it is likely
397
 * to go away. So far the only _real_ user seems to be knfsd.
398
 */
399
static void
400
supermount_write_inode(struct inode *inode, int sync)
401
{
402
	struct super_block *sb = inode->i_sb;
403
	struct super_block *subsb;
404
	struct inode *subi;
405
	struct vfsmount *submnt;
406
407
	ENTER(sb);
408
409
	if (subfs_check_disk_change(sb))
410
		goto out;
411
412
	submnt = subfs_prevent_umount(sb);
413
	if (!submnt)
414
		goto out;
415
416
	subi = get_subfs_inode(inode);
417
	if (IS_ERR(subi))
418
		goto allow_umount;
419
420
	subsb = subfs_get_sb(sb);
421
	if (!sb)
422
		goto put_subi;
423
424
	if (subsb->s_op && subsb->s_op->write_inode) {
425
		if (subfs_get_access(inode, 1))
426
			goto put_subi;
427
428
		write_inode_now(subi, sync);
429
430
		subfs_put_access(inode, 1);
431
	}
432
put_subi:
433
	iput(subi);
434
allow_umount:
435
	subfs_allow_umount(sb, submnt);
436
out:
437
	LEAVE(sb);
438
439
	return;
440
}
441
442
/*
443
 * FIXME
444
 * subfs_umount has no business here
445
 * it should be moved into umount_begin; in this case force umount will
446
 * free subfs (and give false No medium as error ... oh, well)
447
 */
448
static void
449
supermount_put_super(struct super_block *sb)
450
{
451
	struct supermount_sb_info *sbi = supermount_sbi(sb);
452
453
	ENTER(sb);
454
455
	subfs_lock(sb);
456
	if (subfs_is_mounted(sb))
457
		subfs_umount(sb, SUBFS_UMNT_NORMAL);
458
	subfs_unlock(sb);
459
460
	supermount_proc_remove(sbi);
461
462
	LEAVE(sb);
463
464
	sb->s_fs_info = 0;
465
	free_sbi(sbi);
466
}
467
468
/*
469
 * The following has to be done in two steps (unfortunately)
470
 * First make sure iput(subi) is run just once - and then put
471
 * read/write access and finally remove inode from list
472
 *
473
 * We can't do it in one shot because removing inode from list
474
 * will remove also possibility to mark it stale. It has been 
475
 * introduced by me :( removing generation numbers. OTOH so far
476
 * it is the only place that needs extra treatment because of it.
477
 */
478
static void
479
supermount_clear_inode(struct inode *inode)
480
{
481
	struct supermount_inode_info *sii = supermount_i(inode);
482
	struct super_block *sb = inode->i_sb;
483
	struct inode *subi;
484
	struct vfsmount *mnt;
485
486
	ENTER(sb, "inode=%p", inode);
487
488
	mnt = subfs_prevent_umount(sb);
489
	if (!mnt)
490
		goto out;
491
492
	subfs_lock(sb);
493
	subi = sii->inode;
494
	sii->inode = 0;
495
	subfs_unlock(sb);
496
497
498
	if (subi) {
499
		/*
500
		 * we used to check for subi->i_count != 1 here.
501
		 * This does not actually work - it is quite possible
502
		 * that inode has been looked up while we were in this
503
		 * function. So just ignore it (the worst thing that
504
		 * may happen is that subfs cannot be remounted)
505
		 */
506
507
		iput(subi);
508
509
	}
510
	subfs_allow_umount(sb, mnt);
511
512
	/*
513
	 * This does not has much to do with subfs but I did not want
514
	 * to export __ functions
515
	 */
516
	subfs_clear_inode(inode);
517
out:
518
	LEAVE(sb, "inode=%p", inode);
519
}
520
/*
521
 * FIXME why it is needed?
522
 */
523
524
static void
525
supermount_write_super(struct super_block *sb)
526
{
527
	struct vfsmount *mnt;
528
529
	ENTER(sb);
530
531
	if (subfs_check_disk_change(sb))
532
		goto out;
533
534
	if (subfs_is_rw(sb)) {
535
		struct super_block *subsb;
536
537
		mnt = subfs_prevent_umount(sb);
538
		if (!mnt)
539
			goto out;
540
541
		subsb = subfs_get_sb(sb);
542
		if (subsb && subsb->s_op && subsb->s_op->write_super)
543
			subsb->s_op->write_super(subsb);
544
545
		subfs_allow_umount(sb, mnt);
546
	}
547
548
out:
549
	LEAVE(sb);
550
551
	return;
552
}
553
554
static int
555
//supermount_statfs(struct super_block *sb, struct kstatfs *buf)
556
supermount_statfs(struct dentry *dentry, struct kstatfs *buf)
557
{
558
	struct super_block *sb=dentry->d_sb;
559
	int rc = 0;
560
	struct super_block *subsb;
561
	struct vfsmount *mnt;
562
563
	ENTER(sb);
564
565
	(void)subfs_check_disk_change(sb);
566
567
	mnt = subfs_prevent_umount(sb);
568
	if (!mnt)
569
		goto out;
570
571
	subsb = subfs_get_sb(sb);
572
	if (subsb && subsb->s_op && subsb->s_op->statfs)
573
		rc = subsb->s_op->statfs(dentry, buf);
574
	if (!rc)
575
		buf->f_type = SUPERMOUNT_SUPER_MAGIC;
576
577
	subfs_allow_umount(sb, mnt);
578
out:
579
	LEAVE(sb, "rc=%d", rc);
580
581
	return rc;
582
}
583
584
static int
585
supermount_remount_fs(struct super_block *sb, int *flags, char *data)
586
{
587
	return -ENOSYS;
588
}
589
590
/*
591
 * based on fs/ntfs/inode.c:ntfs_show_options
592
 */
593
static int
594
supermount_show_options(struct seq_file *sf, struct vfsmount *mnt)
595
{
596
	struct supermount_sb_info *sbi = supermount_sbi(mnt->mnt_sb);
597
598
	seq_printf(sf, ",dev=%s", sbi->devname);
599
	seq_puts(sf, ",fs=");
600
	if (sbi->s_type == default_fs_types)
601
		seq_puts(sf, "auto");
602
	else 
603
		seq_puts(sf, sbi->s_type);
604
	seq_puts(sf, ",tray_lock=");
605
	if (sbi->tray_lock == TRAY_LOCK_ALWAYS)
606
		seq_puts(sf, "always");
607
	else if (sbi->tray_lock == TRAY_LOCK_NEVER)
608
		seq_puts(sf, "never");
609
	else if (sbi->tray_lock == TRAY_LOCK_ONWRITE)
610
		seq_puts(sf, "onwrite");
611
	else
612
		SUPERMOUNT_BUG_ON(1);
613
614
	if (sbi->s_debug)
615
		seq_printf(sf, ",debug=0x%lx", sbi->s_debug);
616
	if (sbi->s_data)
617
		seq_printf(sf, ",--,%s", sbi->s_data);
618
	return 0;
619
}
620
621
/*
622
 * ->read_inode:	not needed
623
 * ->dirty_inode:	probably not needed. It appears VFS layer never
624
 *  			calls mark_inode_dirty itself; exception is
625
 *  			UPDATE_ATIME and it is already handled specially
626
 *  			FIXME
627
 *  			It may be needed for knfsd and similar
628
 * ->put_inode:		not needed
629
 * ->delete_inode:	not needed
630
 * ->write_super:	FIXME not needed, we do not have any backing store
631
 * ->sync_fs:		not needed
632
 * ->write_super_lockfs:not needed
633
 * ->unlockfs:		not needed
634
 * ->umount_begin:	TODO maybe to move subfs_umount aways from put_super
635
 * ->fh_to_dentry:	TODO may be
636
 * ->dentry_to_fh:	TODO may be
637
 */
638
static struct super_operations supermount_sops = {
639
	.alloc_inode	= supermount_alloc_inode,
640
	.destroy_inode	= supermount_destroy_inode,
641
	.write_inode	= supermount_write_inode,
642
	.clear_inode	= supermount_clear_inode,
643
	.put_super	= supermount_put_super,
644
	.write_super	= supermount_write_super,
645
	.statfs		= supermount_statfs,
646
	.remount_fs	= supermount_remount_fs,
647
	.show_options	= supermount_show_options,
648
};
(-)linux-2.6.25.4.orig/fs/supermount/supermount.h (+508 lines)
Line 0 Link Here
1
#ifndef _SUPERMOUNT_I_H
2
#define _SUPERMOUNT_I_H
3
4
/*
5
 *  $Id: supermount.h,v 1.42.2.29 2004/01/18 18:44:25 bor Exp $
6
 */
7
8
#include <linux/module.h>
9
#include <linux/version.h>
10
11
#include <linux/slab.h>
12
#include <linux/sched.h>
13
#include <linux/errno.h>
14
#include <linux/fs.h>
15
#include <linux/list.h>
16
#include <linux/file.h>
17
#include <linux/mm.h>
18
#include <linux/poll.h>
19
#include <linux/smp_lock.h>
20
#include <linux/proc_fs.h>
21
#include <linux/seq_file.h>
22
#include <linux/dnotify.h>
23
#include <linux/mount.h>
24
#include <linux/moduleparam.h>
25
#include <linux/genhd.h>
26
#include <linux/namei.h>
27
#include <linux/supermount_media.h>
28
29
#ifdef CONFIG_SUPERMOUNT_DEBUG
30
#define SUPERMOUNT_DEBUG
31
#endif
32
/*
33
 * The supermount superblock magic number
34
 */
35
36
#define SUPERMOUNT_SUPER_MAGIC	0x9fa1
37
#define SUPERMOUNT_VERSION		"2.0.4"
38
39
#define S_DBG_DEBUG			0x001
40
#define S_DBG_TRACE_DENTRY		0x002
41
#define S_DBG_TRACE_FILE		0x004
42
#define S_DBG_TRACE_FILEMAP		0x008
43
#define S_DBG_TRACE_MEDIACTL		0x010
44
#define S_DBG_TRACE_NAMEI		0x020
45
#define S_DBG_TRACE_SUBFS		0x040
46
#define S_DBG_TRACE_SUPER		0x080
47
48
/*
49
 * The subfs umount reason
50
 */
51
#define SUBFS_UMNT_NORMAL		0 /* normal umount */
52
#define SUBFS_UMNT_MEDIA		1 /* media change detected */
53
#define SUBFS_UMNT_USER			2 /* user request */
54
55
/*
56
 * When to lock media
57
 */
58
#define TRAY_LOCK_NEVER			0
59
#define TRAY_LOCK_ONWRITE		1
60
#define TRAY_LOCK_ALWAYS		2
61
62
extern struct file_system_type supermount_fs_type;
63
64
#ifdef SUPERMOUNT_DEBUG
65
66
#define SUPERMOUNT_BUG_ON(x) BUG_ON(x)
67
#define SUPERMOUNT_BUG_LOCKED_ON(sb, x) \
68
do { \
69
	if (x) { \
70
		subfs_unlock(sb); \
71
		BUG(); \
72
	} \
73
} while (0)
74
75
#define supermount_debug(sb, args...) \
76
do { \
77
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
78
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
79
\
80
	if (supermount_dbg(sb, S_DBG_DEBUG)) { \
81
		printk("%sSUPERMOUNT DEBUG [dev=%s] <%s:%d> ", \
82
			KERN_DEBUG, dev, __FUNCTION__, __LINE__); \
83
		printk(args); \
84
		printk("\n"); \
85
	} \
86
} while(0)
87
88
#define ENTER(sb, args...) \
89
do { \
90
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
91
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
92
\
93
	if (supermount_dbg(sb, S_DBG_TRACE_CURRENT)) { \
94
		printk("%sSUPERMOUNT TRACE [dev=%s] PID=%lu ENTER %s", \
95
			KERN_DEBUG, dev, (unsigned long)current->pid, \
96
			__FUNCTION__); \
97
		printk(" " args); \
98
		printk("\n"); \
99
	} \
100
} while (0)
101
102
#define LEAVE(sb, args...) \
103
do { \
104
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
105
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
106
\
107
	if (supermount_dbg(sb, S_DBG_TRACE_CURRENT)) { \
108
		printk("%sSUPERMOUNT TRACE [dev=%s] PID=%lu LEAVE %s", \
109
			KERN_DEBUG, dev, (unsigned long)current->pid, \
110
			__FUNCTION__); \
111
		printk(" " args); \
112
		printk("\n"); \
113
	} \
114
} while (0)
115
116
#else /* SUPERMOUNT_DEBUG */
117
#define supermount_debug(f, a...) /**/
118
#define SUPERMOUNT_BUG_ON(x) do { } while (0)
119
#define SUPERMOUNT_BUG_LOCKED_ON(sb, x) do { } while (0)
120
121
#define ENTER(sb, args...) do { (void)sb; } while (0)
122
#define LEAVE(sb, args...) do { (void)sb; } while (0)
123
#endif				/* SUPERMOUNT_DEBUG */
124
125
#define supermount_warning(sb, ...) \
126
do { \
127
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
128
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
129
\
130
	printk("%sSUPERMOUNT WARNING [dev=%s] ", KERN_WARNING, dev); \
131
	printk(__VA_ARGS__); \
132
	printk("\n"); \
133
} while(0)
134
135
#define supermount_error(sb, ...) \
136
do { \
137
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
138
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
139
\
140
	printk("%sSUPERMOUNT ERROR [dev=%s] ", KERN_ERR, dev); \
141
	printk(__VA_ARGS__); \
142
	printk("\n"); \
143
} while(0)
144
145
/*
146
 * The following is drived from fs/inode.c:update_atime()
147
 */
148
/*#define NEED_WRITE_ATIME(inode) \
149
    (!(inode->i_flags & S_NOATIME) || \
150
	    (inode->i_sb->s_flags & MS_NOATIME) || \
151
	    ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
152
*/
153
#define NEED_WRITE_ATIME(inode) \
154
	(!((inode->i_flags & S_NOATIME) || \
155
	 ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) || \
156
	 IS_RDONLY(inode)))
157
158
/*
159
#define NEED_WRITE_ATIME(inode) \
160
	(!(IS_NOATIME(inode) || \
161
	 (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode)) || \
162
	 IS_RDONLY(inode)))
163
*/
164
165
/*
166
 * supermount super-block data in memory
167
 */
168
struct supermount_sb_info;
169
struct supermount_sb_info {
170
	/* == options == */
171
	unsigned long s_debug;	/* debug flags S_DBG_* */
172
	char *s_type;		/* Type of fs to be sub-mounted */
173
	char *devname;		/* Where to mount the subfs from */
174
	char *s_data;		/* Data to pass when mounting subfs */
175
	/* == end of options == */
176
	struct vfsmount *s_undermount;
177
				/* Mount point for subfs */
178
	int readcount;		/* Refcount of read access
179
				   on the filesystem */
180
	int writecount;		/* Refcount of write access
181
				   on the filesystem */
182
	int lockcount;		/* Refcount of requests to lock tray */
183
	struct list_head s_inodes;
184
				/* list of active inodes */
185
	struct list_head s_files;
186
				/* list of active files */
187
	struct list_head s_dentries;
188
				/* list of active dentries */
189
	struct semaphore sem;
190
	struct super_block *host;
191
				/* needed for procfs support */
192
	struct supermount_sb_info *next;
193
				/* list of all supermount fs */
194
	unsigned int tray_lock:2;
195
	unsigned int disabled:1;
196
	unsigned int rw:1;
197
};
198
199
static inline struct supermount_sb_info *
200
supermount_sbi(struct super_block *sb)
201
{
202
	struct supermount_sb_info *sbi;
203
	BUG_ON(!sb);
204
	BUG_ON(sb->s_type != &supermount_fs_type);
205
206
	sbi = (struct supermount_sb_info *) (sb->s_fs_info);
207
	BUG_ON(!sbi);
208
209
	return sbi;
210
}
211
212
static inline struct vfsmount *
213
subfs_mnt(struct super_block *sb)
214
{
215
	return supermount_sbi(sb)->s_undermount;
216
}
217
218
static inline struct super_block *
219
subfs_sb(struct super_block *sb)
220
{
221
	struct vfsmount *mnt = subfs_mnt(sb);
222
223
	if (mnt) return mnt->mnt_sb;
224
225
	return 0;
226
}
227
228
/* this is expected to run under sb->sem */
229
static inline int
230
subfs_is_mounted(struct super_block *sb)
231
{
232
	struct supermount_sb_info *sbi = supermount_sbi(sb);
233
234
	return sbi->s_undermount != 0;
235
}
236
237
/* this is expected to run under sb->sem */
238
static inline int
239
subfs_is_busy(struct super_block *sb)
240
{
241
	struct vfsmount *mnt = subfs_mnt(sb);
242
243
	/*
244
	 * In "normal" case mnt_count is 2. But we currently do
245
	 * not insert subfs into task namespace so count is 1
246
	 * FIXME
247
	 * This also means we do not do_umount i.e. do not run
248
	 * either umount_begin or DQUOT_OFF for subfs.
249
	 */
250
	if (mnt) return atomic_read(&mnt->mnt_count) > 1;
251
252
	return 0;
253
}
254
255
/* this is expected to run under sb->sem */
256
static inline int
257
subfs_is_rw(struct super_block *sb)
258
{
259
	struct super_block *subsb;
260
261
	if (!subfs_is_mounted(sb))
262
		return 0;
263
	
264
	subsb = subfs_sb(sb);
265
	return !(subsb->s_flags & MS_RDONLY);
266
}
267
268
static inline void
269
subfs_lock(struct super_block *sb)
270
{
271
	struct supermount_sb_info *sbi = supermount_sbi(sb);
272
273
	down(&sbi->sem);
274
}
275
276
static inline void
277
subfs_unlock(struct super_block *sb)
278
{
279
	struct supermount_sb_info *sbi = supermount_sbi(sb);
280
281
	up(&sbi->sem);
282
}
283
284
/*
285
 * query debug flags set
286
 */
287
static inline int supermount_dbg(struct super_block *sb, unsigned long flags)
288
{
289
	struct supermount_sb_info *sbi = supermount_sbi(sb);
290
291
	return sbi->s_debug & flags;
292
}
293
294
/*
295
 * supermount inode info
296
 */
297
298
struct supermount_inode_info {
299
	struct list_head list;
300
  	struct inode *inode;	/* subfs inode */
301
	int readcount;
302
	int writecount;
303
	struct inode vfs_inode;	/* superfs inode */
304
};
305
306
static inline int
307
is_inode_supermounted(struct inode *inode)
308
{
309
	return inode && inode->i_sb && inode->i_sb->s_type == &supermount_fs_type;
310
}
311
312
static inline struct supermount_inode_info *
313
supermount_i(struct inode *inode)
314
{
315
	SUPERMOUNT_BUG_ON(!is_inode_supermounted(inode));
316
317
	return list_entry(inode, struct supermount_inode_info, vfs_inode);
318
}
319
320
static inline int
321
is_inode_obsolete(struct inode *inode)
322
{
323
	struct supermount_inode_info *sii = supermount_i(inode);
324
325
	return sii->inode == 0;
326
}
327
328
static inline void
329
supermount_list_add_inode(struct inode *inode)
330
{
331
	struct supermount_inode_info *sii = supermount_i(inode);
332
333
	list_add(&(sii->list), &(supermount_sbi(inode->i_sb)->s_inodes));
334
}
335
336
/*
337
 * FIXME
338
 * Should we propagate all flags? *_QUOTA looks very possible candidate
339
 * We can't just assign them because other flags may be set by VFS
340
 */
341
#define SMNT_INODE_FLAGS (S_IMMUTABLE|S_NOATIME|S_APPEND|S_SYNC)
342
static inline void
343
set_inode_flags(struct inode *inode, struct inode *subi)
344
{
345
	inode->i_flags &= ~SMNT_INODE_FLAGS;
346
	if (subi)
347
		inode->i_flags |= (subi->i_flags & SMNT_INODE_FLAGS);
348
}
349
350
/*
351
 * supermount dentry info
352
 */
353
354
struct supermount_dentry_info {
355
	struct list_head list;
356
	struct dentry *dentry;
357
	struct dentry *host;
358
};
359
360
static inline int
361
is_dentry_supermounted(struct dentry *dentry)
362
{
363
	return (dentry && dentry->d_sb && dentry->d_sb->s_type == &supermount_fs_type);
364
}
365
366
static inline struct supermount_dentry_info *
367
supermount_d(struct dentry *dentry)
368
{
369
	SUPERMOUNT_BUG_ON(!is_dentry_supermounted(dentry));
370
	SUPERMOUNT_BUG_ON(!dentry->d_fsdata);
371
372
	return  (struct supermount_dentry_info *)dentry->d_fsdata;
373
}
374
375
static inline int
376
is_dentry_obsolete(struct dentry *dentry)
377
{
378
	struct supermount_dentry_info *sdi = supermount_d(dentry);
379
380
	return sdi->dentry == 0;
381
}
382
383
/*
384
 * Supermount file info 
385
 */
386
387
struct supermount_file_info {
388
	struct list_head	list;
389
	struct file *		host;
390
	struct file		*file;
391
	pid_t			owner;
392
	struct vm_operations_struct *vm_ops;
393
	unsigned int		fake:1;
394
};
395
396
static inline int
397
is_file_supermounted(struct file *file)
398
{
399
	return file && file->f_dentry && is_dentry_supermounted(file->f_dentry);
400
}
401
402
static inline struct supermount_file_info *
403
supermount_f(struct file *file)
404
{
405
	SUPERMOUNT_BUG_ON(!is_file_supermounted(file));
406
	SUPERMOUNT_BUG_ON(!file->f_supermount);
407
408
	return  file->f_supermount;
409
}
410
411
static inline int
412
is_file_obsolete(struct file *file)
413
{
414
	struct supermount_file_info *sfi = supermount_f(file);
415
416
	return sfi->file == NULL;
417
}
418
419
static inline int
420
is_file_fake(struct file *file)
421
{
422
	struct supermount_file_info *sfi = supermount_f(file);
423
424
	return sfi->fake;
425
}
426
427
/* dentry.c */
428
extern rwlock_t d_compare_lock;
429
extern struct dentry_operations supermount_dops;
430
extern int init_dentry_info(struct dentry *);
431
extern void attach_subfs_dentry(struct dentry *, struct dentry *);
432
extern struct dentry *get_subfs_dentry(struct dentry *dentry);
433
 
434
/* file.c */
435
extern struct file_operations supermount_dir_operations;
436
extern struct file_operations supermount_file_operations;
437
438
/* filemap.c */
439
extern struct vm_operations_struct supermount_vm_ops;
440
extern int supermount_file_mmap(struct file *, struct vm_area_struct *);
441
extern struct file *get_subfs_file(struct file*);
442
443
/* mediactl.c */
444
extern void supermount_mediactl(struct super_block *, int, int);
445
static inline void
446
supermount_lock_door(struct super_block *sb)
447
{
448
	supermount_mediactl(sb, MEDIA_LOCK, 1);
449
}
450
static inline void
451
supermount_unlock_door(struct super_block *sb)
452
{
453
	supermount_mediactl(sb, MEDIA_UNLOCK, 1);
454
}
455
456
static inline void
457
mark_media_supermounted(struct super_block *sb)
458
{
459
	supermount_mediactl(sb, SUPERMOUNT_INC_COUNT, 0);
460
	supermount_mediactl(sb, MEDIA_UNLOCK, 0);
461
}
462
463
static inline void
464
unmark_media_supermounted(struct super_block *sb)
465
{
466
	supermount_mediactl(sb, SUPERMOUNT_DEC_COUNT, 0);
467
}
468
469
/* namei.c */
470
extern struct inode_operations supermount_dir_iops;
471
extern struct inode_operations supermount_file_iops;
472
extern struct inode_operations supermount_symlink_iops;
473
extern struct inode *create_supermount_inode(struct super_block *);
474
extern struct inode *get_subfs_inode(struct inode *inode);
475
476
/* proc.c */
477
#ifdef CONFIG_PROC_FS
478
extern void supermount_proc_register(void);
479
extern void supermount_proc_unregister(void);
480
extern void supermount_proc_insert(struct supermount_sb_info *);
481
extern void supermount_proc_remove(struct supermount_sb_info *);
482
#else
483
#define supermount_proc_register() do { } while(0)
484
#define supermount_proc_unregister() do { } while(0)
485
#define supermount_proc_insert(sbi) do { } while(0)
486
#define supermount_proc_remove(sbi) do { } while(0)
487
#endif
488
489
/* subfs.c */
490
extern void subfs_umount(struct super_block *sb, int);
491
extern struct vfsmount *subfs_go_online(struct super_block *);
492
extern void subfs_go_offline(struct super_block *, struct vfsmount *);
493
extern int subfs_get_access(struct inode *, int);
494
extern void subfs_put_access(struct inode *, int);
495
extern int subfs_check_disk_change(struct super_block *);
496
extern struct vfsmount *subfs_prevent_umount(struct super_block *);
497
extern void subfs_allow_umount(struct super_block *, struct vfsmount *);
498
extern struct vfsmount *subfs_get_mnt(struct super_block *sb);
499
extern struct super_block *subfs_get_sb(struct super_block *sb);
500
extern void subfs_clear_inode(struct inode *);
501
502
/* super.c */
503
extern struct super_block *supermount_get_sb(struct file_system_type *, int, const char *, void *,struct vfsmount *mnt);
504
extern void attach_subfs_inode(struct inode *, struct inode *);
505
extern void supermount_init_root_inode(struct inode *);
506
extern char *strdup(const char *);
507
508
#endif				/* _SUPERMOUNT_I_H */
(-)linux-2.6.25.4.orig/fs/udf/super.c (-1 / +7 lines)
Lines 368-374 Link Here
368
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
368
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
369
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
369
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
370
	Opt_rootdir, Opt_utf8, Opt_iocharset,
370
	Opt_rootdir, Opt_utf8, Opt_iocharset,
371
	Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
371
	Opt_ignore, Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
372
};
372
};
373
373
374
static match_table_t tokens = {
374
static match_table_t tokens = {
Lines 397-402 Link Here
397
	{Opt_rootdir,	"rootdir=%u"},
397
	{Opt_rootdir,	"rootdir=%u"},
398
	{Opt_utf8,	"utf8"},
398
	{Opt_utf8,	"utf8"},
399
	{Opt_iocharset,	"iocharset=%s"},
399
	{Opt_iocharset,	"iocharset=%s"},
400
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
401
	/* Silently ignore NLS option */
402
	{Opt_ignore, "codepage"},
403
#endif
400
	{Opt_err,	NULL}
404
	{Opt_err,	NULL}
401
};
405
};
402
406
Lines 687-692 Link Here
687
				udf_debug("ISO9660 Volume Descriptor Set "
691
				udf_debug("ISO9660 Volume Descriptor Set "
688
					  "Terminator found\n");
692
					  "Terminator found\n");
689
				break;
693
				break;
694
			case Opt_ignore:
695
				break;
690
			default:
696
			default:
691
				udf_debug("ISO9660 VRS (%u) found\n",
697
				udf_debug("ISO9660 VRS (%u) found\n",
692
					  vsd->structType);
698
					  vsd->structType);
(-)linux-2.6.25.4.orig/include/linux/cdrom.h (+3 lines)
Lines 992-997 Link Here
992
extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi,
992
extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi,
993
		struct inode *ip, unsigned int cmd, unsigned long arg);
993
		struct inode *ip, unsigned int cmd, unsigned long arg);
994
extern int cdrom_media_changed(struct cdrom_device_info *);
994
extern int cdrom_media_changed(struct cdrom_device_info *);
995
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
996
extern int cdrom_mediactl(struct cdrom_device_info *, struct block_device *, int, int);
997
#endif
995
998
996
extern int register_cdrom(struct cdrom_device_info *cdi);
999
extern int register_cdrom(struct cdrom_device_info *cdi);
997
extern int unregister_cdrom(struct cdrom_device_info *cdi);
1000
extern int unregister_cdrom(struct cdrom_device_info *cdi);
(-)linux-2.6.25.4.orig/include/linux/genhd.h (+4 lines)
Lines 141-146 Link Here
141
	struct disk_stats dkstats;
141
	struct disk_stats dkstats;
142
#endif
142
#endif
143
	struct work_struct async_notify;
143
	struct work_struct async_notify;
144
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
145
	int scount;			/* number of supermounted partitions */
146
#endif
147
144
};
148
};
145
149
146
/* 
150
/* 
(-)linux-2.6.25.4.orig/include/linux/supermount_media.h (+47 lines)
Line 0 Link Here
1
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2
3
/*
4
 * These are the "op" operation codes for mediactl() media control
5
 * calls for device special files
6
 */
7
enum {
8
	MEDIA_LOCK = 1234,	/* Lock the drive door */
9
	MEDIA_UNLOCK,		/* Unlock the drive door */
10
	SUPERMOUNT_INC_COUNT,
11
	SUPERMOUNT_DEC_COUNT,
12
};
13
14
static inline int
15
supermount_usage_count(struct block_device *bdev, int count)
16
{
17
	if (bdev) {
18
		count -= bdev->bd_disk->scount;
19
		if (count < 0)
20
			count = 0;
21
	}
22
	return count;
23
}
24
25
static inline int
26
dev_is_supermounted(struct block_device *bdev)
27
{
28
	return bdev ? bdev->bd_disk->scount > 0 : 0;
29
}
30
31
#else /* CONFIG_SUPERMOUNT */
32
33
static inline int
34
supermount_usage_count(struct block_device *bdev, int count)
35
{
36
	(void)bdev; // make compiler happy
37
	return count;
38
}
39
40
static inline int
41
dev_is_supermounted(struct block_device *bdev)
42
{
43
	(void)bdev; // make compiler happy
44
	return 0;
45
}
46
47
#endif /* CONFIG_SUPERMOUNT */
(-)linux-2.6.25.4.orig/drivers/scsi/sd.c (-1 / +73 lines)
Lines 55-60 Link Here
55
#include <scsi/scsi_device.h>
55
#include <scsi/scsi_device.h>
56
#include <scsi/scsi_driver.h>
56
#include <scsi/scsi_driver.h>
57
#include <scsi/scsi_eh.h>
57
#include <scsi/scsi_eh.h>
58
#include <linux/supermount_media.h>
58
#include <scsi/scsi_host.h>
59
#include <scsi/scsi_host.h>
59
#include <scsi/scsi_ioctl.h>
60
#include <scsi/scsi_ioctl.h>
60
#include <scsi/scsicam.h>
61
#include <scsi/scsicam.h>
Lines 610-615 Link Here
610
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
611
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
611
	}
612
	}
612
613
614
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
615
	if (supermount_usage_count(inode->i_bdev, sdkp->openers++) == 0 && sdev->removable) {
616
		if (scsi_block_when_processing_errors(sdev))
617
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
618
	}
619
#endif
613
	return 0;
620
	return 0;
614
621
615
error_out:
622
error_out:
Lines 640-646 Link Here
640
		if (scsi_block_when_processing_errors(sdev))
647
		if (scsi_block_when_processing_errors(sdev))
641
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
648
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
642
	}
649
	}
643
650
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
651
	if (supermount_usage_count(inode->i_bdev, --sdkp->openers) == 0 && sdev->removable) {
652
		if (scsi_block_when_processing_errors(sdev))
653
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
654
	}
655
#endif
644
	/*
656
	/*
645
	 * XXX and what if there are packets in flight and this close()
657
	 * XXX and what if there are packets in flight and this close()
646
	 * XXX is followed by a "rmmod sd_mod"?
658
	 * XXX is followed by a "rmmod sd_mod"?
Lines 782-787 Link Here
782
					      sshdr);
794
					      sshdr);
783
	}
795
	}
784
796
797
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
798
	/*
799
	 * FIXME HACK
800
	 * busy device that is unplugged is SDEV_DEL but online and ioctl
801
	 * does not return any error. Oh well, it is likely layering
802
	 * violation but for now it enables media checks for supermount
803
	 */
804
805
	if (sdp->sdev_state == SDEV_DEL) 
806
		retval = 1;
807
#endif
785
	/*
808
	/*
786
	 * Unable to test, unit probably not ready.   This usually
809
	 * Unable to test, unit probably not ready.   This usually
787
	 * means there is no disc in the drive.  Mark as changed,
810
	 * means there is no disc in the drive.  Mark as changed,
Lines 867-872 Link Here
867
	}
890
	}
868
}
891
}
869
892
893
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
894
/*
895
 * This function performs media control operations.  Currently the
896
 * only functions used are MEDIA_LOCK and MEDIA_UNLOCK, to lock and
897
 * unlock the drive door.
898
 */
899
900
static int sd_mediactl(struct block_device *bdev, int op, int optarg)
901
{
902
	struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
903
	struct scsi_device *sdp = sdkp->device;
904
	int rc = 0;
905
906
	SCSI_LOG_HLQUEUE(3, printk("sd_mediactl: disk=%s\n",
907
						bdev->bd_disk->disk_name));
908
909
	if (!sdp->removable)
910
		return 0;
911
912
	if (!scsi_block_when_processing_errors(sdp))
913
		return -ENODEV;
914
915
	switch (op) {
916
	case MEDIA_LOCK:
917
		if (supermount_usage_count(bdev, sdkp->openers) == 0)
918
			rc = scsi_set_medium_removal(sdp, SCSI_REMOVAL_PREVENT);
919
		/* FIXME is it the right way? */
920
		if (optarg)
921
			sdkp->openers++;
922
		break;
923
	case MEDIA_UNLOCK:
924
		if (optarg && sdkp->openers > 0)
925
			sdkp->openers--;
926
		if (supermount_usage_count(bdev, sdkp->openers) == 0)
927
			rc = scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW);
928
		break;
929
	default:
930
		rc = -EINVAL;
931
		break;
932
	}
933
934
	return rc;
935
}
936
#endif
937
870
938
871
#ifdef CONFIG_COMPAT
939
#ifdef CONFIG_COMPAT
872
/* 
940
/* 
Lines 914-919 Link Here
914
#endif
982
#endif
915
	.media_changed		= sd_media_changed,
983
	.media_changed		= sd_media_changed,
916
	.revalidate_disk	= sd_revalidate_disk,
984
	.revalidate_disk	= sd_revalidate_disk,
985
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
986
	.mediactl		= sd_mediactl,
987
#endif
988
	
917
};
989
};
918
990
919
/**
991
/**
(-)linux-2.6.25.4.orig/include/linux/fs.h (+16 lines)
Lines 92-97 Link Here
92
/* public flags for file_system_type */
92
/* public flags for file_system_type */
93
#define FS_REQUIRES_DEV 1 
93
#define FS_REQUIRES_DEV 1 
94
#define FS_BINARY_MOUNTDATA 2
94
#define FS_BINARY_MOUNTDATA 2
95
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
96
#define FS_NO_SUBMNT	64	/* Prevent mounting over this filesystem */
97
#endif
95
#define FS_HAS_SUBTYPE 4
98
#define FS_HAS_SUBTYPE 4
96
#define FS_REVAL_DOT	16384	/* Check the paths ".", ".." for staleness */
99
#define FS_REVAL_DOT	16384	/* Check the paths ".", ".." for staleness */
97
#define FS_RENAME_DOES_D_MOVE	32768	/* FS will handle d_move()
100
#define FS_RENAME_DOES_D_MOVE	32768	/* FS will handle d_move()
Lines 118-123 Link Here
118
				   MS_VERBOSE is deprecated. */
121
				   MS_VERBOSE is deprecated. */
119
#define MS_SILENT	32768
122
#define MS_SILENT	32768
120
#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
123
#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
124
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
125
#define MS_SUPERMOUNTED (1<<29) /* 21 is being used now by update atime*/
126
#endif
121
#define MS_UNBINDABLE	(1<<17)	/* change to unbindable */
127
#define MS_UNBINDABLE	(1<<17)	/* change to unbindable */
122
#define MS_PRIVATE	(1<<18)	/* change to private */
128
#define MS_PRIVATE	(1<<18)	/* change to private */
123
#define MS_SLAVE	(1<<19)	/* change to slave */
129
#define MS_SLAVE	(1<<19)	/* change to slave */
Lines 809-814 Link Here
809
	struct list_head	f_ep_links;
815
	struct list_head	f_ep_links;
810
	spinlock_t		f_ep_lock;
816
	spinlock_t		f_ep_lock;
811
#endif /* #ifdef CONFIG_EPOLL */
817
#endif /* #ifdef CONFIG_EPOLL */
818
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
819
	/* Used by supermount. Use(fullness) unconfirmed */
820
	void                    *f_supermount;
821
#endif
812
	struct address_space	*f_mapping;
822
	struct address_space	*f_mapping;
813
};
823
};
814
extern spinlock_t files_lock;
824
extern spinlock_t files_lock;
Lines 1029-1034 Link Here
1029
	 */
1039
	 */
1030
	struct mutex s_vfs_rename_mutex;	/* Kludge */
1040
	struct mutex s_vfs_rename_mutex;	/* Kludge */
1031
1041
1042
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1043
     atomic_t s_media_changed;
1044
#endif
1032
	/* Granularity of c/m/atime in ns.
1045
	/* Granularity of c/m/atime in ns.
1033
	   Cannot be worse than a second */
1046
	   Cannot be worse than a second */
1034
	u32		   s_time_gran;
1047
	u32		   s_time_gran;
Lines 1132-1137 Link Here
1132
	int (*direct_access) (struct block_device *, sector_t, unsigned long *);
1145
	int (*direct_access) (struct block_device *, sector_t, unsigned long *);
1133
	int (*media_changed) (struct gendisk *);
1146
	int (*media_changed) (struct gendisk *);
1134
	int (*revalidate_disk) (struct gendisk *);
1147
	int (*revalidate_disk) (struct gendisk *);
1148
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1149
	int (*mediactl) (struct block_device *, int, int);
1150
#endif
1135
	int (*getgeo)(struct block_device *, struct hd_geometry *);
1151
	int (*getgeo)(struct block_device *, struct hd_geometry *);
1136
	struct module *owner;
1152
	struct module *owner;
1137
};
1153
};

Return to bug 15838