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

(-)linux-2.6.8.1_supermount/Documentation/filesystems/00-INDEX (+2 lines)
Lines 36-41 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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh Exp $
(-)linux-2.6.8.1_supermount/drivers/cdrom/cdrom.c (-9 / +47 lines)
Lines 275-280 Link Here
275
#include <linux/fcntl.h>
275
#include <linux/fcntl.h>
276
#include <linux/blkdev.h>
276
#include <linux/blkdev.h>
277
#include <linux/times.h>
277
#include <linux/times.h>
278
#include <linux/supermount_media.h>
278
279
279
#include <asm/uaccess.h>
280
#include <asm/uaccess.h>
280
281
Lines 333-339 Link Here
333
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
334
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
334
335
335
/* Not-exported routines. */
336
/* Not-exported routines. */
336
static int open_for_data(struct cdrom_device_info * cdi);
337
static int open_for_data(struct cdrom_device_info * cdi, struct block_device *bdev);
337
static int check_for_audio_disc(struct cdrom_device_info * cdi,
338
static int check_for_audio_disc(struct cdrom_device_info * cdi,
338
			 struct cdrom_device_ops * cdo);
339
			 struct cdrom_device_ops * cdo);
339
static void sanitize_format(union cdrom_addr *addr, 
340
static void sanitize_format(union cdrom_addr *addr, 
Lines 885-891 Link Here
885
 */
886
 */
886
int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
887
int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
887
{
888
{
888
	int ret;
889
	int ret = 0;
889
890
890
	cdinfo(CD_OPEN, "entering cdrom_open\n"); 
891
	cdinfo(CD_OPEN, "entering cdrom_open\n"); 
891
892
Lines 895-901 Link Here
895
	if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
896
	if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
896
		ret = cdi->ops->open(cdi, 1);
897
		ret = cdi->ops->open(cdi, 1);
897
	} else {
898
	} else {
898
		ret = open_for_data(cdi);
899
		open_for_data(cdi, ip->i_bdev);
899
		if (ret)
900
		if (ret)
900
			goto err;
901
			goto err;
901
		if (fp->f_mode & FMODE_WRITE) {
902
		if (fp->f_mode & FMODE_WRITE) {
Lines 923-929 Link Here
923
}
924
}
924
925
925
static
926
static
926
int open_for_data(struct cdrom_device_info * cdi)
927
int open_for_data(struct cdrom_device_info * cdi, struct block_device *bdev)
927
{
928
{
928
	int ret;
929
	int ret;
929
	struct cdrom_device_ops *cdo = cdi->ops;
930
	struct cdrom_device_ops *cdo = cdi->ops;
Lines 1006-1012 Link Here
1006
		cdinfo(CD_OPEN, "open device failed.\n"); 
1007
		cdinfo(CD_OPEN, "open device failed.\n"); 
1007
		goto clean_up_and_return;
1008
		goto clean_up_and_return;
1008
	}
1009
	}
1009
	if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
1010
	if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK) &&
1011
	    supermount_usage_count(bdev, cdi->use_count) > 0) {
1010
			cdo->lock_door(cdi, 1);
1012
			cdo->lock_door(cdi, 1);
1011
			cdinfo(CD_OPEN, "door locked.\n");
1013
			cdinfo(CD_OPEN, "door locked.\n");
1012
	}
1014
	}
Lines 1019-1025 Link Here
1019
	This ensures that the drive gets unlocked after a mount fails.  This 
1021
	This ensures that the drive gets unlocked after a mount fails.  This 
1020
	is a goto to avoid bloating the driver with redundant code. */ 
1022
	is a goto to avoid bloating the driver with redundant code. */ 
1021
clean_up_and_return:
1023
clean_up_and_return:
1022
	cdinfo(CD_WARNING, "open failed.\n"); 
1024
	cdinfo(CD_OPEN, "open failed.\n"); 
1023
	if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1025
	if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1024
			cdo->lock_door(cdi, 0);
1026
			cdo->lock_door(cdi, 0);
1025
			cdinfo(CD_OPEN, "door unlocked.\n");
1027
			cdinfo(CD_OPEN, "door unlocked.\n");
Lines 1096-1102 Link Here
1096
		cdi->use_count--;
1098
		cdi->use_count--;
1097
	if (cdi->use_count == 0)
1099
	if (cdi->use_count == 0)
1098
		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
1100
		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
1099
	if (cdi->use_count == 0 &&
1101
	if (!supermount_usage_count(fp ? fp->f_dentry->d_inode->i_bdev : 0, cdi->use_count) &&
1100
	    (cdo->capability & CDC_LOCK) && !keeplocked) {
1102
	    (cdo->capability & CDC_LOCK) && !keeplocked) {
1101
		cdinfo(CD_CLOSE, "Unlocking door!\n");
1103
		cdinfo(CD_CLOSE, "Unlocking door!\n");
1102
		cdo->lock_door(cdi, 0);
1104
		cdo->lock_door(cdi, 0);
Lines 1368-1373 Link Here
1368
		tracks->cdi, tracks->xa);
1370
		tracks->cdi, tracks->xa);
1369
}	
1371
}	
1370
1372
1373
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1374
/*
1375
 * MEDIA_LOCK, MEDIA_UNLOCK
1376
 *   optarg == 0 - do not adjust usage count (compatibility)
1377
 *   optarg == 1 - adjust usage count
1378
 */
1379
int cdrom_mediactl(struct cdrom_device_info *cdi, struct block_device *bdev, int op, int optarg)
1380
{
1381
	struct cdrom_device_ops *cdo = cdi->ops;
1382
1383
	switch (op) {
1384
	case MEDIA_LOCK:
1385
	case MEDIA_UNLOCK:
1386
		if (op == MEDIA_UNLOCK && optarg) {
1387
			cdi->use_count--;
1388
		if (cdi->use_count < 0)
1389
			cdi->use_count = 0;
1390
		}
1391
		if (cdo->capability & ~cdi->mask & CDC_LOCK &&
1392
		    cdi->options & CDO_LOCK &&
1393
			supermount_usage_count(bdev, cdi->use_count) == 0)
1394
			cdo->lock_door(cdi, (op == MEDIA_LOCK));
1395
		if (op == MEDIA_LOCK && optarg)
1396
			cdi->use_count++;
1397
		break;
1398
	default:
1399
		return -EINVAL;
1400
	}
1401
	return 0;
1402
}
1403
#endif
1404
1371
/* Requests to the low-level drivers will /always/ be done in the
1405
/* Requests to the low-level drivers will /always/ be done in the
1372
   following format convention:
1406
   following format convention:
1373
1407
Lines 2114-2121 Link Here
2114
		cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n"); 
2148
		cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n"); 
2115
		if (!CDROM_CAN(CDC_OPEN_TRAY))
2149
		if (!CDROM_CAN(CDC_OPEN_TRAY))
2116
			return -ENOSYS;
2150
			return -ENOSYS;
2117
		if (cdi->use_count != 1 || keeplocked)
2151
		if (keeplocked ||
2118
			return -EBUSY;
2152
		    (supermount_usage_count(ip->i_bdev,cdi->use_count) != 1))
2153
                        return -EBUSY;
2119
		if (CDROM_CAN(CDC_LOCK))
2154
		if (CDROM_CAN(CDC_LOCK))
2120
			if ((ret=cdo->lock_door(cdi, 0)))
2155
			if ((ret=cdo->lock_door(cdi, 0)))
2121
				return ret;
2156
				return ret;
Lines 2914-2919 Link Here
2914
EXPORT_SYMBOL(cdrom_release);
2949
EXPORT_SYMBOL(cdrom_release);
2915
EXPORT_SYMBOL(cdrom_ioctl);
2950
EXPORT_SYMBOL(cdrom_ioctl);
2916
EXPORT_SYMBOL(cdrom_media_changed);
2951
EXPORT_SYMBOL(cdrom_media_changed);
2952
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2953
EXPORT_SYMBOL(cdrom_mediactl);
2954
#endif
2917
EXPORT_SYMBOL(cdrom_number_of_slots);
2955
EXPORT_SYMBOL(cdrom_number_of_slots);
2918
EXPORT_SYMBOL(cdrom_mode_select);
2956
EXPORT_SYMBOL(cdrom_mode_select);
2919
EXPORT_SYMBOL(cdrom_mode_sense);
2957
EXPORT_SYMBOL(cdrom_mode_sense);
(-)linux-2.6.8.1_supermount/drivers/cdrom/cdu31a.c (+29 lines)
Lines 3173-3178 Link Here
3173
3173
3174
static int scd_block_release(struct inode *inode, struct file *file)
3174
static int scd_block_release(struct inode *inode, struct file *file)
3175
{
3175
{
3176
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3177
        /*
3178
         * This is the same sort of clockload as use in blkdev_get.
3179
         * We need information whether device is supermounted inside
3180
         * of cdrom_release to decide if tray must be unlocked.
3181
         * This information so far is available only by looking
3182
         * up superblock but it needs struct *bdev and it is not
3183
         * available in cdrom_release anymore
3184
         */
3185
        struct dentry t_dentry;
3186
        struct file t_file;
3187
3188
        if (!file) {
3189
                t_file.f_dentry = &t_dentry;
3190
                t_dentry.d_inode = inode;
3191
                file = &t_file;
3192
        }
3193
#endif
3194
3176
	return cdrom_release(&scd_info, file);
3195
	return cdrom_release(&scd_info, file);
3177
}
3196
}
3178
3197
Lines 3187-3192 Link Here
3187
	return cdrom_media_changed(&scd_info);
3206
	return cdrom_media_changed(&scd_info);
3188
}
3207
}
3189
3208
3209
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3210
static int scd_block_mediactl(struct block_device *bdev, int op, int arg)
3211
{
3212
	return cdrom_mediactl(&scd_info, bdev, op, arg);
3213
}
3214
#endif
3215
3190
struct block_device_operations scd_bdops =
3216
struct block_device_operations scd_bdops =
3191
{
3217
{
3192
	.owner		= THIS_MODULE,
3218
	.owner		= THIS_MODULE,
Lines 3194-3199 Link Here
3194
	.release	= scd_block_release,
3220
	.release	= scd_block_release,
3195
	.ioctl		= scd_block_ioctl,
3221
	.ioctl		= scd_block_ioctl,
3196
	.media_changed	= scd_block_media_changed,
3222
	.media_changed	= scd_block_media_changed,
3223
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3224
	.mediactl	= scd_block_mediactl,
3225
#endif
3197
};
3226
};
3198
3227
3199
static struct gendisk *scd_gendisk;
3228
static struct gendisk *scd_gendisk;
(-)linux-2.6.8.1_supermount/drivers/cdrom/cm206.c (+29 lines)
Lines 1357-1362 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 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 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.8.1_supermount/drivers/cdrom/mcd.c (+29 lines)
Lines 221-226 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 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 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.8.1_supermount/drivers/cdrom/mcdx.c (+30 lines)
Lines 226-231 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 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 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.8.1_supermount/drivers/cdrom/sbpcd.c (+30 lines)
Lines 5365-5370 Link Here
5365
static int sbpcd_block_release(struct inode *inode, struct file *file)
5365
static int sbpcd_block_release(struct inode *inode, struct file *file)
5366
{
5366
{
5367
	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5367
	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5368
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5369
        /*
5370
         * This is the same sort of clockload as use in blkdev_get.
5371
         * We need information whether device is supermounted inside
5372
         * of cdrom_release to decide if tray must be unlocked.
5373
         * This information so far is available only by looking
5374
         * up superblock but it needs struct *bdev and it is not
5375
         * available in cdrom_release anymore
5376
         */
5377
        struct dentry t_dentry;
5378
        struct file t_file;
5379
5380
        if (!file) {
5381
                t_file.f_dentry = &t_dentry;
5382
                t_dentry.d_inode = inode;
5383
                file = &t_file;
5384
        }
5385
#endif
5386
5368
	return cdrom_release(p->sbpcd_infop, file);
5387
	return cdrom_release(p->sbpcd_infop, file);
5369
}
5388
}
5370
5389
Lines 5381-5386 Link Here
5381
	return cdrom_media_changed(p->sbpcd_infop);
5400
	return cdrom_media_changed(p->sbpcd_infop);
5382
}
5401
}
5383
5402
5403
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5404
static int sbpcd_block_mediactl(struct block_device *bdev, int op, int arg)
5405
{
5406
	struct sbpcd_drive *p = bdev->bd_disk->private_data;
5407
	return cdrom_mediactl(p->sbpcd_infop, bdev, op, arg);
5408
}
5409
#endif
5410
5384
static struct block_device_operations sbpcd_bdops =
5411
static struct block_device_operations sbpcd_bdops =
5385
{
5412
{
5386
	.owner		= THIS_MODULE,
5413
	.owner		= THIS_MODULE,
Lines 5388-5393 Link Here
5388
	.release	= sbpcd_block_release,
5415
	.release	= sbpcd_block_release,
5389
	.ioctl		= sbpcd_block_ioctl,
5416
	.ioctl		= sbpcd_block_ioctl,
5390
	.media_changed	= sbpcd_block_media_changed,
5417
	.media_changed	= sbpcd_block_media_changed,
5418
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5419
	.mediactl	= sbpcd_block_mediactl,
5420
#endif
5391
};
5421
};
5392
/*==========================================================================*/
5422
/*==========================================================================*/
5393
/*
5423
/*
(-)linux-2.6.8.1_supermount/drivers/ide/ide-cd.c (-1 / +32 lines)
Lines 3384-3389 Link Here
3384
{
3384
{
3385
	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
3385
	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
3386
	struct cdrom_info *info = drive->driver_data;
3386
	struct cdrom_info *info = drive->driver_data;
3387
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3388
	/*
3389
	 * This is the same sort of clockload as use in blkdev_get.
3390
	 * We need information whether device is supermounted inside
3391
	 * of cdrom_release to decide if tray must be unlocked.
3392
	 * This information so far is available only by looking
3393
	 * up superblock but it needs struct *bdev and it is not
3394
	 * available in cdrom_release anymore
3395
	 */
3396
	struct dentry t_dentry;
3397
	struct file t_file;
3398
3399
	if (!file) {
3400
		t_file.f_dentry = &t_dentry;
3401
		t_dentry.d_inode = inode;
3402
		file = &t_file;
3403
	}
3404
#endif
3387
3405
3388
	cdrom_release (&info->devinfo, file);
3406
	cdrom_release (&info->devinfo, file);
3389
	drive->usage--;
3407
	drive->usage--;
Lines 3418-3430 Link Here
3418
	return  0;
3436
	return  0;
3419
}
3437
}
3420
3438
3439
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3440
static int idecd_mediactl(struct block_device *bdev, int op, int arg)
3441
{
3442
	struct gendisk *disk = bdev->bd_disk;
3443
	ide_drive_t *drive = disk->private_data;
3444
	struct cdrom_info *info = drive->driver_data;
3445
	return cdrom_mediactl(&info->devinfo, bdev, op, arg);
3446
}
3447
#endif
3448
3421
static struct block_device_operations idecd_ops = {
3449
static struct block_device_operations idecd_ops = {
3422
	.owner		= THIS_MODULE,
3450
	.owner		= THIS_MODULE,
3423
	.open		= idecd_open,
3451
	.open		= idecd_open,
3424
	.release	= idecd_release,
3452
	.release	= idecd_release,
3425
	.ioctl		= idecd_ioctl,
3453
	.ioctl		= idecd_ioctl,
3426
	.media_changed	= idecd_media_changed,
3454
	.media_changed	= idecd_media_changed,
3427
	.revalidate_disk= idecd_revalidate_disk
3455
	.revalidate_disk= idecd_revalidate_disk,
3456
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
3457
	.mediactl	= idecd_mediactl,
3458
#endif
3428
};
3459
};
3429
3460
3430
/* options */
3461
/* options */
(-)linux-2.6.8.1_supermount/drivers/ide/ide-floppy.c (-4 / +40 lines)
Lines 98-103 Link Here
98
#include <linux/cdrom.h>
98
#include <linux/cdrom.h>
99
#include <linux/ide.h>
99
#include <linux/ide.h>
100
100
101
#include <linux/supermount_media.h>
102
101
#include <asm/byteorder.h>
103
#include <asm/byteorder.h>
102
#include <asm/irq.h>
104
#include <asm/irq.h>
103
#include <asm/uaccess.h>
105
#include <asm/uaccess.h>
Lines 1877-1883 Link Here
1877
	
1879
	
1878
	debug_log(KERN_INFO "Reached idefloppy_open\n");
1880
	debug_log(KERN_INFO "Reached idefloppy_open\n");
1879
1881
1880
	if (drive->usage == 1) {
1882
	if (supermount_usage_count(inode->i_bdev, drive->usage) == 1) {
1881
		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
1883
		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
1882
		/* Just in case */
1884
		/* Just in case */
1883
1885
Lines 1924-1930 Link Here
1924
	
1926
	
1925
	debug_log(KERN_INFO "Reached idefloppy_release\n");
1927
	debug_log(KERN_INFO "Reached idefloppy_release\n");
1926
1928
1927
	if (drive->usage == 1) {
1929
	if (supermount_usage_count(inode->i_bdev, drive->usage) == 1) {
1928
		idefloppy_floppy_t *floppy = drive->driver_data;
1930
		idefloppy_floppy_t *floppy = drive->driver_data;
1929
1931
1930
		/* IOMEGA Clik! drives do not support lock/unlock commands */
1932
		/* IOMEGA Clik! drives do not support lock/unlock commands */
Lines 1957-1963 Link Here
1957
		prevent = 0;
1959
		prevent = 0;
1958
		/* fall through */
1960
		/* fall through */
1959
	case CDROM_LOCKDOOR:
1961
	case CDROM_LOCKDOOR:
1960
		if (drive->usage > 1)
1962
		if (supermount_usage_count(bdev, drive->usage) > 1)
1961
			return -EBUSY;
1963
			return -EBUSY;
1962
1964
1963
		/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
1965
		/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
Lines 2025-2037 Link Here
2025
	return 0;
2027
	return 0;
2026
}
2028
}
2027
2029
2030
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2031
static int idefloppy_mediactl (struct block_device *bdev, int op, int optarg)
2032
{
2033
	ide_drive_t *drive = bdev->bd_disk->private_data;
2034
	idefloppy_floppy_t *floppy = drive->driver_data;
2035
	idefloppy_pc_t pc;
2036
2037
        switch (op) {
2038
                case MEDIA_LOCK:
2039
                case MEDIA_UNLOCK:
2040
                        if (op == MEDIA_UNLOCK && optarg) {
2041
                                drive->usage--;
2042
                                if (drive->usage < 0)
2043
                                        drive->usage = 0;
2044
                        }
2045
                        /* IOMEGA Clik! drives do not support lock/unlock commands */
2046
                        if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)
2047
                            && supermount_usage_count(bdev, drive->usage) == 0) {
2048
                                idefloppy_create_prevent_cmd(&pc, (op == MEDIA_LOCK));
2049
                                (void) idefloppy_queue_pc_tail(drive, &pc);
2050
                        }
2051
                        if (op == MEDIA_LOCK && optarg)
2052
                                drive->usage++;
2053
                        break;
2054
                default:
2055
                        return -EINVAL;
2056
        }
2057
        return 0;
2058
}
2059
#endif
2060
2028
static struct block_device_operations idefloppy_ops = {
2061
static struct block_device_operations idefloppy_ops = {
2029
	.owner		= THIS_MODULE,
2062
	.owner		= THIS_MODULE,
2030
	.open		= idefloppy_open,
2063
	.open		= idefloppy_open,
2031
	.release	= idefloppy_release,
2064
	.release	= idefloppy_release,
2032
	.ioctl		= idefloppy_ioctl,
2065
	.ioctl		= idefloppy_ioctl,
2033
	.media_changed	= idefloppy_media_changed,
2066
	.media_changed	= idefloppy_media_changed,
2034
	.revalidate_disk= idefloppy_revalidate_disk
2067
	.revalidate_disk= idefloppy_revalidate_disk,
2068
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2069
	.mediactl	= idefloppy_mediactl,
2070
#endif
2035
};
2071
};
2036
2072
2037
static int idefloppy_attach (ide_drive_t *drive)
2073
static int idefloppy_attach (ide_drive_t *drive)
(-)linux-2.6.8.1_supermount/drivers/scsi/sd.c (-2 / +62 lines)
Lines 49-54 Link Here
49
#include <linux/kref.h>
49
#include <linux/kref.h>
50
#include <asm/uaccess.h>
50
#include <asm/uaccess.h>
51
51
52
#include <linux/supermount_media.h>
53
52
#include <scsi/scsi.h>
54
#include <scsi/scsi.h>
53
#include <scsi/scsi_cmnd.h>
55
#include <scsi/scsi_cmnd.h>
54
#include <scsi/scsi_dbg.h>
56
#include <scsi/scsi_dbg.h>
Lines 469-475 Link Here
469
	if (!scsi_device_online(sdev))
471
	if (!scsi_device_online(sdev))
470
		goto error_out;
472
		goto error_out;
471
473
472
	if (!sdkp->openers++ && sdev->removable) {
474
	if (supermount_usage_count(inode->i_bdev, sdkp->openers++) == 0 && sdev->removable) {
473
		if (scsi_block_when_processing_errors(sdev))
475
		if (scsi_block_when_processing_errors(sdev))
474
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
476
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
475
	}
477
	}
Lines 500-506 Link Here
500
502
501
	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
503
	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
502
504
503
	if (!--sdkp->openers && sdev->removable) {
505
	if (supermount_usage_count(inode->i_bdev, --sdkp->openers) == 0 && sdev->removable) {
504
		if (scsi_block_when_processing_errors(sdev))
506
		if (scsi_block_when_processing_errors(sdev))
505
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
507
			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
506
	}
508
	}
Lines 660-665 Link Here
660
		 goto not_present;
662
		 goto not_present;
661
663
662
	/*
664
	/*
665
	 * FIXME HACK
666
	 * busy device that is unplugged is SDEV_DEL but online and ioctl
667
	 * does not return any error. Oh well, it is likely layering
668
	 * violation but for now it enables media checks for supermount
669
	 */
670
671
	if (sdp->sdev_state == SDEV_DEL) 
672
		goto not_present;
673
674
	/*
663
	 * For removable scsi disk we have to recognise the presence
675
	 * 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
676
	 * 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)
677
	 * struct and tested at open !  Daniel Roche (dan@lectra.fr)
Lines 682-687 Link Here
682
	sd_revalidate_disk(sdkp->disk);
694
	sd_revalidate_disk(sdkp->disk);
683
}
695
}
684
696
697
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
698
/*
699
 * This function performs media control operations.  Currently the
700
 * only functions used are MEDIA_LOCK and MEDIA_UNLOCK, to lock and
701
 * unlock the drive door.
702
 */
703
704
static int sd_mediactl(struct block_device *bdev, int op, int optarg)
705
{
706
	struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
707
	struct scsi_device *sdp = sdkp->device;
708
	int rc = 0;
709
710
	SCSI_LOG_HLQUEUE(3, printk("sd_mediactl: disk=%s\n",
711
						bdev->bd_disk->disk_name));
712
713
	if (!sdp->removable)
714
		return 0;
715
716
	if (!scsi_block_when_processing_errors(sdp))
717
		return -ENODEV;
718
719
	switch (op) {
720
	case MEDIA_LOCK:
721
		if (supermount_usage_count(bdev, sdkp->openers) == 0)
722
			rc = scsi_set_medium_removal(sdp, SCSI_REMOVAL_PREVENT);
723
		/* FIXME is it the right way? */
724
		if (optarg)
725
			sdkp->openers++;
726
		break;
727
	case MEDIA_UNLOCK:
728
		if (optarg && sdkp->openers > 0)
729
			sdkp->openers--;
730
		if (supermount_usage_count(bdev, sdkp->openers) == 0)
731
			rc = scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW);
732
		break;
733
	default:
734
		rc = -EINVAL;
735
		break;
736
	}
737
738
	return rc;
739
}
740
#endif
741
685
static struct block_device_operations sd_fops = {
742
static struct block_device_operations sd_fops = {
686
	.owner			= THIS_MODULE,
743
	.owner			= THIS_MODULE,
687
	.open			= sd_open,
744
	.open			= sd_open,
Lines 689-694 Link Here
689
	.ioctl			= sd_ioctl,
746
	.ioctl			= sd_ioctl,
690
	.media_changed		= sd_media_changed,
747
	.media_changed		= sd_media_changed,
691
	.revalidate_disk	= sd_revalidate_disk,
748
	.revalidate_disk	= sd_revalidate_disk,
749
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
750
	.mediactl		= sd_mediactl,
751
#endif
692
};
752
};
693
753
694
/**
754
/**
(-)linux-2.6.8.1_supermount/drivers/scsi/sr.c (+32 lines)
Lines 480-485 Link Here
480
{
480
{
481
	int ret;
481
	int ret;
482
	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
482
	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
483
484
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
485
	/*
486
	 * This is the same sort of clockload as use in blkdev_get.
487
	 * We need information whether device is supermounted inside
488
	 * of cdrom_release to decide if tray must be unlocked.
489
	 * This information so far is available only by looking
490
	 * up superblock but it needs struct *bdev and it is not
491
	 * available in cdrom_release anymore
492
	 */
493
	struct dentry t_dentry;
494
	struct file t_file;
495
496
	if (!file) {
497
		t_file.f_dentry = &t_dentry;
498
		t_dentry.d_inode = inode;
499
		file = &t_file;
500
	}
501
#endif
502
483
	ret = cdrom_release(&cd->cdi, file);
503
	ret = cdrom_release(&cd->cdi, file);
484
	if(ret)
504
	if(ret)
485
		return ret;
505
		return ret;
Lines 513-518 Link Here
513
	return cdrom_media_changed(&cd->cdi);
533
	return cdrom_media_changed(&cd->cdi);
514
}
534
}
515
535
536
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
537
static int sr_block_mediactl(struct block_device *bdev, int op, int arg)
538
{
539
	struct gendisk *disk = bdev->bd_disk;
540
	struct scsi_cd *cd = scsi_cd(disk);
541
	return cdrom_mediactl(&cd->cdi, bdev, op, arg);
542
}
543
#endif
544
516
struct block_device_operations sr_bdops =
545
struct block_device_operations sr_bdops =
517
{
546
{
518
	.owner		= THIS_MODULE,
547
	.owner		= THIS_MODULE,
Lines 520-525 Link Here
520
	.release	= sr_block_release,
549
	.release	= sr_block_release,
521
	.ioctl		= sr_block_ioctl,
550
	.ioctl		= sr_block_ioctl,
522
	.media_changed	= sr_block_media_changed,
551
	.media_changed	= sr_block_media_changed,
552
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
553
	.mediactl	= sr_block_mediactl,
554
#endif
523
};
555
};
524
556
525
static int sr_open(struct cdrom_device_info *cdi, int purpose)
557
static int sr_open(struct cdrom_device_info *cdi, int purpose)
(-)linux-2.6.8.1_supermount/fs/Kconfig (+2 lines)
Lines 937-942 Link Here
937
	  To compile this as a module, choose M here: the module will be called
937
	  To compile this as a module, choose M here: the module will be called
938
	  ramfs.
938
	  ramfs.
939
939
940
source "fs/supermount/Kconfig"
941
940
endmenu
942
endmenu
941
943
942
menu "Miscellaneous filesystems"
944
menu "Miscellaneous filesystems"
(-)linux-2.6.8.1_supermount/fs/Makefile (+1 lines)
Lines 91-93 Link Here
91
obj-$(CONFIG_XFS_FS)		+= xfs/
91
obj-$(CONFIG_XFS_FS)		+= xfs/
92
obj-$(CONFIG_AFS_FS)		+= afs/
92
obj-$(CONFIG_AFS_FS)		+= afs/
93
obj-$(CONFIG_BEFS_FS)		+= befs/
93
obj-$(CONFIG_BEFS_FS)		+= befs/
94
obj-$(CONFIG_SUPERMOUNT)	+= supermount/
(-)linux-2.6.8.1_supermount/fs/block_dev.c (+33 lines)
Lines 511-522 Link Here
511
{
511
{
512
	struct gendisk *disk = bdev->bd_disk;
512
	struct gendisk *disk = bdev->bd_disk;
513
	struct block_device_operations * bdops = disk->fops;
513
	struct block_device_operations * bdops = disk->fops;
514
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
515
	struct super_block *sb = NULL;
516
	int supermounted = 0;
517
#endif
514
518
515
	if (!bdops->media_changed)
519
	if (!bdops->media_changed)
516
		return 0;
520
		return 0;
517
	if (!bdops->media_changed(bdev->bd_disk))
521
	if (!bdops->media_changed(bdev->bd_disk))
518
		return 0;
522
		return 0;
519
523
524
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
525
	sb = get_super(bdev);
526
	if (sb) {
527
		atomic_set(&sb->s_media_changed, 1);
528
		supermounted = sb->s_flags & MS_SUPERMOUNTED;
529
		drop_super(sb);
530
	}
531
532
	/*
533
	 * Supermount used to did invalidate_device followed by
534
	 * destroy_buffers. invalidate_device hardly does anything
535
	 * useful here as it won't really invalidate "busy" inodes
536
	 * and every inode in subfs is busy (at least one reference
537
	 * from superfs exists). So now it just flushes
538
	 * buffers so they do not accidentally overwrite newly
539
	 * inserted media
540
	 *
541
	 * FIXME unfortunately during umount VFS may write on its
542
	 * own, like write_super. Those writes will go to a wrong
543
	 * media thus corrupting it :(
544
	 *
545
	 * There is no error print because supermount warns user
546
	 * itself.
547
	 */
548
549
	if (supermounted) {
550
		invalidate_bdev(bdev, 1);
551
	} else
552
#endif
520
	if (__invalidate_device(bdev, 0))
553
	if (__invalidate_device(bdev, 0))
521
		printk("VFS: busy inodes on changed media.\n");
554
		printk("VFS: busy inodes on changed media.\n");
522
555
(-)linux-2.6.8.1_supermount/fs/ext2/super.c (+6 lines)
Lines 303-308 Link Here
303
	{Opt_ignore, "noquota"},
303
	{Opt_ignore, "noquota"},
304
	{Opt_ignore, "quota"},
304
	{Opt_ignore, "quota"},
305
	{Opt_ignore, "usrquota"},
305
	{Opt_ignore, "usrquota"},
306
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
307
	/* Silently ignore NLS options */
308
	{Opt_ignore, "iocharset"},
309
	{Opt_ignore, "codepage"},
310
	{Opt_ignore, "umask"},
311
#endif
306
	{Opt_err, NULL}
312
	{Opt_err, NULL}
307
};
313
};
308
314
(-)linux-2.6.8.1_supermount/fs/isofs/inode.c (+4 lines)
Lines 364-369 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.8.1_supermount/fs/namespace.c (+9 lines)
Lines 1016-1021 Link Here
1016
	if (retval)
1016
	if (retval)
1017
		goto dput_out;
1017
		goto dput_out;
1018
1018
1019
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1020
	if (!(flags & (MS_REMOUNT | MS_MOVE)) &&
1021
	    (nd.mnt->mnt_sb->s_type->fs_flags & FS_NO_SUBMNT)) {
1022
		retval = -EPERM;
1023
		path_release(&nd);
1024
		return retval;
1025
	}
1026
#endif
1027
1019
	if (flags & MS_REMOUNT)
1028
	if (flags & MS_REMOUNT)
1020
		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
1029
		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
1021
				    data_page);
1030
				    data_page);
(-)linux-2.6.8.1_supermount/fs/super.c (-2 / +29 lines)
Lines 82-87 Link Here
82
		s->dq_op = sb_dquot_ops;
82
		s->dq_op = sb_dquot_ops;
83
		s->s_qcop = sb_quotactl_ops;
83
		s->s_qcop = sb_quotactl_ops;
84
		s->s_op = &default_op;
84
		s->s_op = &default_op;
85
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
86
		atomic_set(&s->s_media_changed, 0);
87
#endif
85
	}
88
	}
86
out:
89
out:
87
	return s;
90
	return s;
Lines 527-532 Link Here
527
	return 0;
530
	return 0;
528
}
531
}
529
532
533
#ifdef CONFIG_SUPERMOUNT_MODULE
534
EXPORT_SYMBOL(do_remount_sb);
535
#endif
536
530
static void do_emergency_remount(unsigned long foo)
537
static void do_emergency_remount(unsigned long foo)
531
{
538
{
532
	struct super_block *sb;
539
	struct super_block *sb;
Lines 657-667 Link Here
657
		goto out;
664
		goto out;
658
665
659
	if (s->s_root) {
666
	if (s->s_root) {
660
		if ((flags ^ s->s_flags) & MS_RDONLY) {
667
		if (((flags ^ s->s_flags) & MS_RDONLY)
668
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
669
		/* disallow double mounting for supermounted device */
670
		    || ((flags | s->s_flags) & MS_SUPERMOUNTED)
671
#endif
672
		   )
673
		{
661
			up_write(&s->s_umount);
674
			up_write(&s->s_umount);
662
			deactivate_super(s);
675
			deactivate_super(s);
663
			s = ERR_PTR(-EBUSY);
676
			s = ERR_PTR(-EBUSY);
664
		}
677
		}
678
665
		goto out;
679
		goto out;
666
	} else {
680
	} else {
667
		char b[BDEVNAME_SIZE];
681
		char b[BDEVNAME_SIZE];
Lines 765-770 Link Here
765
	if (!type)
779
	if (!type)
766
		return ERR_PTR(-ENODEV);
780
		return ERR_PTR(-ENODEV);
767
781
782
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
783
	/* sanity checks; supermount relies on these assumptions */
784
	if (flags & MS_SUPERMOUNTED) {
785
		sb = ERR_PTR(-EINVAL);
786
		if (type->fs_flags & FS_ODD_RENAME)
787
			goto out;
788
		if (!(type->fs_flags & FS_REQUIRES_DEV))
789
			goto out;
790
		sb = ERR_PTR(-ENOMEM);
791
	}
792
#endif
768
	mnt = alloc_vfsmnt(name);
793
	mnt = alloc_vfsmnt(name);
769
	if (!mnt)
794
	if (!mnt)
770
		goto out;
795
		goto out;
Lines 810-816 Link Here
810
	return (struct vfsmount *)sb;
835
	return (struct vfsmount *)sb;
811
}
836
}
812
837
813
EXPORT_SYMBOL_GPL(do_kern_mount);
838
#ifdef CONFIG_SUPERMOUNT_MODULE
839
EXPORT_SYMBOL(do_kern_mount);
840
#endif
814
841
815
struct vfsmount *kern_mount(struct file_system_type *type)
842
struct vfsmount *kern_mount(struct file_system_type *type)
816
{
843
{
(-)linux-2.6.8.1_supermount/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.8.1_supermount/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.8.1_supermount/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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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.8.1_supermount/fs/supermount/file.c (+689 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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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
		int bug = atomic_read(&subfile->f_count) != 1;
554
		fput(subfile);
555
		subfs_put_access(inode, file->f_mode & FMODE_WRITE);
556
		SUPERMOUNT_BUG_ON(bug);
557
	}
558
559
	if (sfi)
560
		kfree(sfi);
561
562
	LEAVE(sb, "inode=%p file=%p", inode, file);
563
564
	return 0;
565
566
}
567
568
static int
569
supermount_fsync(struct file *file, struct dentry *dentry, int datasync)
570
{
571
	struct super_block *sb = file->f_dentry->d_sb;
572
	struct file *subfile;
573
	int rc;
574
575
	ENTER(sb, "file=%p dentry=%s sync=%d", file, dentry->d_name.name, datasync);
576
577
	rc = -ESTALE;
578
	if (subfs_check_disk_change(sb))
579
		goto out;
580
581
	subfile = get_subfs_file(file);
582
	rc = PTR_ERR(subfile);
583
	if (IS_ERR(subfile))
584
		goto out;
585
586
	rc = -EINVAL;
587
	if (subfile->f_op && subfile->f_op->fsync)
588
		rc = subfile->f_op->fsync(subfile, subfile->f_dentry, datasync);
589
590
	fput(subfile);
591
out:
592
	ENTER(sb, "file=%p dentry=%s rc=%d", file, dentry->d_name.name, rc);
593
594
	return rc;
595
}
596
597
static int
598
supermount_fasync(int fd, struct file *file, int on)
599
{
600
	struct super_block *sb = file->f_dentry->d_sb;
601
	struct file *subfile;
602
	int rc;
603
604
	ENTER(sb, "fd=%d file=%p on=%d", fd, file, on);
605
606
	rc = -ESTALE;
607
	if (subfs_check_disk_change(sb))
608
		goto out;
609
610
	subfile = get_subfs_file(file);
611
	rc = PTR_ERR(subfile);
612
	if (IS_ERR(subfile))
613
		goto out;
614
615
	rc = -EINVAL;
616
	if (subfile->f_op && subfile->f_op->fasync)
617
		rc = subfile->f_op->fasync(fd, subfile, on);
618
619
	fput(subfile);
620
out:
621
	LEAVE(sb, "fd=%d file=%p rc=%d", fd, file, rc);
622
623
	return rc;
624
}
625
626
static int
627
supermount_lock(struct file *file, int cmd, struct file_lock *fl)
628
{
629
	struct super_block *sb = file->f_dentry->d_sb;
630
	struct file *subfile;
631
	int rc;
632
633
	ENTER(sb, "file=%p cmd=%d", file, cmd);
634
635
	rc = -ESTALE;
636
	if (subfs_check_disk_change(sb))
637
		goto out;
638
639
	subfile = get_subfs_file(file);
640
	rc = PTR_ERR(subfile);
641
	if (IS_ERR(subfile))
642
		goto out;
643
644
	rc = 0;
645
	if (subfile->f_op && subfile->f_op->lock)
646
		rc = subfile->f_op->lock(subfile, cmd, fl);
647
	else if (cmd == F_GETLK)
648
		posix_test_lock(file, fl);
649
650
	fput(subfile);
651
out:
652
	LEAVE(sb, "file=%p rc=%d", file, rc);
653
654
	return rc;
655
}
656
657
/* Fixme:
658
 * readv: easy, export churnk from vfs
659
 * writev: easy, export churnk from vfs
660
 * sendpage: only used for networking, not needed
661
 * get_unmmapped_area: only used for devices, not needed
662
 */
663
664
struct file_operations supermount_dir_operations = {
665
	.llseek		= supermount_llseek,
666
	.read		= supermount_read,
667
	.readdir	= supermount_readdir,
668
	.ioctl		= supermount_ioctl,
669
	.open		= supermount_open,
670
	.flush		= supermount_flush,
671
	.release	= supermount_release,
672
	.fsync		= supermount_fsync,
673
	.fasync		= supermount_fasync,
674
};
675
676
struct file_operations supermount_file_operations = {
677
	.llseek		= supermount_llseek,
678
	.read		= supermount_read,
679
	.write		= supermount_write,
680
	.poll		= supermount_poll,
681
	.ioctl		= supermount_ioctl,
682
	.mmap		= supermount_file_mmap, /* from filemap.c */
683
	.open		= supermount_open,
684
	.flush		= supermount_flush,
685
	.release	= supermount_release,
686
	.fsync		= supermount_fsync,
687
	.fasync		= supermount_fasync,
688
	.lock		= supermount_lock,
689
};
(-)linux-2.6.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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 = vfs_permission(subi, mask);
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 = vfs_permission(inode, mask);
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
	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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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 inline 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 inline 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.8.1_supermount/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: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh 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 void
400
supermount_write_inode(struct inode *inode, int sync)
401
{
402
	struct super_block *sb = inode->i_sb;
403
	struct super_block *subsb;
404
	struct inode *subi;
405
	struct vfsmount *submnt;
406
407
	ENTER(sb);
408
409
	if (subfs_check_disk_change(sb))
410
		goto out;
411
412
	submnt = subfs_prevent_umount(sb);
413
	if (!submnt)
414
		goto out;
415
416
	subi = get_subfs_inode(inode);
417
	if (IS_ERR(subi))
418
		goto allow_umount;
419
420
	subsb = subfs_get_sb(sb);
421
	if (!sb)
422
		goto put_subi;
423
424
	if (subsb->s_op && subsb->s_op->write_inode) {
425
		if (subfs_get_access(inode, 1))
426
			goto put_subi;
427
428
		write_inode_now(subi, sync);
429
430
		subfs_put_access(inode, 1);
431
	}
432
put_subi:
433
	iput(subi);
434
allow_umount:
435
	subfs_allow_umount(sb, submnt);
436
out:
437
	LEAVE(sb);
438
439
	return;
440
}
441
442
/*
443
 * FIXME
444
 * subfs_umount has no business here
445
 * it should be moved into umount_begin; in this case force umount will
446
 * free subfs (and give false No medium as error ... oh, well)
447
 */
448
static void
449
supermount_put_super(struct super_block *sb)
450
{
451
	struct supermount_sb_info *sbi = supermount_sbi(sb);
452
453
	ENTER(sb);
454
455
	subfs_lock(sb);
456
	if (subfs_is_mounted(sb))
457
		subfs_umount(sb, SUBFS_UMNT_NORMAL);
458
	subfs_unlock(sb);
459
460
	supermount_proc_remove(sbi);
461
462
	LEAVE(sb);
463
464
	sb->s_fs_info = 0;
465
	free_sbi(sbi);
466
}
467
468
/*
469
 * The following has to be done in two steps (unfortunately)
470
 * First make sure iput(subi) is run just once - and then put
471
 * read/write access and finally remove inode from list
472
 *
473
 * We can't do it in one shot because removing inode from list
474
 * will remove also possibility to mark it stale. It has been 
475
 * introduced by me :( removing generation numbers. OTOH so far
476
 * it is the only place that needs extra treatment because of it.
477
 */
478
static void
479
supermount_clear_inode(struct inode *inode)
480
{
481
	struct supermount_inode_info *sii = supermount_i(inode);
482
	struct super_block *sb = inode->i_sb;
483
	struct inode *subi;
484
	struct vfsmount *mnt;
485
486
	ENTER(sb, "inode=%p", inode);
487
488
	mnt = subfs_prevent_umount(sb);
489
	if (!mnt)
490
		goto out;
491
492
	subfs_lock(sb);
493
	subi = sii->inode;
494
	sii->inode = 0;
495
	subfs_unlock(sb);
496
497
498
	if (subi) {
499
		/*
500
		 * we used to check for subi->i_count != 1 here.
501
		 * This does not actually work - it is quite possible
502
		 * that inode has been looked up while we were in this
503
		 * function. So just ignore it (the worst thing that
504
		 * may happen is that subfs cannot be remounted)
505
		 */
506
507
		iput(subi);
508
509
	}
510
	subfs_allow_umount(sb, mnt);
511
512
	/*
513
	 * This does not has much to do with subfs but I did not want
514
	 * to export __ functions
515
	 */
516
	subfs_clear_inode(inode);
517
out:
518
	LEAVE(sb, "inode=%p", inode);
519
}
520
/*
521
 * FIXME why it is needed?
522
 */
523
524
static void
525
supermount_write_super(struct super_block *sb)
526
{
527
	struct vfsmount *mnt;
528
529
	ENTER(sb);
530
531
	if (subfs_check_disk_change(sb))
532
		goto out;
533
534
	if (subfs_is_rw(sb)) {
535
		struct super_block *subsb;
536
537
		mnt = subfs_prevent_umount(sb);
538
		if (!mnt)
539
			goto out;
540
541
		subsb = subfs_get_sb(sb);
542
		if (subsb && subsb->s_op && subsb->s_op->write_super)
543
			subsb->s_op->write_super(subsb);
544
545
		subfs_allow_umount(sb, mnt);
546
	}
547
548
out:
549
	LEAVE(sb);
550
551
	return;
552
}
553
554
static int
555
supermount_statfs(struct super_block *sb, struct kstatfs *buf)
556
{
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.8.1_supermount/fs/supermount/supermount.h (+497 lines)
Line 0 Link Here
1
#ifndef _SUPERMOUNT_I_H
2
#define _SUPERMOUNT_I_H
3
4
/*
5
 *  $Id: 4715_supermount-2.0.4-2.6.7.patch,v 1.1 2004/06/22 22:15:04 gregkh Exp $
6
 */
7
8
#include <linux/module.h>
9
#include <linux/version.h>
10
11
#include <linux/slab.h>
12
#include <linux/sched.h>
13
#include <linux/errno.h>
14
#include <linux/fs.h>
15
#include <linux/list.h>
16
#include <linux/file.h>
17
#include <linux/mm.h>
18
#include <linux/poll.h>
19
#include <linux/smp_lock.h>
20
#include <linux/proc_fs.h>
21
#include <linux/seq_file.h>
22
#include <linux/dnotify.h>
23
#include <linux/mount.h>
24
#include <linux/moduleparam.h>
25
#include <linux/genhd.h>
26
#include <linux/namei.h>
27
#include <linux/supermount_media.h>
28
29
#ifdef CONFIG_SUPERMOUNT_DEBUG
30
#define SUPERMOUNT_DEBUG
31
#endif
32
/*
33
 * The supermount superblock magic number
34
 */
35
36
#define SUPERMOUNT_SUPER_MAGIC	0x9fa1
37
#define SUPERMOUNT_VERSION		"2.0.4"
38
39
#define S_DBG_DEBUG			0x001
40
#define S_DBG_TRACE_DENTRY		0x002
41
#define S_DBG_TRACE_FILE		0x004
42
#define S_DBG_TRACE_FILEMAP		0x008
43
#define S_DBG_TRACE_MEDIACTL		0x010
44
#define S_DBG_TRACE_NAMEI		0x020
45
#define S_DBG_TRACE_SUBFS		0x040
46
#define S_DBG_TRACE_SUPER		0x080
47
48
/*
49
 * The subfs umount reason
50
 */
51
#define SUBFS_UMNT_NORMAL		0 /* normal umount */
52
#define SUBFS_UMNT_MEDIA		1 /* media change detected */
53
#define SUBFS_UMNT_USER			2 /* user request */
54
55
/*
56
 * When to lock media
57
 */
58
#define TRAY_LOCK_NEVER			0
59
#define TRAY_LOCK_ONWRITE		1
60
#define TRAY_LOCK_ALWAYS		2
61
62
extern struct file_system_type supermount_fs_type;
63
64
#ifdef SUPERMOUNT_DEBUG
65
66
#define SUPERMOUNT_BUG_ON(x) BUG_ON(x)
67
#define SUPERMOUNT_BUG_LOCKED_ON(sb, x) \
68
do { \
69
	if (x) { \
70
		subfs_unlock(sb); \
71
		BUG(); \
72
	} \
73
} while (0)
74
75
#define supermount_debug(sb, args...) \
76
do { \
77
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
78
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
79
\
80
	if (supermount_dbg(sb, S_DBG_DEBUG)) { \
81
		printk("%sSUPERMOUNT DEBUG [dev=%s] <%s:%d> ", \
82
			KERN_DEBUG, dev, __FUNCTION__, __LINE__); \
83
		printk(args); \
84
		printk("\n"); \
85
	} \
86
} while(0)
87
88
#define ENTER(sb, args...) \
89
do { \
90
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
91
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
92
\
93
	if (supermount_dbg(sb, S_DBG_TRACE_CURRENT)) { \
94
		printk("%sSUPERMOUNT TRACE [dev=%s] PID=%lu ENTER %s", \
95
			KERN_DEBUG, dev, (unsigned long)current->pid, \
96
			__FUNCTION__); \
97
		printk(" " args); \
98
		printk("\n"); \
99
	} \
100
} while (0)
101
102
#define LEAVE(sb, args...) \
103
do { \
104
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
105
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
106
\
107
	if (supermount_dbg(sb, S_DBG_TRACE_CURRENT)) { \
108
		printk("%sSUPERMOUNT TRACE [dev=%s] PID=%lu LEAVE %s", \
109
			KERN_DEBUG, dev, (unsigned long)current->pid, \
110
			__FUNCTION__); \
111
		printk(" " args); \
112
		printk("\n"); \
113
	} \
114
} while (0)
115
116
#else /* SUPERMOUNT_DEBUG */
117
#define supermount_debug(f, a...) /**/
118
#define SUPERMOUNT_BUG_ON(x) do { } while (0)
119
#define SUPERMOUNT_BUG_LOCKED_ON(sb, x) do { } while (0)
120
121
#define ENTER(sb, args...) do { (void)sb; } while (0)
122
#define LEAVE(sb, args...) do { (void)sb; } while (0)
123
#endif				/* SUPERMOUNT_DEBUG */
124
125
#define supermount_warning(sb, ...) \
126
do { \
127
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
128
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
129
\
130
	printk("%sSUPERMOUNT WARNING [dev=%s] ", KERN_WARNING, dev); \
131
	printk(__VA_ARGS__); \
132
	printk("\n"); \
133
} while(0)
134
135
#define supermount_error(sb, ...) \
136
do { \
137
	struct supermount_sb_info *sbi = supermount_sbi(sb); \
138
	char *dev = sbi->devname ? sbi->devname : "unknown"; \
139
\
140
	printk("%sSUPERMOUNT ERROR [dev=%s] ", KERN_ERR, dev); \
141
	printk(__VA_ARGS__); \
142
	printk("\n"); \
143
} while(0)
144
145
/*
146
 * The following is drived from fs/inode.c:update_atime()
147
 */
148
#define NEED_WRITE_ATIME(inode) \
149
	(!(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.8.1_supermount/fs/udf/super.c (-1 / +7 lines)
Lines 278-284 Link Here
278
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
278
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
279
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
279
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
280
	Opt_rootdir, Opt_utf8, Opt_iocharset,
280
	Opt_rootdir, Opt_utf8, Opt_iocharset,
281
	Opt_err
281
	Opt_ignore, Opt_err
282
};
282
};
283
283
284
static match_table_t tokens = {
284
static match_table_t tokens = {
Lines 303-308 Link Here
303
	{Opt_rootdir, "rootdir=%u"},
303
	{Opt_rootdir, "rootdir=%u"},
304
	{Opt_utf8, "utf8"},
304
	{Opt_utf8, "utf8"},
305
	{Opt_iocharset, "iocharset=%s"},
305
	{Opt_iocharset, "iocharset=%s"},
306
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
307
	/* Silently ignore NLS option */
308
	{Opt_ignore, "codepage"},
309
#endif
306
	{Opt_err, NULL}
310
	{Opt_err, NULL}
307
};
311
};
308
312
Lines 423-428 Link Here
423
				uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
427
				uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
424
				break;
428
				break;
425
#endif
429
#endif
430
			case Opt_ignore:
431
				break;
426
			default:
432
			default:
427
				printk(KERN_ERR "udf: bad mount option \"%s\" "
433
				printk(KERN_ERR "udf: bad mount option \"%s\" "
428
						"or missing value\n", p);
434
						"or missing value\n", p);
(-)linux-2.6.8.1_supermount/include/linux/cdrom.h (+3 lines)
Lines 987-992 Link Here
987
extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi,
987
extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi,
988
		struct inode *ip, unsigned int cmd, unsigned long arg);
988
		struct inode *ip, unsigned int cmd, unsigned long arg);
989
extern int cdrom_media_changed(struct cdrom_device_info *);
989
extern int cdrom_media_changed(struct cdrom_device_info *);
990
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
991
extern int cdrom_mediactl(struct cdrom_device_info *, struct block_device *, int, int);
992
#endif
990
993
991
extern int register_cdrom(struct cdrom_device_info *cdi);
994
extern int register_cdrom(struct cdrom_device_info *cdi);
992
extern int unregister_cdrom(struct cdrom_device_info *cdi);
995
extern int unregister_cdrom(struct cdrom_device_info *cdi);
(-)linux-2.6.8.1_supermount/include/linux/fs.h (+14 lines)
Lines 96-101 Link Here
96
/* public flags for file_system_type */
96
/* public flags for file_system_type */
97
#define FS_REQUIRES_DEV 1 
97
#define FS_REQUIRES_DEV 1 
98
#define FS_BINARY_MOUNTDATA 2
98
#define FS_BINARY_MOUNTDATA 2
99
#define FS_NO_SUBMNT	64	/* Prevent mounting over this filesystem */
99
#define FS_REVAL_DOT	16384	/* Check the paths ".", ".." for staleness */
100
#define FS_REVAL_DOT	16384	/* Check the paths ".", ".." for staleness */
100
#define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
101
#define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
101
				  * as nfs_rename() will be cleaned up
102
				  * as nfs_rename() will be cleaned up
Lines 119-124 Link Here
119
#define MS_VERBOSE	32768
120
#define MS_VERBOSE	32768
120
#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
121
#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
121
#define MS_ONE_SECOND	(1<<17)	/* fs has 1 sec a/m/ctime resolution */
122
#define MS_ONE_SECOND	(1<<17)	/* fs has 1 sec a/m/ctime resolution */
123
#define MS_SUPERMOUNTED	(1<<18)
122
#define MS_ACTIVE	(1<<30)
124
#define MS_ACTIVE	(1<<30)
123
#define MS_NOUSER	(1<<31)
125
#define MS_NOUSER	(1<<31)
124
126
Lines 587-592 Link Here
587
	spinlock_t		f_ep_lock;
589
	spinlock_t		f_ep_lock;
588
#endif /* #ifdef CONFIG_EPOLL */
590
#endif /* #ifdef CONFIG_EPOLL */
589
	struct address_space	*f_mapping;
591
	struct address_space	*f_mapping;
592
593
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
594
	/* Used by supermount. Use(fullness) unconfirmed */
595
	void                    *f_supermount;
596
#endif
590
};
597
};
591
extern spinlock_t files_lock;
598
extern spinlock_t files_lock;
592
#define file_list_lock() spin_lock(&files_lock);
599
#define file_list_lock() spin_lock(&files_lock);
Lines 771-776 Link Here
771
	 * even looking at it. You had been warned.
778
	 * even looking at it. You had been warned.
772
	 */
779
	 */
773
	struct semaphore s_vfs_rename_sem;	/* Kludge */
780
	struct semaphore s_vfs_rename_sem;	/* Kludge */
781
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
782
       atomic_t s_media_changed;
783
#endif
784
774
};
785
};
775
786
776
/*
787
/*
Lines 840-845 Link Here
840
	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
851
	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
841
	int (*media_changed) (struct gendisk *);
852
	int (*media_changed) (struct gendisk *);
842
	int (*revalidate_disk) (struct gendisk *);
853
	int (*revalidate_disk) (struct gendisk *);
854
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
855
	int (*mediactl) (struct block_device *, int, int);
856
#endif
843
	struct module *owner;
857
	struct module *owner;
844
};
858
};
845
859
(-)linux-2.6.8.1_supermount/include/linux/genhd.h (+3 lines)
Lines 108-113 Link Here
108
#else
108
#else
109
	struct disk_stats dkstats;
109
	struct disk_stats dkstats;
110
#endif
110
#endif
111
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
112
	int scount;			/* number of supermounted partitions */
113
#endif
111
};
114
};
112
115
113
/* 
116
/* 
(-)linux-2.6.8.1_supermount/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 60462