Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 76086
Collapse All | Expand All

(-)linux-2.6.10-ck1.orig/Documentation/filesystems/00-INDEX (+2 lines)
Lines 36-41 romfs.txt Link Here
36
	- Description of the ROMFS filesystem.
36
	- Description of the ROMFS filesystem.
37
smbfs.txt
37
smbfs.txt
38
	- info on using filesystems with the SMB protocol (Windows 3.11 and NT)
38
	- info on using filesystems with the SMB protocol (Windows 3.11 and NT)
39
supermount.txt
40
	- info on using supermount for removable media.
39
sysv-fs.txt
41
sysv-fs.txt
40
	- info on the SystemV/V7/Xenix/Coherent filesystem.
42
	- info on the SystemV/V7/Xenix/Coherent filesystem.
41
udf.txt
43
udf.txt
(-)linux-2.6.10-ck1.orig/Documentation/filesystems/supermount.txt (+250 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: in the above description `none' is literal word. While device
33
is ignored by supermount itself, using real files in this place (real
34
device name or mount point directory name) is known to cause problems.
35
Some programs - fuser is one of them - will try to descend into filesystem
36
if dev can be statted, thus making supermount to attempt to access media.
37
This is annoying at best - in the worst case it can take very long time
38
during startup or shutdown.
39
40
Notice that you do not directly specify the block device you are going
41
to mount on the mount command line.  This is because the supermount
42
filesystem is NOT connected to a block device; rather, supermount is
43
responsible for connecting a separate filesystem to the block device.
44
You specify the sub-filesystem and block device name by providing the
45
<superfs-options> field, where the following options are currently
46
recognised:
47
48
49
* fs=<filesystem-type>			[default is "auto"]
50
51
	Specify the subfilesystem type. Not every filesystem type has
52
been tested.  If you use `auto', it will try the following filesystems
53
in order:
54
		    	"udf"
55
			"iso9660"
56
			"ext2"
57
			"vfat"
58
			"msdos"
59
60
It is also possible to give list of types separated by `:', like
61
62
		fs=ext2:vfat
63
		    - or -
64
		fs=udf:iso9660
65
 
66
67
* dev=<block-device>			[no default, mandatory]
68
69
	Specify the block device on which the subfs is to be mounted.
70
71
72
* tray_lock={always,onwrite,never}	[default is "onwrite"]
73
74
	Specify when supermount is to prevent media removal. `always' means
75
on every access (it was default in earlier versions), `onwrite' means only
76
for write access and `never' means never :) `onwrite' and `never' are the
77
same for ro media like CD-ROM. It is not clear when `never' is actually useful,
78
it is presented for completeness only.
79
80
* debug[=<bitmap>]			[default is no debug]
81
82
	Enable debugging code in the supermount filesystem, if
83
the debug option was enabled at compile time.  By default, debugging
84
code is compiled into the kernel but is disabled until a debug mount
85
option is seen. <bitmap> is the combination of debug flags, following
86
flags are possible:
87
88
	0x001 - "generic" debug (used by supermount_debug) - default
89
	0x002 - trace dentry.c
90
	0x004 - trace file.c
91
	0x008 - trace filemap.c
92
	0x010 - trace mediactl.c
93
	0x020 - trace namei.c
94
	0x040 - trace subfs.c
95
	0x080 - trace super.c
96
97
Trace flags turn on tracing of functions in correpsonding files.
98
"Generic" debug flag is tested in supermount_debug; for compatibility,
99
if no flags are specified, this flag is set.
100
101
102
* '--'
103
104
	All options after the option string '--' will be passed
105
directly to the subfilesystem when it gets mounted.
106
107
Errors
108
------
109
110
In addition to "normal" errors during file operations supermount may
111
return following error codes:
112
113
* No medium found
114
115
	You attempt to access supermounted filesystem when there is no
116
medium inserted
117
118
* Wrong medium type
119
120
	(Not really generated by supermount) You attempt to mount CD
121
without data tracks
122
123
* Stale NFS file handle
124
125
	You attempt to use file handle after medium has been changed.
126
127
* No such device or address
128
129
	(Not really generated by supermount) device specified in
130
dev=<device> option does not exist. Also some drivers return this
131
error instead of "No medium found", one example being floppy driver.
132
133
* Device or resource busy
134
135
	(Not really generated by supermount) device is already mounted.
136
Supermount prevents double mount even if kernel otherwise would make it
137
possible.
138
139
* No such file or directory
140
141
	(Not really generated by supermount) file name specified by
142
dev=<device> option does not exist
143
144
* Operation not permitted
145
146
	You attempt to access subfs that is currently disabled
147
148
/proc support
149
-------------
150
151
If kernel has been compiled with procfs support, supermount will provide
152
/proc interface to read subfs status and to control some aspects of subfs.
153
The following files are created under /proc/fs/supermount:
154
155
* version (ro)
156
	Shows supermount version.
157
158
* subfs (rw)
159
160
	Reading this file returns list of all subfs status. One line for
161
every subfs is returned; the format is
162
	
163
	<devname> disabled
164
		- or -
165
	<devname> unmounted
166
		- or -
167
	<devname> mounted readcount writecount
168
169
where <devname> is the string passed in `dev=' parameter during mount.
170
`readcount' is number of current subfs "users" needing ro access; `writecount'
171
is the number of "users" needing rw mode. It is mostly the number of open
172
files, but inode operations also add to these counts. Those operations
173
are normally short-lived to be seen.
174
175
	Writing this file changes subfs status; the following commands are
176
suported:
177
178
	<devname> [disable|enable] [release [force]]
179
180
`disable' will disable subfs (i.e. any futher attempt to mount is rejected).
181
Subfs must be unmounted; use `disable release' or `disable release force' to
182
unmount and disable at the same time.
183
184
`enable' will enable disabled subfs, it has no effect if subfs is already
185
enabled.
186
187
`release' will unmount subfs unless it is busy (opencount > 0). To unmount
188
busy subfs add `force'; the effect is very much as if media change has been
189
detected (with the difference that subfs will be cleanly unmounted).
190
191
Some basic sanity checks are performed, i.e. it is impossible to specify
192
both `enable' and `disable' or `force' without `release'.
193
194
Internals/Locking
195
-----------------
196
197
THIS SECTION IS PROBABLY INCOMPLETE. CORRECTIONS ARE WELCOME.
198
199
Supermount itself is using two locks and relies on two more locking rules
200
as implemented by kernel.
201
202
* supermount_proc_sem
203
204
	Global mutex used to protect list of sbi during access to
205
/proc/fs/supermount/subfs
206
207
* sbi->sem
208
209
	Per-filesystem mutex that protects subfs state (mounted/unmounted).
210
Any changes to subfs state (mounting, unmouting, adding or removing file,
211
dentry or inode) happen under this mutex.
212
213
* inode->i_sem (see Documentation/filesystem/Locking)
214
215
	Per-inode mutex used by VFS to serialize inode unlink operation.
216
Supermount relies on the fact that link/unlink for an inode are mutually
217
locked and thus inode->i_nlink is atomic inside of fs method.
218
219
* BKL
220
221
	Used to protect device usage count. It is changed in open/release
222
and referenced in ioctl all of which run under BKL. Supermount adds mediactl
223
and internally wraps it in BKL as well.
224
225
Caveats/BUGS
226
------------
227
228
Inode times are believed to be correctly updated; still it is possible that
229
I missed some point.
230
231
If subfs is not yet mounted, find /mnt/cdrom fails with "find: /mnt/cdrom
232
changed during execution of find". It is unlikely it can be fixed in
233
supermount; much more simple is to provide wrapper that will check if subfs
234
is mounted and do simple "touch  /mnt/cdrom" if not to make sure it is.
235
236
Supermount attempts to check for changed media at every operation and
237
invalidate and umount old subfs to avoid new media corruption in rw case.
238
Still it is possible that kernel will write out stale information and
239
it is outside of supermount control.
240
241
By default cdrom driver does not check media type i.e. supermount will
242
try all configured fs types in turn that may be quite time consuming.
243
Use sysctl -w dev.cdrom.check_media=1 to enable it. Comments in cdrom.c
244
indicate that some (non conforming) software may have problems with this
245
settings. YMMV
246
247
atime management does not work for special files. There is no hooks from
248
VFS into fs to indicate when it gets updated
249
250
$Id: supermount.txt,v 1.17.2.1 2003/06/12 07:41:27 bor Exp $
(-)linux-2.6.10-ck1.orig/drivers/cdrom/cdrom.c (-8 / +46 lines)
Lines 281-286 Link Here
281
#include <linux/fcntl.h>
281
#include <linux/fcntl.h>
282
#include <linux/blkdev.h>
282
#include <linux/blkdev.h>
283
#include <linux/times.h>
283
#include <linux/times.h>
284
#include <linux/supermount_media.h>
284
285
285
#include <asm/uaccess.h>
286
#include <asm/uaccess.h>
286
287
Lines 339-345 static const char *mrw_address_space[] = Link Here
339
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
340
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
340
341
341
/* Not-exported routines. */
342
/* Not-exported routines. */
342
static int open_for_data(struct cdrom_device_info * cdi);
343
static int open_for_data(struct cdrom_device_info * cdi, struct block_device *bdev);
343
static int check_for_audio_disc(struct cdrom_device_info * cdi,
344
static int check_for_audio_disc(struct cdrom_device_info * cdi,
344
			 struct cdrom_device_ops * cdo);
345
			 struct cdrom_device_ops * cdo);
345
static void sanitize_format(union cdrom_addr *addr, 
346
static void sanitize_format(union cdrom_addr *addr, 
Lines 1003-1009 int cdrom_open(struct cdrom_device_info Link Here
1003
	if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
1004
	if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
1004
		ret = cdi->ops->open(cdi, 1);
1005
		ret = cdi->ops->open(cdi, 1);
1005
	} else {
1006
	} else {
1006
		ret = open_for_data(cdi);
1007
		ret = open_for_data(cdi, ip->i_bdev);
1007
		if (ret)
1008
		if (ret)
1008
			goto err;
1009
			goto err;
1009
		cdrom_mmc3_profile(cdi);
1010
		cdrom_mmc3_profile(cdi);
Lines 1033-1039 err: Link Here
1033
}
1034
}
1034
1035
1035
static
1036
static
1036
int open_for_data(struct cdrom_device_info * cdi)
1037
int open_for_data(struct cdrom_device_info * cdi, struct block_device *bdev)
1037
{
1038
{
1038
	int ret;
1039
	int ret;
1039
	struct cdrom_device_ops *cdo = cdi->ops;
1040
	struct cdrom_device_ops *cdo = cdi->ops;
Lines 1116-1122 int open_for_data(struct cdrom_device_in Link Here
1116
		cdinfo(CD_OPEN, "open device failed.\n"); 
1117
		cdinfo(CD_OPEN, "open device failed.\n"); 
1117
		goto clean_up_and_return;
1118
		goto clean_up_and_return;
1118
	}
1119
	}
1119
	if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
1120
	if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK &&
1121
	    supermount_usage_count(bdev, cdi->use_count) > 0) {
1120
			cdo->lock_door(cdi, 1);
1122
			cdo->lock_door(cdi, 1);
1121
			cdinfo(CD_OPEN, "door locked.\n");
1123
			cdinfo(CD_OPEN, "door locked.\n");
1122
	}
1124
	}
Lines 1129-1135 int open_for_data(struct cdrom_device_in Link Here
1129
	This ensures that the drive gets unlocked after a mount fails.  This 
1131
	This ensures that the drive gets unlocked after a mount fails.  This 
1130
	is a goto to avoid bloating the driver with redundant code. */ 
1132
	is a goto to avoid bloating the driver with redundant code. */ 
1131
clean_up_and_return:
1133
clean_up_and_return:
1132
	cdinfo(CD_WARNING, "open failed.\n"); 
1134
	cdinfo(CD_OPEN, "open failed.\n"); 
1133
	if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1135
	if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1134
			cdo->lock_door(cdi, 0);
1136
			cdo->lock_door(cdi, 0);
1135
			cdinfo(CD_OPEN, "door unlocked.\n");
1137
			cdinfo(CD_OPEN, "door unlocked.\n");
Lines 1208-1214 int cdrom_release(struct cdrom_device_in Link Here
1208
		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
1210
		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
1209
	if (cdi->use_count == 0)
1211
	if (cdi->use_count == 0)
1210
		cdrom_dvd_rw_close_write(cdi);
1212
		cdrom_dvd_rw_close_write(cdi);
1211
	if (cdi->use_count == 0 &&
1213
	if (supermount_usage_count(fp ? fp->f_dentry->d_inode->i_bdev : 0, cdi->use_count) == 0 &&
1212
	    (cdo->capability & CDC_LOCK) && !keeplocked) {
1214
	    (cdo->capability & CDC_LOCK) && !keeplocked) {
1213
		cdinfo(CD_CLOSE, "Unlocking door!\n");
1215
		cdinfo(CD_CLOSE, "Unlocking door!\n");
1214
		cdo->lock_door(cdi, 0);
1216
		cdo->lock_door(cdi, 0);
Lines 1481-1486 static void cdrom_count_tracks(struct cd Link Here
1481
		tracks->cdi, tracks->xa);
1483
		tracks->cdi, tracks->xa);
1482
}	
1484
}	
1483
1485
1486
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1487
/*
1488
 * MEDIA_LOCK, MEDIA_UNLOCK
1489
 *   optarg == 0 - do not adjust usage count (compatibility)
1490
 *   optarg == 1 - adjust usage count
1491
 */
1492
int cdrom_mediactl(struct cdrom_device_info *cdi, struct block_device *bdev, int op, int optarg)
1493
{
1494
	struct cdrom_device_ops *cdo = cdi->ops;
1495
1496
	switch (op) {
1497
	case MEDIA_LOCK:
1498
	case MEDIA_UNLOCK:
1499
		if (op == MEDIA_UNLOCK && optarg) {
1500
			cdi->use_count--;
1501
		if (cdi->use_count < 0)
1502
			cdi->use_count = 0;
1503
		}
1504
		if (cdo->capability & ~cdi->mask & CDC_LOCK &&
1505
		    cdi->options & CDO_LOCK &&
1506
			supermount_usage_count(bdev, cdi->use_count) == 0)
1507
			cdo->lock_door(cdi, (op == MEDIA_LOCK));
1508
		if (op == MEDIA_LOCK && optarg)
1509
			cdi->use_count++;
1510
		break;
1511
	default:
1512
		return -EINVAL;
1513
	}
1514
	return 0;
1515
}
1516
#endif
1517
1484
/* Requests to the low-level drivers will /always/ be done in the
1518
/* Requests to the low-level drivers will /always/ be done in the
1485
   following format convention:
1519
   following format convention:
1486
1520
Lines 2232-2239 int cdrom_ioctl(struct file * file, stru Link Here
2232
		cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n"); 
2266
		cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n"); 
2233
		if (!CDROM_CAN(CDC_OPEN_TRAY))
2267
		if (!CDROM_CAN(CDC_OPEN_TRAY))
2234
			return -ENOSYS;
2268
			return -ENOSYS;
2235
		if (cdi->use_count != 1 || keeplocked)
2269
		if (keeplocked ||
2236
			return -EBUSY;
2270
		    (supermount_usage_count(ip->i_bdev,cdi->use_count) != 1))
2271
                        return -EBUSY;
2237
		if (CDROM_CAN(CDC_LOCK))
2272
		if (CDROM_CAN(CDC_LOCK))
2238
			if ((ret=cdo->lock_door(cdi, 0)))
2273
			if ((ret=cdo->lock_door(cdi, 0)))
2239
				return ret;
2274
				return ret;
Lines 3069-3074 EXPORT_SYMBOL(cdrom_open); Link Here
3069
EXPORT_SYMBOL(cdrom_release);
3104
EXPORT_SYMBOL(cdrom_release);
3070
EXPORT_SYMBOL(cdrom_ioctl);
3105
EXPORT_SYMBOL(cdrom_ioctl);
3071
EXPORT_SYMBOL(cdrom_media_changed);
3106
EXPORT_SYMBOL(cdrom_media_changed);
3107
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3108
EXPORT_SYMBOL(cdrom_mediactl);
3109
#endif
3072
EXPORT_SYMBOL(cdrom_number_of_slots);
3110
EXPORT_SYMBOL(cdrom_number_of_slots);
3073
EXPORT_SYMBOL(cdrom_mode_select);
3111
EXPORT_SYMBOL(cdrom_mode_select);
3074
EXPORT_SYMBOL(cdrom_mode_sense);
3112
EXPORT_SYMBOL(cdrom_mode_sense);
(-)linux-2.6.10-ck1.orig/drivers/cdrom/cdu31a.c (+29 lines)
Lines 3003-3008 static int scd_block_open(struct inode * Link Here
3003
3003
3004
static int scd_block_release(struct inode *inode, struct file *file)
3004
static int scd_block_release(struct inode *inode, struct file *file)
3005
{
3005
{
3006
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3007
        /*
3008
         * This is the same sort of clockload as use in blkdev_get.
3009
         * We need information whether device is supermounted inside
3010
         * of cdrom_release to decide if tray must be unlocked.
3011
         * This information so far is available only by looking
3012
         * up superblock but it needs struct *bdev and it is not
3013
         * available in cdrom_release anymore
3014
         */
3015
        struct dentry t_dentry;
3016
        struct file t_file;
3017
3018
        if (!file) {
3019
                t_file.f_dentry = &t_dentry;
3020
                t_dentry.d_inode = inode;
3021
                file = &t_file;
3022
        }
3023
#endif
3024
3006
	return cdrom_release(&scd_info, file);
3025
	return cdrom_release(&scd_info, file);
3007
}
3026
}
3008
3027
Lines 3029-3034 static int scd_block_media_changed(struc Link Here
3029
	return cdrom_media_changed(&scd_info);
3048
	return cdrom_media_changed(&scd_info);
3030
}
3049
}
3031
3050
3051
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3052
static int scd_block_mediactl(struct block_device *bdev, int op, int arg)
3053
{
3054
	return cdrom_mediactl(&scd_info, bdev, op, arg);
3055
}
3056
#endif
3057
3032
struct block_device_operations scd_bdops =
3058
struct block_device_operations scd_bdops =
3033
{
3059
{
3034
	.owner		= THIS_MODULE,
3060
	.owner		= THIS_MODULE,
Lines 3036-3041 struct block_device_operations scd_bdops Link Here
3036
	.release	= scd_block_release,
3062
	.release	= scd_block_release,
3037
	.ioctl		= scd_block_ioctl,
3063
	.ioctl		= scd_block_ioctl,
3038
	.media_changed	= scd_block_media_changed,
3064
	.media_changed	= scd_block_media_changed,
3065
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3066
	.mediactl	= scd_block_mediactl,
3067
#endif
3039
};
3068
};
3040
3069
3041
static struct gendisk *scd_gendisk;
3070
static struct gendisk *scd_gendisk;
(-)linux-2.6.10-ck1.orig/drivers/cdrom/cm206.c (+29 lines)
Lines 1357-1362 static int cm206_block_open(struct inode Link Here
1357
1357
1358
static int cm206_block_release(struct inode *inode, struct file *file)
1358
static int cm206_block_release(struct inode *inode, struct file *file)
1359
{
1359
{
1360
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1361
        /*
1362
         * This is the same sort of clockload as use in blkdev_get.
1363
         * We need information whether device is supermounted inside
1364
         * of cdrom_release to decide if tray must be unlocked.
1365
         * This information so far is available only by looking
1366
         * up superblock but it needs struct *bdev and it is not
1367
         * available in cdrom_release anymore
1368
         */
1369
        struct dentry t_dentry;
1370
        struct file t_file;
1371
1372
        if (!file) {
1373
                t_file.f_dentry = &t_dentry;
1374
                t_dentry.d_inode = inode;
1375
                file = &t_file;
1376
        }
1377
#endif
1378
1360
	return cdrom_release(&cm206_info, file);
1379
	return cdrom_release(&cm206_info, file);
1361
}
1380
}
1362
1381
Lines 1371-1376 static int cm206_block_media_changed(str Link Here
1371
	return cdrom_media_changed(&cm206_info);
1390
	return cdrom_media_changed(&cm206_info);
1372
}
1391
}
1373
1392
1393
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1394
static int cm206_block_mediactl(struct block_device *bdev, int op, int arg)
1395
{
1396
	return cdrom_mediactl(&cm206_info, bdev, op, arg);
1397
}
1398
#endif
1399
1374
static struct block_device_operations cm206_bdops =
1400
static struct block_device_operations cm206_bdops =
1375
{
1401
{
1376
	.owner		= THIS_MODULE,
1402
	.owner		= THIS_MODULE,
Lines 1378-1383 static struct block_device_operations cm Link Here
1378
	.release	= cm206_block_release,
1404
	.release	= cm206_block_release,
1379
	.ioctl		= cm206_block_ioctl,
1405
	.ioctl		= cm206_block_ioctl,
1380
	.media_changed	= cm206_block_media_changed,
1406
	.media_changed	= cm206_block_media_changed,
1407
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1408
	.mediactl	= cm206_block_mediactl,
1409
#endif
1381
};
1410
};
1382
1411
1383
static struct gendisk *cm206_gendisk;
1412
static struct gendisk *cm206_gendisk;
(-)linux-2.6.10-ck1.orig/drivers/cdrom/mcd.c (+29 lines)
Lines 221-226 static int mcd_block_open(struct inode * Link Here
221
221
222
static int mcd_block_release(struct inode *inode, struct file *file)
222
static int mcd_block_release(struct inode *inode, struct file *file)
223
{
223
{
224
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
225
        /*
226
         * This is the same sort of clockload as use in blkdev_get.
227
         * We need information whether device is supermounted inside
228
         * of cdrom_release to decide if tray must be unlocked.
229
         * This information so far is available only by looking
230
         * up superblock but it needs struct *bdev and it is not
231
         * available in cdrom_release anymore
232
         */
233
        struct dentry t_dentry;
234
        struct file t_file;
235
236
        if (!file) {
237
                t_file.f_dentry = &t_dentry;
238
                t_dentry.d_inode = inode;
239
                file = &t_file;
240
        }
241
#endif
242
224
	return cdrom_release(&mcd_info, file);
243
	return cdrom_release(&mcd_info, file);
225
}
244
}
226
245
Lines 235-240 static int mcd_block_media_changed(struc Link Here
235
	return cdrom_media_changed(&mcd_info);
254
	return cdrom_media_changed(&mcd_info);
236
}
255
}
237
256
257
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
258
static int mcd_block_mediactl(struct block_device *bdev, int op, int arg)
259
{
260
	return cdrom_mediactl(&mcd_info, bdev, op, arg);
261
}
262
#endif
263
238
static struct block_device_operations mcd_bdops =
264
static struct block_device_operations mcd_bdops =
239
{
265
{
240
	.owner		= THIS_MODULE,
266
	.owner		= THIS_MODULE,
Lines 242-247 static struct block_device_operations mc Link Here
242
	.release	= mcd_block_release,
268
	.release	= mcd_block_release,
243
	.ioctl		= mcd_block_ioctl,
269
	.ioctl		= mcd_block_ioctl,
244
	.media_changed	= mcd_block_media_changed,
270
	.media_changed	= mcd_block_media_changed,
271
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
272
	.mediactl	= mcd_block_mediactl,
273
#endif
245
};
274
};
246
275
247
static struct gendisk *mcd_gendisk;
276
static struct gendisk *mcd_gendisk;
(-)linux-2.6.10-ck1.orig/drivers/cdrom/mcdx.c (+30 lines)
Lines 226-231 static int mcdx_block_open(struct inode Link Here
226
static int mcdx_block_release(struct inode *inode, struct file *file)
226
static int mcdx_block_release(struct inode *inode, struct file *file)
227
{
227
{
228
	struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
228
	struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
229
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
230
        /*
231
         * This is the same sort of clockload as use in blkdev_get.
232
         * We need information whether device is supermounted inside
233
         * of cdrom_release to decide if tray must be unlocked.
234
         * This information so far is available only by looking
235
         * up superblock but it needs struct *bdev and it is not
236
         * available in cdrom_release anymore
237
         */
238
        struct dentry t_dentry;
239
        struct file t_file;
240
241
        if (!file) {
242
                t_file.f_dentry = &t_dentry;
243
                t_dentry.d_inode = inode;
244
                file = &t_file;
245
        }
246
#endif
247
229
	return cdrom_release(&p->info, file);
248
	return cdrom_release(&p->info, file);
230
}
249
}
231
250
Lines 242-247 static int mcdx_block_media_changed(stru Link Here
242
	return cdrom_media_changed(&p->info);
261
	return cdrom_media_changed(&p->info);
243
}
262
}
244
263
264
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
265
static int mcdx_block_mediactl(struct block_device *bdev, int op, int arg)
266
{
267
	struct s_drive_stuff *p = bdev->bd_disk->private_data;
268
	return cdrom_mediactl(&p->info, bdev, op, arg);
269
}
270
#endif
271
245
static struct block_device_operations mcdx_bdops =
272
static struct block_device_operations mcdx_bdops =
246
{
273
{
247
	.owner		= THIS_MODULE,
274
	.owner		= THIS_MODULE,
Lines 249-254 static struct block_device_operations mc Link Here
249
	.release	= mcdx_block_release,
276
	.release	= mcdx_block_release,
250
	.ioctl		= mcdx_block_ioctl,
277
	.ioctl		= mcdx_block_ioctl,
251
	.media_changed	= mcdx_block_media_changed,
278
	.media_changed	= mcdx_block_media_changed,
279
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
280
	.mediactl	= mcdx_block_mediactl,
281
#endif
252
};
282
};
253
283
254
284
(-)linux-2.6.10-ck1.orig/drivers/cdrom/sbpcd.c (+30 lines)
Lines 5366-5371 static int sbpcd_block_open(struct inode Link Here
5366
static int sbpcd_block_release(struct inode *inode, struct file *file)
5366
static int sbpcd_block_release(struct inode *inode, struct file *file)
5367
{
5367
{
5368
	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5368
	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5369
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5370
        /*
5371
         * This is the same sort of clockload as use in blkdev_get.
5372
         * We need information whether device is supermounted inside
5373
         * of cdrom_release to decide if tray must be unlocked.
5374
         * This information so far is available only by looking
5375
         * up superblock but it needs struct *bdev and it is not
5376
         * available in cdrom_release anymore
5377
         */
5378
        struct dentry t_dentry;
5379
        struct file t_file;
5380
5381
        if (!file) {
5382
                t_file.f_dentry = &t_dentry;
5383
                t_dentry.d_inode = inode;
5384
                file = &t_file;
5385
        }
5386
#endif
5387
5369
	return cdrom_release(p->sbpcd_infop, file);
5388
	return cdrom_release(p->sbpcd_infop, file);
5370
}
5389
}
5371
5390
Lines 5382-5387 static int sbpcd_block_media_changed(str Link Here
5382
	return cdrom_media_changed(p->sbpcd_infop);
5401
	return cdrom_media_changed(p->sbpcd_infop);
5383
}
5402
}
5384
5403
5404
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5405
static int sbpcd_block_mediactl(struct block_device *bdev, int op, int arg)
5406
{
5407
	struct sbpcd_drive *p = bdev->bd_disk->private_data;
5408
	return cdrom_mediactl(p->sbpcd_infop, bdev, op, arg);
5409
}
5410
#endif
5411
5385
static struct block_device_operations sbpcd_bdops =
5412
static struct block_device_operations sbpcd_bdops =
5386
{
5413
{
5387
	.owner		= THIS_MODULE,
5414
	.owner		= THIS_MODULE,
Lines 5389-5394 static struct block_device_operations sb Link Here
5389
	.release	= sbpcd_block_release,
5416
	.release	= sbpcd_block_release,
5390
	.ioctl		= sbpcd_block_ioctl,
5417
	.ioctl		= sbpcd_block_ioctl,
5391
	.media_changed	= sbpcd_block_media_changed,
5418
	.media_changed	= sbpcd_block_media_changed,
5419
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5420
	.mediactl	= sbpcd_block_mediactl,
5421
#endif
5392
};
5422
};
5393
/*==========================================================================*/
5423
/*==========================================================================*/
5394
/*
5424
/*
(-)linux-2.6.10-ck1.orig/drivers/ide/ide-cd.c (-1 / +32 lines)
Lines 3398-3403 static int idecd_release(struct inode * Link Here
3398
{
3398
{
3399
	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
3399
	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
3400
	struct cdrom_info *info = drive->driver_data;
3400
	struct cdrom_info *info = drive->driver_data;
3401
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3402
	/*
3403
	 * This is the same sort of clockload as use in blkdev_get.
3404
	 * We need information whether device is supermounted inside
3405
	 * of cdrom_release to decide if tray must be unlocked.
3406
	 * This information so far is available only by looking
3407
	 * up superblock but it needs struct *bdev and it is not
3408
	 * available in cdrom_release anymore
3409
	 */
3410
	struct dentry t_dentry;
3411
	struct file t_file;
3412
3413
	if (!file) {
3414
		t_file.f_dentry = &t_dentry;
3415
		t_dentry.d_inode = inode;
3416
		file = &t_file;
3417
	}
3418
#endif
3401
3419
3402
	cdrom_release (&info->devinfo, file);
3420
	cdrom_release (&info->devinfo, file);
3403
	drive->usage--;
3421
	drive->usage--;
Lines 3432-3444 static int idecd_revalidate_disk(struct Link Here
3432
	return  0;
3450
	return  0;
3433
}
3451
}
3434
3452
3453
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3454
static int idecd_mediactl(struct block_device *bdev, int op, int arg)
3455
{
3456
	struct gendisk *disk = bdev->bd_disk;
3457
	ide_drive_t *drive = disk->private_data;
3458
	struct cdrom_info *info = drive->driver_data;
3459
	return cdrom_mediactl(&info->devinfo, bdev, op, arg);
3460
}
3461
#endif
3462
3435
static struct block_device_operations idecd_ops = {
3463
static struct block_device_operations idecd_ops = {
3436
	.owner		= THIS_MODULE,
3464
	.owner		= THIS_MODULE,
3437
	.open		= idecd_open,
3465
	.open		= idecd_open,
3438
	.release	= idecd_release,
3466
	.release	= idecd_release,
3439
	.ioctl		= idecd_ioctl,
3467
	.ioctl		= idecd_ioctl,
3440
	.media_changed	= idecd_media_changed,
3468
	.media_changed	= idecd_media_changed,
3441
	.revalidate_disk= idecd_revalidate_disk
3469
	.revalidate_disk= idecd_revalidate_disk,
3470
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3471
	.mediactl	= idecd_mediactl,
3472
#endif
3442
};
3473
};
3443
3474
3444
/* options */
3475
/* options */
(-)linux-2.6.10-ck1.orig/drivers/ide/ide-floppy.c (-4 / +40 lines)
Lines 99-104 Link Here
99
#include <linux/ide.h>
99
#include <linux/ide.h>
100
#include <linux/bitops.h>
100
#include <linux/bitops.h>
101
101
102
#include <linux/supermount_media.h>
103
102
#include <asm/byteorder.h>
104
#include <asm/byteorder.h>
103
#include <asm/irq.h>
105
#include <asm/irq.h>
104
#include <asm/uaccess.h>
106
#include <asm/uaccess.h>
Lines 1890-1896 static int idefloppy_open(struct inode * Link Here
1890
	
1892
	
1891
	debug_log(KERN_INFO "Reached idefloppy_open\n");
1893
	debug_log(KERN_INFO "Reached idefloppy_open\n");
1892
1894
1893
	if (drive->usage == 1) {
1895
	if (supermount_usage_count(inode->i_bdev, drive->usage) == 1) {
1894
		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
1896
		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
1895
		/* Just in case */
1897
		/* Just in case */
1896
1898
Lines 1937-1943 static int idefloppy_release(struct inod Link Here
1937
	
1939
	
1938
	debug_log(KERN_INFO "Reached idefloppy_release\n");
1940
	debug_log(KERN_INFO "Reached idefloppy_release\n");
1939
1941
1940
	if (drive->usage == 1) {
1942
	if (supermount_usage_count(inode->i_bdev, drive->usage) == 1) {
1941
		idefloppy_floppy_t *floppy = drive->driver_data;
1943
		idefloppy_floppy_t *floppy = drive->driver_data;
1942
1944
1943
		/* IOMEGA Clik! drives do not support lock/unlock commands */
1945
		/* IOMEGA Clik! drives do not support lock/unlock commands */
Lines 1970-1976 static int idefloppy_ioctl(struct inode Link Here
1970
		prevent = 0;
1972
		prevent = 0;
1971
		/* fall through */
1973
		/* fall through */
1972
	case CDROM_LOCKDOOR:
1974
	case CDROM_LOCKDOOR:
1973
		if (drive->usage > 1)
1975
		if (supermount_usage_count(bdev, drive->usage) > 1)
1974
			return -EBUSY;
1976
			return -EBUSY;
1975
1977
1976
		/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
1978
		/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
Lines 2038-2050 static int idefloppy_revalidate_disk(str Link Here
2038
	return 0;
2040
	return 0;
2039
}
2041
}
2040
2042
2043
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2044
static int idefloppy_mediactl (struct block_device *bdev, int op, int optarg)
2045
{
2046
	ide_drive_t *drive = bdev->bd_disk->private_data;
2047
	idefloppy_floppy_t *floppy = drive->driver_data;
2048
	idefloppy_pc_t pc;
2049
2050
        switch (op) {
2051
                case MEDIA_LOCK:
2052
                case MEDIA_UNLOCK:
2053
                        if (op == MEDIA_UNLOCK && optarg) {
2054
                                drive->usage--;
2055
                                if (drive->usage < 0)
2056
                                        drive->usage = 0;
2057
                        }
2058
                        /* IOMEGA Clik! drives do not support lock/unlock commands */
2059
                        if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)
2060
                            && supermount_usage_count(bdev, drive->usage) == 0) {
2061
                                idefloppy_create_prevent_cmd(&pc, (op == MEDIA_LOCK));
2062
                                (void) idefloppy_queue_pc_tail(drive, &pc);
2063
                        }
2064
                        if (op == MEDIA_LOCK && optarg)
2065
                                drive->usage++;
2066
                        break;
2067
                default:
2068
                        return -EINVAL;
2069
        }
2070
        return 0;
2071
}
2072
#endif
2073
2041
static struct block_device_operations idefloppy_ops = {
2074
static struct block_device_operations idefloppy_ops = {
2042
	.owner		= THIS_MODULE,
2075
	.owner		= THIS_MODULE,
2043
	.open		= idefloppy_open,
2076
	.open		= idefloppy_open,
2044
	.release	= idefloppy_release,
2077
	.release	= idefloppy_release,
2045
	.ioctl		= idefloppy_ioctl,
2078
	.ioctl		= idefloppy_ioctl,
2046
	.media_changed	= idefloppy_media_changed,
2079
	.media_changed	= idefloppy_media_changed,
2047
	.revalidate_disk= idefloppy_revalidate_disk
2080
	.revalidate_disk= idefloppy_revalidate_disk,
2081
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2082
	.mediactl	= idefloppy_mediactl,
2083
#endif
2048
};
2084
};
2049
2085
2050
static int idefloppy_attach (ide_drive_t *drive)
2086
static int idefloppy_attach (ide_drive_t *drive)
(-)linux-2.6.10-ck1.orig/drivers/scsi/sd.c (-2 / +61 lines)
Lines 49-54 Link Here
49
#include <linux/blkpg.h>
49
#include <linux/blkpg.h>
50
#include <linux/kref.h>
50
#include <linux/kref.h>
51
#include <linux/delay.h>
51
#include <linux/delay.h>
52
#include <linux/supermount_media.h>
52
#include <asm/uaccess.h>
53
#include <asm/uaccess.h>
53
54
54
#include <scsi/scsi.h>
55
#include <scsi/scsi.h>
Lines 468-474 static int sd_open(struct inode *inode, Link Here
468
	if (!scsi_device_online(sdev))
469
	if (!scsi_device_online(sdev))
469
		goto error_out;
470
		goto error_out;
470
471
471
	if (!sdkp->openers++ && sdev->removable) {
472
	if (supermount_usage_count(inode->i_bdev, sdkp->openers++) == 0 && sdev->removable) {
472
		if (scsi_block_when_processing_errors(sdev))
473
		if (scsi_block_when_processing_errors(sdev))
473
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
474
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
474
	}
475
	}
Lines 499-505 static int sd_release(struct inode *inod Link Here
499
500
500
	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
501
	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
501
502
502
	if (!--sdkp->openers && sdev->removable) {
503
	if (supermount_usage_count(inode->i_bdev, --sdkp->openers) == 0 && sdev->removable) {
503
		if (scsi_block_when_processing_errors(sdev))
504
		if (scsi_block_when_processing_errors(sdev))
504
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
505
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
505
	}
506
	}
Lines 660-665 static int sd_media_changed(struct gendi Link Here
660
		 goto not_present;
661
		 goto not_present;
661
662
662
	/*
663
	/*
664
	 * FIXME HACK
665
	 * busy device that is unplugged is SDEV_DEL but online and ioctl
666
	 * does not return any error. Oh well, it is likely layering
667
	 * violation but for now it enables media checks for supermount
668
	 */
669
670
	if (sdp->sdev_state == SDEV_DEL) 
671
		goto not_present;
672
673
	/*
663
	 * For removable scsi disk we have to recognise the presence
674
	 * For removable scsi disk we have to recognise the presence
664
	 * of a disk in the drive. This is kept in the struct scsi_disk
675
	 * of a disk in the drive. This is kept in the struct scsi_disk
665
	 * struct and tested at open !  Daniel Roche (dan@lectra.fr)
676
	 * struct and tested at open !  Daniel Roche (dan@lectra.fr)
Lines 738-743 static void sd_rescan(struct device *dev Link Here
738
	sd_revalidate_disk(sdkp->disk);
749
	sd_revalidate_disk(sdkp->disk);
739
}
750
}
740
751
752
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
753
/*
754
 * This function performs media control operations.  Currently the
755
 * only functions used are MEDIA_LOCK and MEDIA_UNLOCK, to lock and
756
 * unlock the drive door.
757
 */
758
759
static int sd_mediactl(struct block_device *bdev, int op, int optarg)
760
{
761
	struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
762
	struct scsi_device *sdp = sdkp->device;
763
	int rc = 0;
764
765
	SCSI_LOG_HLQUEUE(3, printk("sd_mediactl: disk=%s\n",
766
						bdev->bd_disk->disk_name));
767
768
	if (!sdp->removable)
769
		return 0;
770
771
	if (!scsi_block_when_processing_errors(sdp))
772
		return -ENODEV;
773
774
	switch (op) {
775
	case MEDIA_LOCK:
776
		if (supermount_usage_count(bdev, sdkp->openers) == 0)
777
			rc = scsi_set_medium_removal(sdp, SCSI_REMOVAL_PREVENT);
778
		/* FIXME is it the right way? */
779
		if (optarg)
780
			sdkp->openers++;
781
		break;
782
	case MEDIA_UNLOCK:
783
		if (optarg && sdkp->openers > 0)
784
			sdkp->openers--;
785
		if (supermount_usage_count(bdev, sdkp->openers) == 0)
786
			rc = scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW);
787
		break;
788
	default:
789
		rc = -EINVAL;
790
		break;
791
	}
792
793
	return rc;
794
}
795
#endif
796
741
static struct block_device_operations sd_fops = {
797
static struct block_device_operations sd_fops = {
742
	.owner			= THIS_MODULE,
798
	.owner			= THIS_MODULE,
743
	.open			= sd_open,
799
	.open			= sd_open,
Lines 745-750 static struct block_device_operations sd Link Here
745
	.ioctl			= sd_ioctl,
801
	.ioctl			= sd_ioctl,
746
	.media_changed		= sd_media_changed,
802
	.media_changed		= sd_media_changed,
747
	.revalidate_disk	= sd_revalidate_disk,
803
	.revalidate_disk	= sd_revalidate_disk,
804
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
805
	.mediactl		= sd_mediactl,
806
#endif
748
};
807
};
749
808
750
/**
809
/**
(-)linux-2.6.10-ck1.orig/drivers/scsi/sr.c (+31 lines)
Lines 466-471 static int sr_block_open(struct inode *i Link Here
466
	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
466
	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
467
	int ret = 0;
467
	int ret = 0;
468
468
469
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
470
	/*
471
	 * This is the same sort of clockload as use in blkdev_get.
472
	 * We need information whether device is supermounted inside
473
	 * of cdrom_release to decide if tray must be unlocked.
474
	 * This information so far is available only by looking
475
	 * up superblock but it needs struct *bdev and it is not
476
	 * available in cdrom_release anymore
477
	 */
478
	struct dentry t_dentry;
479
	struct file t_file;
480
481
	if (!file) {
482
		t_file.f_dentry = &t_dentry;
483
		t_dentry.d_inode = inode;
484
		file = &t_file;
485
	}
486
#endif
487
469
	if(!(cd = scsi_cd_get(disk)))
488
	if(!(cd = scsi_cd_get(disk)))
470
		return -ENXIO;
489
		return -ENXIO;
471
490
Lines 512-517 static int sr_block_media_changed(struct Link Here
512
	return cdrom_media_changed(&cd->cdi);
531
	return cdrom_media_changed(&cd->cdi);
513
}
532
}
514
533
534
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
535
static int sr_block_mediactl(struct block_device *bdev, int op, int arg)
536
{
537
	struct gendisk *disk = bdev->bd_disk;
538
	struct scsi_cd *cd = scsi_cd(disk);
539
	return cdrom_mediactl(&cd->cdi, bdev, op, arg);
540
}
541
#endif
542
515
struct block_device_operations sr_bdops =
543
struct block_device_operations sr_bdops =
516
{
544
{
517
	.owner		= THIS_MODULE,
545
	.owner		= THIS_MODULE,
Lines 519-524 struct block_device_operations sr_bdops Link Here
519
	.release	= sr_block_release,
547
	.release	= sr_block_release,
520
	.ioctl		= sr_block_ioctl,
548
	.ioctl		= sr_block_ioctl,
521
	.media_changed	= sr_block_media_changed,
549
	.media_changed	= sr_block_media_changed,
550
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
551
	.mediactl	= sr_block_mediactl,
552
#endif
522
};
553
};
523
554
524
static int sr_open(struct cdrom_device_info *cdi, int purpose)
555
static int sr_open(struct cdrom_device_info *cdi, int purpose)
(-)linux-2.6.10-ck1.orig/fs/block_dev.c (+33 lines)
Lines 524-535 int check_disk_change(struct block_devic Link Here
524
{
524
{
525
	struct gendisk *disk = bdev->bd_disk;
525
	struct gendisk *disk = bdev->bd_disk;
526
	struct block_device_operations * bdops = disk->fops;
526
	struct block_device_operations * bdops = disk->fops;
527
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
528
	struct super_block *sb = NULL;
529
	int supermounted = 0;
530
#endif
527
531
528
	if (!bdops->media_changed)
532
	if (!bdops->media_changed)
529
		return 0;
533
		return 0;
530
	if (!bdops->media_changed(bdev->bd_disk))
534
	if (!bdops->media_changed(bdev->bd_disk))
531
		return 0;
535
		return 0;
532
536
537
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
538
	sb = get_super(bdev);
539
	if (sb) {
540
		atomic_set(&sb->s_media_changed, 1);
541
		supermounted = sb->s_flags & MS_SUPERMOUNTED;
542
		drop_super(sb);
543
	}
544
545
	/*
546
	 * Supermount used to did invalidate_device followed by
547
	 * destroy_buffers. invalidate_device hardly does anything
548
	 * useful here as it won't really invalidate "busy" inodes
549
	 * and every inode in subfs is busy (at least one reference
550
	 * from superfs exists). So now it just flushes
551
	 * buffers so they do not accidentally overwrite newly
552
	 * inserted media
553
	 *
554
	 * FIXME unfortunately during umount VFS may write on its
555
	 * own, like write_super. Those writes will go to a wrong
556
	 * media thus corrupting it :(
557
	 *
558
	 * There is no error print because supermount warns user
559
	 * itself.
560
	 */
561
562
	if (supermounted) {
563
		invalidate_bdev(bdev, 1);
564
	} else
565
#endif
533
	if (__invalidate_device(bdev, 0))
566
	if (__invalidate_device(bdev, 0))
534
		printk("VFS: busy inodes on changed media.\n");
567
		printk("VFS: busy inodes on changed media.\n");
535
568
(-)linux-2.6.10-ck1.orig/fs/ext2/super.c (+6 lines)
Lines 283-288 static match_table_t tokens = { Link Here
283
	{Opt_ignore, "noquota"},
283
	{Opt_ignore, "noquota"},
284
	{Opt_ignore, "quota"},
284
	{Opt_ignore, "quota"},
285
	{Opt_ignore, "usrquota"},
285
	{Opt_ignore, "usrquota"},
286
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
287
	/* Silently ignore NLS options */
288
	{Opt_ignore, "iocharset=%s"},
289
	{Opt_ignore, "codepage=%s"},
290
	{Opt_ignore, "umask=%o"},
291
#endif
286
	{Opt_err, NULL}
292
	{Opt_err, NULL}
287
};
293
};
288
294
(-)linux-2.6.10-ck1.orig/fs/isofs/inode.c (+4 lines)
Lines 364-369 static match_table_t tokens = { Link Here
364
	{Opt_ignore, "conv=auto"},
364
	{Opt_ignore, "conv=auto"},
365
	{Opt_ignore, "conv=a"},
365
	{Opt_ignore, "conv=a"},
366
	{Opt_nocompress, "nocompress"},
366
	{Opt_nocompress, "nocompress"},
367
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
368
	{Opt_ignore, "codepage=%s"},
369
	{Opt_ignore, "umask=%s"},
370
#endif
367
	{Opt_err, NULL}
371
	{Opt_err, NULL}
368
};
372
};
369
373
(-)linux-2.6.10-ck1.orig/fs/Kconfig (+2 lines)
Lines 972-977 config RAMFS Link Here
972
	  To compile this as a module, choose M here: the module will be called
972
	  To compile this as a module, choose M here: the module will be called
973
	  ramfs.
973
	  ramfs.
974
974
975
source "fs/supermount/Kconfig"
976
975
endmenu
977
endmenu
976
978
977
menu "Miscellaneous filesystems"
979
menu "Miscellaneous filesystems"
(-)linux-2.6.10-ck1.orig/fs/Makefile (+2 lines)
Lines 94-96 obj-$(CONFIG_AFS_FS) += afs/ Link Here
94
obj-$(CONFIG_BEFS_FS)		+= befs/
94
obj-$(CONFIG_BEFS_FS)		+= befs/
95
obj-$(CONFIG_HOSTFS)		+= hostfs/
95
obj-$(CONFIG_HOSTFS)		+= hostfs/
96
obj-$(CONFIG_HPPFS)		+= hppfs/
96
obj-$(CONFIG_HPPFS)		+= hppfs/
97
obj-$(CONFIG_SUPERMOUNT)	+= supermount/
98
(-)linux-2.6.10-ck1.orig/fs/namespace.c (+9 lines)
Lines 1044-1049 long do_mount(char * dev_name, char * di Link Here
1044
	if (retval)
1044
	if (retval)
1045
		goto dput_out;
1045
		goto dput_out;
1046
1046
1047
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1048
	if (!(flags & (MS_REMOUNT | MS_MOVE)) &&
1049
	    (nd.mnt->mnt_sb->s_type->fs_flags & FS_NO_SUBMNT)) {
1050
		retval = -EPERM;
1051
		path_release(&nd);
1052
		return retval;
1053
	}
1054
#endif
1055
1047
	if (flags & MS_REMOUNT)
1056
	if (flags & MS_REMOUNT)
1048
		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
1057
		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
1049
				    data_page);
1058
				    data_page);
(-)linux-2.6.10-ck1.orig/fs/super.c (-1 / +26 lines)
Lines 84-89 static struct super_block *alloc_super(v Link Here
84
		s->dq_op = sb_dquot_ops;
84
		s->dq_op = sb_dquot_ops;
85
		s->s_qcop = sb_quotactl_ops;
85
		s->s_qcop = sb_quotactl_ops;
86
		s->s_op = &default_op;
86
		s->s_op = &default_op;
87
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
88
		atomic_set(&s->s_media_changed, 0);
89
#endif
87
	}
90
	}
88
out:
91
out:
89
	return s;
92
	return s;
Lines 551-556 int do_remount_sb(struct super_block *sb Link Here
551
	return 0;
554
	return 0;
552
}
555
}
553
556
557
#ifdef CONFIG_SUPERMOUNT_MODULE
558
EXPORT_SYMBOL(do_remount_sb);
559
#endif
560
554
static void do_emergency_remount(unsigned long foo)
561
static void do_emergency_remount(unsigned long foo)
555
{
562
{
556
	struct super_block *sb;
563
	struct super_block *sb;
Lines 691-701 struct super_block *get_sb_bdev(struct f Link Here
691
		goto out;
698
		goto out;
692
699
693
	if (s->s_root) {
700
	if (s->s_root) {
694
		if ((flags ^ s->s_flags) & MS_RDONLY) {
701
		if (((flags ^ s->s_flags) & MS_RDONLY)
702
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
703
		/* disallow double mounting for supermounted device */
704
		    || ((flags | s->s_flags) & MS_SUPERMOUNTED)
705
#endif
706
		   )
707
		{
695
			up_write(&s->s_umount);
708
			up_write(&s->s_umount);
696
			deactivate_super(s);
709
			deactivate_super(s);
697
			s = ERR_PTR(-EBUSY);
710
			s = ERR_PTR(-EBUSY);
698
		}
711
		}
712
699
		goto out;
713
		goto out;
700
	} else {
714
	} else {
701
		char b[BDEVNAME_SIZE];
715
		char b[BDEVNAME_SIZE];
Lines 803-808 do_kern_mount(const char *fstype, int fl Link Here
803
	if (!type)
817
	if (!type)
804
		return ERR_PTR(-ENODEV);
818
		return ERR_PTR(-ENODEV);
805
819
820
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
821
	/* sanity checks; supermount relies on these assumptions */
822
	if (flags & MS_SUPERMOUNTED) {
823
		sb = ERR_PTR(-EINVAL);
824
		if (type->fs_flags & FS_ODD_RENAME)
825
			goto out;
826
		if (!(type->fs_flags & FS_REQUIRES_DEV))
827
			goto out;
828
		sb = ERR_PTR(-ENOMEM);
829
	}
830
#endif
806
	mnt = alloc_vfsmnt(name);
831
	mnt = alloc_vfsmnt(name);
807
	if (!mnt)
832
	if (!mnt)
808
		goto out;
833
		goto out;
(-)linux-2.6.10-ck1.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.10-ck1.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.10-ck1.orig/fs/supermount/file.c (+691 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)
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);
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
#ifdef CONFIG_SUPERMOUNT_DEBUG
554
		int bug = atomic_read(&subfile->f_count) != 1;
555
#endif
556
		fput(subfile);
557
		subfs_put_access(inode, file->f_mode & FMODE_WRITE);
558
		SUPERMOUNT_BUG_ON(bug);
559
	}
560
561
	if (sfi)
562
		kfree(sfi);
563
564
	LEAVE(sb, "inode=%p file=%p", inode, file);
565
566
	return 0;
567
568
}
569
570
static int
571
supermount_fsync(struct file *file, struct dentry *dentry, int datasync)
572
{
573
	struct super_block *sb = file->f_dentry->d_sb;
574
	struct file *subfile;
575
	int rc;
576
577
	ENTER(sb, "file=%p dentry=%s sync=%d", file, dentry->d_name.name, datasync);
578
579
	rc = -ESTALE;
580
	if (subfs_check_disk_change(sb))
581
		goto out;
582
583
	subfile = get_subfs_file(file);
584
	rc = PTR_ERR(subfile);
585
	if (IS_ERR(subfile))
586
		goto out;
587
588
	rc = -EINVAL;
589
	if (subfile->f_op && subfile->f_op->fsync)
590
		rc = subfile->f_op->fsync(subfile, subfile->f_dentry, datasync);
591
592
	fput(subfile);
593
out:
594
	ENTER(sb, "file=%p dentry=%s rc=%d", file, dentry->d_name.name, rc);
595
596
	return rc;
597
}
598
599
static int
600
supermount_fasync(int fd, struct file *file, int on)
601
{
602
	struct super_block *sb = file->f_dentry->d_sb;
603
	struct file *subfile;
604
	int rc;
605
606
	ENTER(sb, "fd=%d file=%p on=%d", fd, file, on);
607
608
	rc = -ESTALE;
609
	if (subfs_check_disk_change(sb))
610
		goto out;
611
612
	subfile = get_subfs_file(file);
613
	rc = PTR_ERR(subfile);
614
	if (IS_ERR(subfile))
615
		goto out;
616
617
	rc = -EINVAL;
618
	if (subfile->f_op && subfile->f_op->fasync)
619
		rc = subfile->f_op->fasync(fd, subfile, on);
620
621
	fput(subfile);
622
out:
623
	LEAVE(sb, "fd=%d file=%p rc=%d", fd, file, rc);
624
625
	return rc;
626
}
627
628
static int
629
supermount_lock(struct file *file, int cmd, struct file_lock *fl)
630
{
631
	struct super_block *sb = file->f_dentry->d_sb;
632
	struct file *subfile;
633
	int rc;
634
635
	ENTER(sb, "file=%p cmd=%d", file, cmd);
636
637
	rc = -ESTALE;
638
	if (subfs_check_disk_change(sb))
639
		goto out;
640
641
	subfile = get_subfs_file(file);
642
	rc = PTR_ERR(subfile);
643
	if (IS_ERR(subfile))
644
		goto out;
645
646
	rc = 0;
647
	if (subfile->f_op && subfile->f_op->lock)
648
		rc = subfile->f_op->lock(subfile, cmd, fl);
649
	else if (cmd == F_GETLK)
650
		posix_test_lock(file, fl);
651
652
	fput(subfile);
653
out:
654
	LEAVE(sb, "file=%p rc=%d", file, rc);
655
656
	return rc;
657
}
658
659
/* Fixme:
660
 * readv: easy, export churnk from vfs
661
 * writev: easy, export churnk from vfs
662
 * sendpage: only used for networking, not needed
663
 * get_unmmapped_area: only used for devices, not needed
664
 */
665
666
struct file_operations supermount_dir_operations = {
667
	.llseek		= supermount_llseek,
668
	.read		= supermount_read,
669
	.readdir	= supermount_readdir,
670
	.ioctl		= supermount_ioctl,
671
	.open		= supermount_open,
672
	.flush		= supermount_flush,
673
	.release	= supermount_release,
674
	.fsync		= supermount_fsync,
675
	.fasync		= supermount_fasync,
676
};
677
678
struct file_operations supermount_file_operations = {
679
	.llseek		= supermount_llseek,
680
	.read		= supermount_read,
681
	.write		= supermount_write,
682
	.poll		= supermount_poll,
683
	.ioctl		= supermount_ioctl,
684
	.mmap		= supermount_file_mmap, /* from filemap.c */
685
	.open		= supermount_open,
686
	.flush		= supermount_flush,
687
	.release	= supermount_release,
688
	.fsync		= supermount_fsync,
689
	.fasync		= supermount_fasync,
690
	.lock		= supermount_lock,
691
};
(-)linux-2.6.10-ck1.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.10-ck1.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.10-ck1.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.10-ck1.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.10-ck1.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.10-ck1.orig/fs/supermount/namei.c (+1143 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_ODD_RENAME
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
	rc = subdent->d_inode->i_op->readlink(subdent, buffer, buflen);
890
	subfs_put_access(inode, write_on);
891
	inode->i_atime = subdent->d_inode->i_atime;
892
893
put_subdent:
894
	dput(subdent);
895
go_offline:
896
	subfs_go_offline(sb, mnt);
897
out:
898
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
899
900
	return rc;
901
}
902
903
static int
904
supermount_follow_link(struct dentry *dentry, struct nameidata *nd)
905
{
906
	struct super_block *sb = dentry->d_sb;
907
	struct inode *inode = dentry->d_inode;
908
	struct dentry *subdent;
909
	int write_on = NEED_WRITE_ATIME(inode);
910
	int rc;
911
	struct vfsmount *mnt;
912
	
913
	ENTER(sb, "dentry=%s", dentry->d_name.name);
914
915
	mnt = subfs_go_online(sb);
916
	rc = PTR_ERR(mnt);
917
	if (IS_ERR(mnt))
918
		goto out;
919
920
	subdent = get_subfs_dentry(dentry);
921
	rc = PTR_ERR(subdent);
922
	if (IS_ERR(subdent))
923
		goto go_offline;
924
925
	rc = subfs_get_access(inode, write_on);
926
	if (rc)
927
		goto put_subdent;
928
929
	update_atime(subdent->d_inode);
930
	/* FIXME do we need proper subfs nd here? */
931
	rc = subdent->d_inode->i_op->follow_link(subdent, nd);
932
	subfs_put_access(inode, write_on);
933
	inode->i_atime = subdent->d_inode->i_atime;
934
935
put_subdent:
936
	dput(subdent);	
937
go_offline:
938
	subfs_go_offline(sb, mnt);
939
out:
940
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
941
942
	return rc;
943
}
944
945
static int
946
supermount_permission(struct inode *inode, int mask, struct nameidata *nd)
947
{
948
	struct super_block *sb = inode->i_sb;
949
	struct inode *subi;
950
	int rc;
951
	int write_on = !IS_RDONLY(inode) && (mask & MAY_WRITE);
952
	struct vfsmount *mnt;
953
	int fake_permissions = 1;
954
955
	ENTER(sb, "inode=%p", inode);
956
957
	mnt = subfs_go_online(sb);
958
	rc = PTR_ERR(mnt);
959
	if (IS_ERR(mnt))
960
		goto out;
961
962
	subi = get_subfs_inode(inode);
963
	rc = PTR_ERR(subi);
964
	if (IS_ERR(subi))
965
		goto go_offline;
966
967
	rc = subfs_get_access(inode, write_on);
968
	if (rc)
969
		goto put_subi;
970
971
	fake_permissions = 0;
972
	/* FIXME do we need proper subfs nd here */
973
	if (subi->i_op && subi->i_op->permission)
974
		rc = subi->i_op->permission(subi, mask, nd);
975
	else
976
		rc = generic_permission(subi, mask, NULL);
977
978
	subfs_put_access(inode, write_on);
979
980
put_subi:
981
	iput(subi);
982
go_offline:
983
	subfs_go_offline(sb, mnt);
984
out:
985
	if (fake_permissions && inode == sb->s_root->d_inode) {
986
		/* cf. file.c:supermount_open() */
987
		rc = generic_permission(inode, mask, NULL);
988
	}
989
990
	LEAVE(sb, "inode=%p rc=%d fake=%d", inode, rc, fake_permissions);
991
992
	return rc;
993
}
994
995
static int
996
supermount_setattr(struct dentry *dentry, struct iattr *attr)
997
{
998
	struct super_block *sb = dentry->d_sb;
999
	struct inode *subi;
1000
	struct dentry *subdent;
1001
	int rc;
1002
	struct vfsmount *mnt;
1003
1004
	ENTER(sb, "dentry=%s", dentry->d_name.name);
1005
1006
	mnt = subfs_go_online(sb);
1007
	rc = PTR_ERR(mnt);
1008
	if (IS_ERR(mnt))
1009
		goto out;
1010
1011
	subdent = get_subfs_dentry(dentry);
1012
	rc = PTR_ERR(subdent);
1013
	if (IS_ERR(subdent))
1014
		goto go_offline;
1015
1016
	rc = subfs_get_access(dentry->d_inode, 1);
1017
	if (rc)
1018
		goto put_subdent;
1019
1020
	subi = subdent->d_inode;
1021
	if (subi->i_op && subi->i_op->setattr)
1022
		rc = subi->i_op->setattr(subdent, attr);
1023
	else {
1024
		rc = inode_change_ok(subi, attr);
1025
		/*
1026
		 * FIXME
1027
		 * What to do with quota?
1028
		 */
1029
		if (!rc)
1030
			rc = inode_setattr(subi, attr);
1031
	}
1032
	subfs_put_access(dentry->d_inode, 1);
1033
	if (rc)
1034
		goto put_subdent;
1035
1036
	/* 
1037
	 * If it worked, then we need to mark the modification
1038
	 * to the subfs, and we also need to propogate the
1039
	 * change up to the shadowing inode.  
1040
	 */
1041
	attr->ia_mode = subi->i_mode;
1042
	attr->ia_uid = subi->i_uid;
1043
	attr->ia_gid = subi->i_gid;
1044
	attr->ia_size = subi->i_size;
1045
	attr->ia_atime = subi->i_atime;
1046
	attr->ia_mtime = subi->i_mtime;
1047
	attr->ia_ctime = subi->i_ctime;
1048
	attr->ia_valid =
1049
	    ATTR_UID | ATTR_GID | ATTR_MODE | ATTR_SIZE |
1050
	    ATTR_ATIME | ATTR_MTIME | ATTR_CTIME;
1051
	rc = inode_setattr(dentry->d_inode, attr);
1052
1053
put_subdent:
1054
	dput(subdent);
1055
go_offline:
1056
	subfs_go_offline(sb, mnt);
1057
out:
1058
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
1059
1060
	return rc;
1061
}
1062
1063
static int
1064
supermount_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1065
{
1066
	struct super_block *sb = dentry->d_sb;
1067
	struct vfsmount *submnt;
1068
        struct dentry *subdent = 0;
1069
        int rc;
1070
1071
	ENTER(sb, "dentry=%s", dentry->d_name.name);
1072
1073
	/*
1074
	 * do not use subfs_go_online - it will result in ls /mnt
1075
	 * attempting to mount all supermounted directories
1076
	 */
1077
	submnt = subfs_prevent_umount(sb);
1078
	if (submnt)
1079
		subdent = get_subfs_dentry(dentry);
1080
1081
	/*
1082
	 * do not fail stat for stale files - it is needed to
1083
	 * make sure fuser -m /mnt/cdrom lists all processes still
1084
	 * having any (obsolete) file open
1085
	 */
1086
        if (submnt && subdent && !IS_ERR(subdent)) {
1087
                rc = vfs_getattr(submnt, subdent, stat);
1088
		stat->dev = sb->s_dev;
1089
	} else {
1090
		subfs_lock(sb);
1091
		generic_fillattr(dentry->d_inode, stat);
1092
		subfs_unlock(sb);
1093
		rc = 0;
1094
	}
1095
1096
	if (subdent && !IS_ERR(subdent))
1097
		dput(subdent);
1098
	if (submnt)
1099
		subfs_allow_umount(sb, submnt);
1100
1101
	LEAVE(sb, "dentry=%s rc=%d", dentry->d_name.name, rc);
1102
1103
	return rc;
1104
}
1105
1106
/*
1107
 * directories can handle most operations...  supermount/namei.c just
1108
 * passes them through to the underlying subfs, except for lookup().
1109
 */
1110
1111
/* truncate: is not necesary, handled with setattr
1112
 * revalidate: only needed by nfs
1113
 * ->getattr:	FIXME is not appeared to be used anywhere in kernel; so I am
1114
 *  		not sure how to implement it or what to return
1115
 * FIXME: implement accl functions
1116
 */
1117
1118
struct inode_operations supermount_dir_iops = {
1119
	.create		= supermount_create,
1120
	.lookup		= supermount_lookup,
1121
	.link		= supermount_link,
1122
	.unlink		= supermount_unlink,
1123
	.symlink	= supermount_symlink,
1124
	.mkdir		= supermount_mkdir,
1125
	.rmdir		= supermount_rmdir,
1126
	.mknod		= supermount_mknod,
1127
	.rename		= supermount_rename,
1128
	.permission	= supermount_permission,
1129
	.setattr	= supermount_setattr,
1130
	.getattr	= supermount_getattr,
1131
};
1132
1133
struct inode_operations supermount_symlink_iops = {
1134
	.readlink	= supermount_readlink,
1135
	.follow_link	= supermount_follow_link,
1136
	.setattr	= supermount_setattr,
1137
	.getattr	= supermount_getattr,
1138
};
1139
1140
struct inode_operations supermount_file_iops = {
1141
	.setattr	= supermount_setattr,
1142
	.getattr	= supermount_getattr,
1143
};
(-)linux-2.6.10-ck1.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.10-ck1.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 inline 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 inline 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 inline 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.10-ck1.orig/fs/supermount/super.c (+646 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)
353
{
354
        return get_sb_nodev(fs_type, flags, data, supermount_read_super);
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 int
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 0;
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
{
557
	int rc = 0;
558
	struct super_block *subsb;
559
	struct vfsmount *mnt;
560
561
	ENTER(sb);
562
563
	(void)subfs_check_disk_change(sb);
564
565
	mnt = subfs_prevent_umount(sb);
566
	if (!mnt)
567
		goto out;
568
569
	subsb = subfs_get_sb(sb);
570
	if (subsb && subsb->s_op && subsb->s_op->statfs)
571
		rc = subsb->s_op->statfs(subsb, buf);
572
	if (!rc)
573
		buf->f_type = SUPERMOUNT_SUPER_MAGIC;
574
575
	subfs_allow_umount(sb, mnt);
576
out:
577
	LEAVE(sb, "rc=%d", rc);
578
579
	return rc;
580
}
581
582
static int
583
supermount_remount_fs(struct super_block *sb, int *flags, char *data)
584
{
585
	return -ENOSYS;
586
}
587
588
/*
589
 * based on fs/ntfs/inode.c:ntfs_show_options
590
 */
591
static int
592
supermount_show_options(struct seq_file *sf, struct vfsmount *mnt)
593
{
594
	struct supermount_sb_info *sbi = supermount_sbi(mnt->mnt_sb);
595
596
	seq_printf(sf, ",dev=%s", sbi->devname);
597
	seq_puts(sf, ",fs=");
598
	if (sbi->s_type == default_fs_types)
599
		seq_puts(sf, "auto");
600
	else 
601
		seq_puts(sf, sbi->s_type);
602
	seq_puts(sf, ",tray_lock=");
603
	if (sbi->tray_lock == TRAY_LOCK_ALWAYS)
604
		seq_puts(sf, "always");
605
	else if (sbi->tray_lock == TRAY_LOCK_NEVER)
606
		seq_puts(sf, "never");
607
	else if (sbi->tray_lock == TRAY_LOCK_ONWRITE)
608
		seq_puts(sf, "onwrite");
609
	else
610
		SUPERMOUNT_BUG_ON(1);
611
612
	if (sbi->s_debug)
613
		seq_printf(sf, ",debug=0x%lx", sbi->s_debug);
614
	if (sbi->s_data)
615
		seq_printf(sf, ",--,%s", sbi->s_data);
616
	return 0;
617
}
618
619
/*
620
 * ->read_inode:	not needed
621
 * ->dirty_inode:	probably not needed. It appears VFS layer never
622
 *  			calls mark_inode_dirty itself; exception is
623
 *  			UPDATE_ATIME and it is already handled specially
624
 *  			FIXME
625
 *  			It may be needed for knfsd and similar
626
 * ->put_inode:		not needed
627
 * ->delete_inode:	not needed
628
 * ->write_super:	FIXME not needed, we do not have any backing store
629
 * ->sync_fs:		not needed
630
 * ->write_super_lockfs:not needed
631
 * ->unlockfs:		not needed
632
 * ->umount_begin:	TODO maybe to move subfs_umount aways from put_super
633
 * ->fh_to_dentry:	TODO may be
634
 * ->dentry_to_fh:	TODO may be
635
 */
636
static struct super_operations supermount_sops = {
637
	.alloc_inode	= supermount_alloc_inode,
638
	.destroy_inode	= supermount_destroy_inode,
639
	.write_inode	= supermount_write_inode,
640
	.clear_inode	= supermount_clear_inode,
641
	.put_super	= supermount_put_super,
642
	.write_super	= supermount_write_super,
643
	.statfs		= supermount_statfs,
644
	.remount_fs	= supermount_remount_fs,
645
	.show_options	= supermount_show_options,
646
};
(-)linux-2.6.10-ck1.orig/fs/supermount/supermount.h (+497 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.8"
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
	(!(IS_NOATIME(inode) || \
150
	 (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode)) || \
151
	 IS_RDONLY(inode)))
152
153
154
/*
155
 * supermount super-block data in memory
156
 */
157
struct supermount_sb_info;
158
struct supermount_sb_info {
159
	/* == options == */
160
	unsigned long s_debug;	/* debug flags S_DBG_* */
161
	char *s_type;		/* Type of fs to be sub-mounted */
162
	char *devname;		/* Where to mount the subfs from */
163
	char *s_data;		/* Data to pass when mounting subfs */
164
	/* == end of options == */
165
	struct vfsmount *s_undermount;
166
				/* Mount point for subfs */
167
	int readcount;		/* Refcount of read access
168
				   on the filesystem */
169
	int writecount;		/* Refcount of write access
170
				   on the filesystem */
171
	int lockcount;		/* Refcount of requests to lock tray */
172
	struct list_head s_inodes;
173
				/* list of active inodes */
174
	struct list_head s_files;
175
				/* list of active files */
176
	struct list_head s_dentries;
177
				/* list of active dentries */
178
	struct semaphore sem;
179
	struct super_block *host;
180
				/* needed for procfs support */
181
	struct supermount_sb_info *next;
182
				/* list of all supermount fs */
183
	unsigned int tray_lock:2;
184
	unsigned int disabled:1;
185
	unsigned int rw:1;
186
};
187
188
static inline struct supermount_sb_info *
189
supermount_sbi(struct super_block *sb)
190
{
191
	struct supermount_sb_info *sbi;
192
	BUG_ON(!sb);
193
	BUG_ON(sb->s_type != &supermount_fs_type);
194
195
	sbi = (struct supermount_sb_info *) (sb->s_fs_info);
196
	BUG_ON(!sbi);
197
198
	return sbi;
199
}
200
201
static inline struct vfsmount *
202
subfs_mnt(struct super_block *sb)
203
{
204
	return supermount_sbi(sb)->s_undermount;
205
}
206
207
static inline struct super_block *
208
subfs_sb(struct super_block *sb)
209
{
210
	struct vfsmount *mnt = subfs_mnt(sb);
211
212
	if (mnt) return mnt->mnt_sb;
213
214
	return 0;
215
}
216
217
/* this is expected to run under sb->sem */
218
static inline int
219
subfs_is_mounted(struct super_block *sb)
220
{
221
	struct supermount_sb_info *sbi = supermount_sbi(sb);
222
223
	return sbi->s_undermount != 0;
224
}
225
226
/* this is expected to run under sb->sem */
227
static inline int
228
subfs_is_busy(struct super_block *sb)
229
{
230
	struct vfsmount *mnt = subfs_mnt(sb);
231
232
	/*
233
	 * In "normal" case mnt_count is 2. But we currently do
234
	 * not insert subfs into task namespace so count is 1
235
	 * FIXME
236
	 * This also means we do not do_umount i.e. do not run
237
	 * either umount_begin or DQUOT_OFF for subfs.
238
	 */
239
	if (mnt) return atomic_read(&mnt->mnt_count) > 1;
240
241
	return 0;
242
}
243
244
/* this is expected to run under sb->sem */
245
static inline int
246
subfs_is_rw(struct super_block *sb)
247
{
248
	struct super_block *subsb;
249
250
	if (!subfs_is_mounted(sb))
251
		return 0;
252
	
253
	subsb = subfs_sb(sb);
254
	return !(subsb->s_flags & MS_RDONLY);
255
}
256
257
static inline void
258
subfs_lock(struct super_block *sb)
259
{
260
	struct supermount_sb_info *sbi = supermount_sbi(sb);
261
262
	down(&sbi->sem);
263
}
264
265
static inline void
266
subfs_unlock(struct super_block *sb)
267
{
268
	struct supermount_sb_info *sbi = supermount_sbi(sb);
269
270
	up(&sbi->sem);
271
}
272
273
/*
274
 * query debug flags set
275
 */
276
static inline int supermount_dbg(struct super_block *sb, unsigned long flags)
277
{
278
	struct supermount_sb_info *sbi = supermount_sbi(sb);
279
280
	return sbi->s_debug & flags;
281
}
282
283
/*
284
 * supermount inode info
285
 */
286
287
struct supermount_inode_info {
288
	struct list_head list;
289
  	struct inode *inode;	/* subfs inode */
290
	int readcount;
291
	int writecount;
292
	struct inode vfs_inode;	/* superfs inode */
293
};
294
295
static inline int
296
is_inode_supermounted(struct inode *inode)
297
{
298
	return inode && inode->i_sb && inode->i_sb->s_type == &supermount_fs_type;
299
}
300
301
static inline struct supermount_inode_info *
302
supermount_i(struct inode *inode)
303
{
304
	SUPERMOUNT_BUG_ON(!is_inode_supermounted(inode));
305
306
	return list_entry(inode, struct supermount_inode_info, vfs_inode);
307
}
308
309
static inline int
310
is_inode_obsolete(struct inode *inode)
311
{
312
	struct supermount_inode_info *sii = supermount_i(inode);
313
314
	return sii->inode == 0;
315
}
316
317
static inline void
318
supermount_list_add_inode(struct inode *inode)
319
{
320
	struct supermount_inode_info *sii = supermount_i(inode);
321
322
	list_add(&(sii->list), &(supermount_sbi(inode->i_sb)->s_inodes));
323
}
324
325
/*
326
 * FIXME
327
 * Should we propagate all flags? *_QUOTA looks very possible candidate
328
 * We can't just assign them because other flags may be set by VFS
329
 */
330
#define SMNT_INODE_FLAGS (S_IMMUTABLE|S_NOATIME|S_APPEND|S_SYNC)
331
static inline void
332
set_inode_flags(struct inode *inode, struct inode *subi)
333
{
334
	inode->i_flags &= ~SMNT_INODE_FLAGS;
335
	if (subi)
336
		inode->i_flags |= (subi->i_flags & SMNT_INODE_FLAGS);
337
}
338
339
/*
340
 * supermount dentry info
341
 */
342
343
struct supermount_dentry_info {
344
	struct list_head list;
345
	struct dentry *dentry;
346
	struct dentry *host;
347
};
348
349
static inline int
350
is_dentry_supermounted(struct dentry *dentry)
351
{
352
	return (dentry && dentry->d_sb && dentry->d_sb->s_type == &supermount_fs_type);
353
}
354
355
static inline struct supermount_dentry_info *
356
supermount_d(struct dentry *dentry)
357
{
358
	SUPERMOUNT_BUG_ON(!is_dentry_supermounted(dentry));
359
	SUPERMOUNT_BUG_ON(!dentry->d_fsdata);
360
361
	return  (struct supermount_dentry_info *)dentry->d_fsdata;
362
}
363
364
static inline int
365
is_dentry_obsolete(struct dentry *dentry)
366
{
367
	struct supermount_dentry_info *sdi = supermount_d(dentry);
368
369
	return sdi->dentry == 0;
370
}
371
372
/*
373
 * Supermount file info 
374
 */
375
376
struct supermount_file_info {
377
	struct list_head	list;
378
	struct file *		host;
379
	struct file		*file;
380
	pid_t			owner;
381
	struct vm_operations_struct *vm_ops;
382
	unsigned int		fake:1;
383
};
384
385
static inline int
386
is_file_supermounted(struct file *file)
387
{
388
	return file && file->f_dentry && is_dentry_supermounted(file->f_dentry);
389
}
390
391
static inline struct supermount_file_info *
392
supermount_f(struct file *file)
393
{
394
	SUPERMOUNT_BUG_ON(!is_file_supermounted(file));
395
	SUPERMOUNT_BUG_ON(!file->f_supermount);
396
397
	return  file->f_supermount;
398
}
399
400
static inline int
401
is_file_obsolete(struct file *file)
402
{
403
	struct supermount_file_info *sfi = supermount_f(file);
404
405
	return sfi->file == NULL;
406
}
407
408
static inline int
409
is_file_fake(struct file *file)
410
{
411
	struct supermount_file_info *sfi = supermount_f(file);
412
413
	return sfi->fake;
414
}
415
416
/* dentry.c */
417
extern rwlock_t d_compare_lock;
418
extern struct dentry_operations supermount_dops;
419
extern int init_dentry_info(struct dentry *);
420
extern void attach_subfs_dentry(struct dentry *, struct dentry *);
421
extern struct dentry *get_subfs_dentry(struct dentry *dentry);
422
 
423
/* file.c */
424
extern struct file_operations supermount_dir_operations;
425
extern struct file_operations supermount_file_operations;
426
427
/* filemap.c */
428
extern struct vm_operations_struct supermount_vm_ops;
429
extern int supermount_file_mmap(struct file *, struct vm_area_struct *);
430
extern struct file *get_subfs_file(struct file*);
431
432
/* mediactl.c */
433
extern void supermount_mediactl(struct super_block *, int, int);
434
static inline void
435
supermount_lock_door(struct super_block *sb)
436
{
437
	supermount_mediactl(sb, MEDIA_LOCK, 1);
438
}
439
static inline void
440
supermount_unlock_door(struct super_block *sb)
441
{
442
	supermount_mediactl(sb, MEDIA_UNLOCK, 1);
443
}
444
445
static inline void
446
mark_media_supermounted(struct super_block *sb)
447
{
448
	supermount_mediactl(sb, SUPERMOUNT_INC_COUNT, 0);
449
	supermount_mediactl(sb, MEDIA_UNLOCK, 0);
450
}
451
452
static inline void
453
unmark_media_supermounted(struct super_block *sb)
454
{
455
	supermount_mediactl(sb, SUPERMOUNT_DEC_COUNT, 0);
456
}
457
458
/* namei.c */
459
extern struct inode_operations supermount_dir_iops;
460
extern struct inode_operations supermount_file_iops;
461
extern struct inode_operations supermount_symlink_iops;
462
extern struct inode *create_supermount_inode(struct super_block *);
463
extern struct inode *get_subfs_inode(struct inode *inode);
464
465
/* proc.c */
466
#ifdef CONFIG_PROC_FS
467
extern void supermount_proc_register(void);
468
extern void supermount_proc_unregister(void);
469
extern void supermount_proc_insert(struct supermount_sb_info *);
470
extern void supermount_proc_remove(struct supermount_sb_info *);
471
#else
472
#define supermount_proc_register() do { } while(0)
473
#define supermount_proc_unregister() do { } while(0)
474
#define supermount_proc_insert(sbi) do { } while(0)
475
#define supermount_proc_remove(sbi) do { } while(0)
476
#endif
477
478
/* subfs.c */
479
extern void subfs_umount(struct super_block *sb, int);
480
extern struct vfsmount *subfs_go_online(struct super_block *);
481
extern void subfs_go_offline(struct super_block *, struct vfsmount *);
482
extern int subfs_get_access(struct inode *, int);
483
extern void subfs_put_access(struct inode *, int);
484
extern int subfs_check_disk_change(struct super_block *);
485
extern struct vfsmount *subfs_prevent_umount(struct super_block *);
486
extern void subfs_allow_umount(struct super_block *, struct vfsmount *);
487
extern struct vfsmount *subfs_get_mnt(struct super_block *sb);
488
extern struct super_block *subfs_get_sb(struct super_block *sb);
489
extern void subfs_clear_inode(struct inode *);
490
491
/* super.c */
492
extern struct super_block *supermount_get_sb(struct file_system_type *, int, const char *, void *);
493
extern void attach_subfs_inode(struct inode *, struct inode *);
494
extern void supermount_init_root_inode(struct inode *);
495
extern char *strdup(const char *);
496
497
#endif				/* _SUPERMOUNT_I_H */
(-)linux-2.6.10-ck1.orig/fs/udf/super.c (-1 / +7 lines)
Lines 276-282 enum { Link Here
276
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
276
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
277
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
277
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
278
	Opt_rootdir, Opt_utf8, Opt_iocharset,
278
	Opt_rootdir, Opt_utf8, Opt_iocharset,
279
	Opt_err
279
	Opt_ignore, Opt_err
280
};
280
};
281
281
282
static match_table_t tokens = {
282
static match_table_t tokens = {
Lines 301-306 static match_table_t tokens = { Link Here
301
	{Opt_rootdir, "rootdir=%u"},
301
	{Opt_rootdir, "rootdir=%u"},
302
	{Opt_utf8, "utf8"},
302
	{Opt_utf8, "utf8"},
303
	{Opt_iocharset, "iocharset=%s"},
303
	{Opt_iocharset, "iocharset=%s"},
304
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
305
	/* Silently ignore NLS option */
306
	{Opt_ignore, "codepage=%s"},
307
#endif
304
	{Opt_err, NULL}
308
	{Opt_err, NULL}
305
};
309
};
306
310
Lines 421-426 udf_parse_options(char *options, struct Link Here
421
				uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
425
				uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
422
				break;
426
				break;
423
#endif
427
#endif
428
			case Opt_ignore:
429
				break;
424
			default:
430
			default:
425
				printk(KERN_ERR "udf: bad mount option \"%s\" "
431
				printk(KERN_ERR "udf: bad mount option \"%s\" "
426
						"or missing value\n", p);
432
						"or missing value\n", p);
(-)linux-2.6.10-ck1.orig/include/linux/cdrom.h (+3 lines)
Lines 992-997 extern int cdrom_release(struct cdrom_de 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.10-ck1.orig/include/linux/fs.h (+14 lines)
Lines 101-106 extern int dir_notify_enable; Link Here
101
/* public flags for file_system_type */
101
/* public flags for file_system_type */
102
#define FS_REQUIRES_DEV 1 
102
#define FS_REQUIRES_DEV 1 
103
#define FS_BINARY_MOUNTDATA 2
103
#define FS_BINARY_MOUNTDATA 2
104
#define FS_NO_SUBMNT	64	/* Prevent mounting over this filesystem */
104
#define FS_REVAL_DOT	16384	/* Check the paths ".", ".." for staleness */
105
#define FS_REVAL_DOT	16384	/* Check the paths ".", ".." for staleness */
105
#define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
106
#define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
106
				  * as nfs_rename() will be cleaned up
107
				  * as nfs_rename() will be cleaned up
Lines 124-129 extern int dir_notify_enable; Link Here
124
#define MS_VERBOSE	32768
125
#define MS_VERBOSE	32768
125
#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
126
#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
126
#define MS_ONE_SECOND	(1<<17)	/* fs has 1 sec a/m/ctime resolution */
127
#define MS_ONE_SECOND	(1<<17)	/* fs has 1 sec a/m/ctime resolution */
128
#define MS_SUPERMOUNTED	(1<<18)
127
#define MS_ACTIVE	(1<<30)
129
#define MS_ACTIVE	(1<<30)
128
#define MS_NOUSER	(1<<31)
130
#define MS_NOUSER	(1<<31)
129
131
Lines 599-604 struct file { Link Here
599
	struct list_head	f_ep_links;
601
	struct list_head	f_ep_links;
600
	spinlock_t		f_ep_lock;
602
	spinlock_t		f_ep_lock;
601
#endif /* #ifdef CONFIG_EPOLL */
603
#endif /* #ifdef CONFIG_EPOLL */
604
 
605
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
606
	/* Used by supermount. Use(fullness) unconfirmed */
607
	void                    *f_supermount;
608
#endif
602
	struct address_space	*f_mapping;
609
	struct address_space	*f_mapping;
603
};
610
};
604
extern spinlock_t files_lock;
611
extern spinlock_t files_lock;
Lines 797-802 struct super_block { Link Here
797
	 * even looking at it. You had been warned.
804
	 * even looking at it. You had been warned.
798
	 */
805
	 */
799
	struct semaphore s_vfs_rename_sem;	/* Kludge */
806
	struct semaphore s_vfs_rename_sem;	/* Kludge */
807
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
808
       atomic_t s_media_changed;
809
#endif
810
800
};
811
};
801
812
802
/*
813
/*
Lines 876-881 struct block_device_operations { Link Here
876
	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
887
	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
877
	int (*media_changed) (struct gendisk *);
888
	int (*media_changed) (struct gendisk *);
878
	int (*revalidate_disk) (struct gendisk *);
889
	int (*revalidate_disk) (struct gendisk *);
890
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
891
	int (*mediactl) (struct block_device *, int, int);
892
#endif
879
	struct module *owner;
893
	struct module *owner;
880
};
894
};
881
895
(-)linux-2.6.10-ck1.orig/include/linux/genhd.h (+3 lines)
Lines 126-131 struct gendisk { Link Here
126
#else
126
#else
127
	struct disk_stats dkstats;
127
	struct disk_stats dkstats;
128
#endif
128
#endif
129
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
130
	int scount;			/* number of supermounted partitions */
131
#endif
129
};
132
};
130
133
131
/* 
134
/* 
(-)linux-2.6.10-ck1.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 */

Return to bug 76086