2 ; http://vserver.13thfloor.at/Experimental/BME/delta-2.6.11.5-vs1.9.5.3-bme0.06.1.diff
4 ; Bind Mount Extensions
6 ; this patch adds some functionality to the --bind
9 ; (C) 2003-2004 Herbert Pƶtzl <herbert@13thfloor.at>
13 ; 0.01 - readonly bind mounts
14 ; 0.02 - added ro truncate handling
15 ; - added ro (f)chown, (f)chmod handling
16 ; 0.03 - added ro utime(s) handling
17 ; - added ro access and *_ioctl
18 ; 0.04 - added noatime and nodiratime
19 ; - made autofs4 update_atime uncond
20 ; 0.05 - rewrite regarding (a)time
21 ; - adapted to new 2.6 vfs
22 ; 0.05.1 check for *->mnt added
24 ; this patch is free software; you can redistribute it and/or
25 ; modify it under the terms of the GNU General Public License
26 ; as published by the Free Software Foundation; either version 2
27 ; of the License, or (at your option) any later version.
29 ; this patch is distributed in the hope that it will be useful,
30 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
31 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 ; GNU General Public License for more details.
34 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/arch/sparc64/solaris/fs.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/arch/sparc64/solaris/fs.c
35 --- linux-2.6.11.5-vs1.9.5.3/arch/sparc64/solaris/fs.c 2004-12-25 01:54:50 +0100
36 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/arch/sparc64/solaris/fs.c 2005-03-26 00:25:23 +0100
37 @@ -362,7 +362,7 @@ static int report_statvfs(struct vfsmoun
41 - if (IS_RDONLY(inode)) i = 1;
42 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
43 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
44 if (!sysv_valid_dev(inode->i_sb->s_dev))
46 @@ -398,7 +398,7 @@ static int report_statvfs64(struct vfsmo
50 - if (IS_RDONLY(inode)) i = 1;
51 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
52 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
53 if (!sysv_valid_dev(inode->i_sb->s_dev))
55 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/ext2/ioctl.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/ext2/ioctl.c
56 --- linux-2.6.11.5-vs1.9.5.3/fs/ext2/ioctl.c 2005-03-23 21:34:31 +0100
57 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/ext2/ioctl.c 2005-03-26 00:25:23 +0100
58 @@ -29,7 +29,8 @@ int ext2_ioctl (struct inode * inode, st
59 case EXT2_IOC_SETFLAGS: {
60 unsigned int oldflags;
62 - if (IS_RDONLY(inode))
63 + if (IS_RDONLY(inode) ||
64 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
67 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
68 @@ -70,7 +71,8 @@ int ext2_ioctl (struct inode * inode, st
69 case EXT2_IOC_SETVERSION:
70 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
72 - if (IS_RDONLY(inode))
73 + if (IS_RDONLY(inode) ||
74 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
76 if (get_user(inode->i_generation, (int __user *) arg))
78 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/ext3/ioctl.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/ext3/ioctl.c
79 --- linux-2.6.11.5-vs1.9.5.3/fs/ext3/ioctl.c 2005-03-23 21:34:33 +0100
80 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/ext3/ioctl.c 2005-03-26 00:25:23 +0100
81 @@ -36,7 +36,8 @@ int ext3_ioctl (struct inode * inode, st
82 unsigned int oldflags;
85 - if (IS_RDONLY(inode))
86 + if (IS_RDONLY(inode) ||
87 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
90 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
91 @@ -114,7 +115,8 @@ flags_err:
93 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
95 - if (IS_RDONLY(inode))
96 + if (IS_RDONLY(inode) ||
97 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
99 if (get_user(generation, (int __user *) arg))
101 @@ -165,7 +167,8 @@ flags_err:
102 if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
105 - if (IS_RDONLY(inode))
106 + if (IS_RDONLY(inode) ||
107 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
110 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
111 @@ -186,7 +189,8 @@ flags_err:
112 if (!capable(CAP_SYS_RESOURCE))
115 - if (IS_RDONLY(inode))
116 + if (IS_RDONLY(inode) ||
117 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
120 if (get_user(n_blocks_count, (__u32 __user *)arg))
121 @@ -207,7 +211,8 @@ flags_err:
122 if (!capable(CAP_SYS_RESOURCE))
125 - if (IS_RDONLY(inode))
126 + if (IS_RDONLY(inode) ||
127 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
130 if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
131 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/hfsplus/ioctl.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/hfsplus/ioctl.c
132 --- linux-2.6.11.5-vs1.9.5.3/fs/hfsplus/ioctl.c 2005-03-02 12:38:44 +0100
133 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/hfsplus/ioctl.c 2005-03-26 00:25:23 +0100
134 @@ -34,7 +34,8 @@ int hfsplus_ioctl(struct inode *inode, s
135 flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
136 return put_user(flags, (int __user *)arg);
137 case HFSPLUS_IOC_EXT2_SETFLAGS: {
138 - if (IS_RDONLY(inode))
139 + if (IS_RDONLY(inode) ||
140 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
143 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
144 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/namei.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/namei.c
145 --- linux-2.6.11.5-vs1.9.5.3/fs/namei.c 2005-03-25 23:52:18 +0100
146 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/namei.c 2005-03-26 00:25:23 +0100
147 @@ -242,7 +242,7 @@ int permission(struct inode *inode, int
149 * Nobody gets write access to a read-only fs.
151 - if (IS_RDONLY(inode) &&
152 + if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
153 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
156 @@ -1162,7 +1162,8 @@ static inline int check_sticky(struct in
157 * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
158 * nfs_async_unlink().
160 -static inline int may_delete(struct inode *dir,struct dentry *victim,int isdir)
161 +static inline int may_delete(struct inode *dir, struct dentry *victim,
162 + int isdir, struct nameidata *nd)
166 @@ -1171,7 +1172,7 @@ static inline int may_delete(struct inod
168 BUG_ON(victim->d_parent->d_inode != dir);
170 - error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
171 + error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
175 @@ -1332,7 +1333,8 @@ int may_open(struct nameidata *nd, int a
179 - } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
180 + } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
181 + && (flag & FMODE_WRITE))
184 * An append-only file must be opened in append mode for writing.
185 @@ -1580,9 +1582,10 @@ fail:
187 EXPORT_SYMBOL_GPL(lookup_create);
189 -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
190 +int vfs_mknod(struct inode *dir, struct dentry *dentry,
191 + int mode, dev_t dev, struct nameidata *nd)
193 - int error = may_create(dir, dentry, NULL);
194 + int error = may_create(dir, dentry, nd);
198 @@ -1624,7 +1627,6 @@ asmlinkage long sys_mknod(const char __u
200 dentry = lookup_create(&nd, 0);
201 error = PTR_ERR(dentry);
203 if (!IS_POSIXACL(nd.dentry->d_inode))
204 mode &= ~current->fs->umask;
205 if (!IS_ERR(dentry)) {
206 @@ -1633,11 +1635,12 @@ asmlinkage long sys_mknod(const char __u
207 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
209 case S_IFCHR: case S_IFBLK:
210 - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
211 - new_decode_dev(dev));
212 + error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
213 + new_decode_dev(dev), &nd);
215 case S_IFIFO: case S_IFSOCK:
216 - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
217 + error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
222 @@ -1655,9 +1658,10 @@ out:
226 -int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
227 +int vfs_mkdir(struct inode *dir, struct dentry *dentry,
228 + int mode, struct nameidata *nd)
230 - int error = may_create(dir, dentry, NULL);
231 + int error = may_create(dir, dentry, nd);
235 @@ -1698,7 +1702,8 @@ asmlinkage long sys_mkdir(const char __u
236 if (!IS_ERR(dentry)) {
237 if (!IS_POSIXACL(nd.dentry->d_inode))
238 mode &= ~current->fs->umask;
239 - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
240 + error = vfs_mkdir(nd.dentry->d_inode, dentry,
244 up(&nd.dentry->d_inode->i_sem);
245 @@ -1742,9 +1747,10 @@ void dentry_unhash(struct dentry *dentry
246 spin_unlock(&dcache_lock);
249 -int vfs_rmdir(struct inode *dir, struct dentry *dentry)
250 +int vfs_rmdir(struct inode *dir, struct dentry *dentry,
251 + struct nameidata *nd)
253 - int error = may_delete(dir, dentry, 1);
254 + int error = may_delete(dir, dentry, 1, nd);
258 @@ -1806,7 +1812,7 @@ asmlinkage long sys_rmdir(const char __u
259 dentry = lookup_hash(&nd.last, nd.dentry);
260 error = PTR_ERR(dentry);
261 if (!IS_ERR(dentry)) {
262 - error = vfs_rmdir(nd.dentry->d_inode, dentry);
263 + error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
266 up(&nd.dentry->d_inode->i_sem);
267 @@ -1817,9 +1823,10 @@ exit:
271 -int vfs_unlink(struct inode *dir, struct dentry *dentry)
272 +int vfs_unlink(struct inode *dir, struct dentry *dentry,
273 + struct nameidata *nd)
275 - int error = may_delete(dir, dentry, 0);
276 + int error = may_delete(dir, dentry, 0, nd);
280 @@ -1881,7 +1888,7 @@ asmlinkage long sys_unlink(const char __
281 inode = dentry->d_inode;
283 atomic_inc(&inode->i_count);
284 - error = vfs_unlink(nd.dentry->d_inode, dentry);
285 + error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
289 @@ -1900,9 +1907,10 @@ slashes:
293 -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
294 +int vfs_symlink(struct inode *dir, struct dentry *dentry,
295 + const char *oldname, int mode, struct nameidata *nd)
297 - int error = may_create(dir, dentry, NULL);
298 + int error = may_create(dir, dentry, nd);
302 @@ -1944,7 +1952,8 @@ asmlinkage long sys_symlink(const char _
303 dentry = lookup_create(&nd, 0);
304 error = PTR_ERR(dentry);
305 if (!IS_ERR(dentry)) {
306 - error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
307 + error = vfs_symlink(nd.dentry->d_inode, dentry,
308 + from, S_IALLUGO, &nd);
311 up(&nd.dentry->d_inode->i_sem);
312 @@ -1956,7 +1965,8 @@ out:
316 -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
317 +int vfs_link(struct dentry *old_dentry, struct inode *dir,
318 + struct dentry *new_dentry, struct nameidata *nd)
320 struct inode *inode = old_dentry->d_inode;
322 @@ -1964,7 +1974,7 @@ int vfs_link(struct dentry *old_dentry,
326 - error = may_create(dir, new_dentry, NULL);
327 + error = may_create(dir, new_dentry, nd);
331 @@ -2028,7 +2038,8 @@ asmlinkage long sys_link(const char __us
332 new_dentry = lookup_create(&nd, 0);
333 error = PTR_ERR(new_dentry);
334 if (!IS_ERR(new_dentry)) {
335 - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
336 + error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
340 up(&nd.dentry->d_inode->i_sem);
341 @@ -2158,14 +2169,14 @@ int vfs_rename(struct inode *old_dir, st
342 if (old_dentry->d_inode == new_dentry->d_inode)
345 - error = may_delete(old_dir, old_dentry, is_dir);
346 + error = may_delete(old_dir, old_dentry, is_dir, NULL);
350 if (!new_dentry->d_inode)
351 error = may_create(new_dir, new_dentry, NULL);
353 - error = may_delete(new_dir, new_dentry, is_dir);
354 + error = may_delete(new_dir, new_dentry, is_dir, NULL);
358 @@ -2241,6 +2252,9 @@ static inline int do_rename(const char *
360 if (old_dentry == trap)
363 + if (MNT_IS_RDONLY(newnd.mnt))
365 new_dentry = lookup_hash(&newnd.last, new_dir);
366 error = PTR_ERR(new_dentry);
367 if (IS_ERR(new_dentry))
368 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/namespace.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/namespace.c
369 --- linux-2.6.11.5-vs1.9.5.3/fs/namespace.c 2005-03-23 21:34:32 +0100
370 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/namespace.c 2005-03-26 00:20:19 +0100
371 @@ -252,24 +252,26 @@ static int show_vfsmnt(struct seq_file *
372 struct vfsmount *mnt = v;
374 static struct proc_fs_info {
382 - { MS_SYNCHRONOUS, ",sync" },
383 - { MS_DIRSYNC, ",dirsync" },
384 - { MS_MANDLOCK, ",mand" },
385 - { MS_NOATIME, ",noatime" },
386 - { MS_NODIRATIME, ",nodiratime" },
387 - { MS_TAGXID, ",tagxid" },
390 - static struct proc_fs_info mnt_info[] = {
391 - { MNT_NOSUID, ",nosuid" },
392 - { MNT_NODEV, ",nodev" },
393 - { MNT_NOEXEC, ",noexec" },
395 + { MS_RDONLY, MNT_RDONLY, "ro", "rw" },
396 + { MS_SYNCHRONOUS, 0, ",sync", NULL },
397 + { MS_DIRSYNC, 0, ",dirsync", NULL },
398 + { MS_MANDLOCK, 0, ",mand", NULL },
399 + { MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
400 + { MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
401 + { 0, MNT_NOSUID, ",nosuid", NULL },
402 + { 0, MNT_NODEV, ",nodev", NULL },
403 + { 0, MNT_NOEXEC, ",noexec", NULL },
404 + { MS_TAGXID, 0, ",tagxid", NULL },
405 + { 0, 0, NULL, NULL }
407 - struct proc_fs_info *fs_infop;
408 + struct proc_fs_info *p;
409 + unsigned long s_flags = mnt->mnt_sb->s_flags;
410 + int mnt_flags = mnt->mnt_flags;
412 if (vx_flags(VXF_HIDE_MOUNT, 0))
414 @@ -285,14 +287,15 @@ static int show_vfsmnt(struct seq_file *
417 mangle(m, mnt->mnt_sb->s_type->name);
418 - seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
419 - for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
420 - if (mnt->mnt_sb->s_flags & fs_infop->flag)
421 - seq_puts(m, fs_infop->str);
423 - for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
424 - if (mnt->mnt_flags & fs_infop->flag)
425 - seq_puts(m, fs_infop->str);
427 + for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
428 + if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
430 + seq_puts(m, p->set_str);
433 + seq_puts(m, p->unset_str);
436 if (mnt->mnt_flags & MNT_XID)
437 seq_printf(m, ",xid=%d", mnt->mnt_xid);
438 @@ -684,7 +687,8 @@ out_unlock:
442 -static int do_loopback(struct nameidata *nd, char *old_name, xid_t xid, int flags)
443 +static int do_loopback(struct nameidata *nd, char *old_name,
444 + xid_t xid, int flags, int mnt_flags)
446 struct nameidata old_nd;
447 struct vfsmount *mnt = NULL;
448 @@ -725,6 +729,7 @@ static int do_loopback(struct nameidata
449 spin_unlock(&vfsmount_lock);
452 + mnt->mnt_flags = mnt_flags;
455 up_write(¤t->namespace->sem);
456 @@ -1112,12 +1117,18 @@ long do_mount(char * dev_name, char * di
459 /* Separate the per-mountpoint flags */
460 + if (flags & MS_RDONLY)
461 + mnt_flags |= MNT_RDONLY;
462 if (flags & MS_NOSUID)
463 mnt_flags |= MNT_NOSUID;
464 if (flags & MS_NODEV)
465 mnt_flags |= MNT_NODEV;
466 if (flags & MS_NOEXEC)
467 mnt_flags |= MNT_NOEXEC;
468 + if (flags & MS_NOATIME)
469 + mnt_flags |= MNT_NOATIME;
470 + if (flags & MS_NODIRATIME)
471 + mnt_flags |= MNT_NODIRATIME;
472 flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_ACTIVE);
474 if (vx_ccaps(VXC_SECURE_MOUNT))
475 @@ -1136,7 +1147,7 @@ long do_mount(char * dev_name, char * di
476 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
478 else if (flags & MS_BIND)
479 - retval = do_loopback(&nd, dev_name, xid, flags);
480 + retval = do_loopback(&nd, dev_name, xid, flags, mnt_flags);
481 else if (flags & MS_MOVE)
482 retval = do_move_mount(&nd, dev_name);
484 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/nfs/dir.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/nfs/dir.c
485 --- linux-2.6.11.5-vs1.9.5.3/fs/nfs/dir.c 2005-03-23 21:34:32 +0100
486 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/nfs/dir.c 2005-03-26 00:25:23 +0100
487 @@ -773,7 +773,8 @@ static int is_atomic_open(struct inode *
488 if (nd->flags & LOOKUP_DIRECTORY)
490 /* Are we trying to write to a read only partition? */
491 - if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
492 + if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
493 + (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
497 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/nfsd/vfs.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/nfsd/vfs.c
498 --- linux-2.6.11.5-vs1.9.5.3/fs/nfsd/vfs.c 2005-03-02 12:38:45 +0100
499 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/nfsd/vfs.c 2005-03-26 00:25:23 +0100
500 @@ -1115,13 +1115,13 @@ nfsd_create(struct svc_rqst *rqstp, stru
501 err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
504 - err = vfs_mkdir(dirp, dchild, iap->ia_mode);
505 + err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
511 - err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
512 + err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
515 printk("nfsd: bad file type %o in nfsd_create\n", type);
516 @@ -1397,11 +1397,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str
518 strncpy(path_alloced, path, plen);
519 path_alloced[plen] = 0;
520 - err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
521 + err = vfs_symlink(dentry->d_inode, dnew,
522 + path_alloced, mode, NULL);
526 - err = vfs_symlink(dentry->d_inode, dnew, path, mode);
527 + err = vfs_symlink(dentry->d_inode, dnew,
531 if (EX_ISSYNC(fhp->fh_export))
532 @@ -1459,7 +1461,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
533 dold = tfhp->fh_dentry;
534 dest = dold->d_inode;
536 - err = vfs_link(dold, dirp, dnew);
537 + err = vfs_link(dold, dirp, dnew, NULL);
539 if (EX_ISSYNC(ffhp->fh_export)) {
541 @@ -1620,9 +1622,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
545 - err = vfs_unlink(dirp, rdentry);
546 + err = vfs_unlink(dirp, rdentry, NULL);
547 } else { /* It's RMDIR */
548 - err = vfs_rmdir(dirp, rdentry);
549 + err = vfs_rmdir(dirp, rdentry, NULL);
553 @@ -1734,7 +1736,8 @@ nfsd_permission(struct svc_export *exp,
555 if (!(acc & MAY_LOCAL_ACCESS))
556 if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
557 - if (EX_RDONLY(exp) || IS_RDONLY(inode))
558 + if (EX_RDONLY(exp) || IS_RDONLY(inode)
559 + || MNT_IS_RDONLY(exp->ex_mnt))
561 if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
563 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/open.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/open.c
564 --- linux-2.6.11.5-vs1.9.5.3/fs/open.c 2005-03-23 21:34:32 +0100
565 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/open.c 2005-03-26 00:25:24 +0100
566 @@ -244,7 +244,7 @@ static inline long do_sys_truncate(const
570 - if (IS_RDONLY(inode))
571 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
575 @@ -368,7 +368,7 @@ asmlinkage long sys_utime(char __user *
576 inode = nd.dentry->d_inode;
579 - if (IS_RDONLY(inode))
580 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
583 /* Don't worry, the checks are done in inode_change_ok() */
584 @@ -425,7 +425,7 @@ long do_utimes(char __user * filename, s
585 inode = nd.dentry->d_inode;
588 - if (IS_RDONLY(inode))
589 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
592 /* Don't worry, the checks are done in inode_change_ok() */
593 @@ -507,7 +507,8 @@ asmlinkage long sys_access(const char __
595 res = permission(nd.dentry->d_inode, mode, &nd);
596 /* SuS v2 requires we report a read only fs too */
597 - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
598 + if(!res && (mode & S_IWOTH)
599 + && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
600 && !special_file(nd.dentry->d_inode->i_mode))
603 @@ -613,7 +614,7 @@ asmlinkage long sys_fchmod(unsigned int
604 inode = dentry->d_inode;
607 - if (IS_RDONLY(inode))
608 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
611 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
612 @@ -645,7 +646,7 @@ asmlinkage long sys_chmod(const char __u
613 inode = nd.dentry->d_inode;
616 - if (IS_RDONLY(inode))
617 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
621 @@ -666,7 +667,8 @@ out:
625 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
626 +static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
627 + uid_t user, gid_t group)
629 struct inode * inode;
631 @@ -678,7 +680,7 @@ static int chown_common(struct dentry *
635 - if (IS_RDONLY(inode))
636 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
639 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
640 @@ -709,7 +711,7 @@ asmlinkage long sys_chown(const char __u
642 error = user_path_walk(filename, &nd);
644 - error = chown_common(nd.dentry, user, group);
645 + error = chown_common(nd.dentry, nd.mnt, user, group);
649 @@ -722,7 +724,7 @@ asmlinkage long sys_lchown(const char __
651 error = user_path_walk_link(filename, &nd);
653 - error = chown_common(nd.dentry, user, group);
654 + error = chown_common(nd.dentry, nd.mnt, user, group);
658 @@ -736,7 +738,7 @@ asmlinkage long sys_fchown(unsigned int
662 - error = chown_common(file->f_dentry, user, group);
663 + error = chown_common(file->f_dentry, file->f_vfsmnt, user, group);
667 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/reiserfs/ioctl.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/reiserfs/ioctl.c
668 --- linux-2.6.11.5-vs1.9.5.3/fs/reiserfs/ioctl.c 2005-03-23 21:34:31 +0100
669 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/reiserfs/ioctl.c 2005-03-26 00:25:24 +0100
670 @@ -41,7 +41,8 @@ int reiserfs_ioctl (struct inode * inode
671 flags &= REISERFS_FL_USER_VISIBLE;
672 return put_user(flags, (int __user *) arg);
673 case REISERFS_IOC_SETFLAGS: {
674 - if (IS_RDONLY(inode))
675 + if (IS_RDONLY(inode) ||
676 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
679 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
680 @@ -80,7 +81,8 @@ int reiserfs_ioctl (struct inode * inode
681 case REISERFS_IOC_SETVERSION:
682 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
684 - if (IS_RDONLY(inode))
685 + if (IS_RDONLY(inode) ||
686 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
688 if (get_user(inode->i_generation, (int __user *) arg))
690 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/reiserfs/xattr.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/reiserfs/xattr.c
691 --- linux-2.6.11.5-vs1.9.5.3/fs/reiserfs/xattr.c 2005-03-02 12:38:46 +0100
692 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/reiserfs/xattr.c 2005-03-26 00:25:24 +0100
693 @@ -834,7 +834,7 @@ reiserfs_delete_xattrs (struct inode *in
694 if (dir->d_inode->i_nlink <= 2) {
695 root = get_xa_root (inode->i_sb);
696 reiserfs_write_lock_xattrs (inode->i_sb);
697 - err = vfs_rmdir (root->d_inode, dir);
698 + err = vfs_rmdir (root->d_inode, dir, NULL);
699 reiserfs_write_unlock_xattrs (inode->i_sb);
702 @@ -1355,7 +1355,7 @@ __reiserfs_permission (struct inode *ino
704 * Nobody gets write access to a read-only fs.
706 - if (IS_RDONLY(inode) &&
707 + if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
708 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
711 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/fs/xattr.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/xattr.c
712 --- linux-2.6.11.5-vs1.9.5.3/fs/xattr.c 2004-12-25 01:55:21 +0100
713 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/fs/xattr.c 2005-03-26 00:25:03 +0100
717 setxattr(struct dentry *d, char __user *name, void __user *value,
718 - size_t size, int flags)
719 + size_t size, int flags, struct vfsmount *mnt)
723 @@ -56,6 +56,9 @@ setxattr(struct dentry *d, char __user *
724 error = security_inode_setxattr(d, kname, kvalue, size, flags);
728 + if (MNT_IS_RDONLY(mnt))
730 error = d->d_inode->i_op->setxattr(d, kname, kvalue, size, flags);
733 @@ -77,7 +80,7 @@ sys_setxattr(char __user *path, char __u
734 error = user_path_walk(path, &nd);
737 - error = setxattr(nd.dentry, name, value, size, flags);
738 + error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
742 @@ -92,7 +95,7 @@ sys_lsetxattr(char __user *path, char __
743 error = user_path_walk_link(path, &nd);
746 - error = setxattr(nd.dentry, name, value, size, flags);
747 + error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
751 @@ -107,7 +110,7 @@ sys_fsetxattr(int fd, char __user *name,
755 - error = setxattr(f->f_dentry, name, value, size, flags);
756 + error = setxattr(f->f_dentry, name, value, size, flags, f->f_vfsmnt);
760 @@ -285,7 +288,7 @@ sys_flistxattr(int fd, char __user *list
761 * Extended attribute REMOVE operations
764 -removexattr(struct dentry *d, char __user *name)
765 +removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
768 char kname[XATTR_NAME_MAX + 1];
769 @@ -301,6 +304,9 @@ removexattr(struct dentry *d, char __use
770 error = security_inode_removexattr(d, kname);
774 + if (MNT_IS_RDONLY(mnt))
776 down(&d->d_inode->i_sem);
777 error = d->d_inode->i_op->removexattr(d, kname);
778 up(&d->d_inode->i_sem);
779 @@ -318,7 +324,7 @@ sys_removexattr(char __user *path, char
780 error = user_path_walk(path, &nd);
783 - error = removexattr(nd.dentry, name);
784 + error = removexattr(nd.dentry, name, nd.mnt);
788 @@ -332,7 +338,7 @@ sys_lremovexattr(char __user *path, char
789 error = user_path_walk_link(path, &nd);
792 - error = removexattr(nd.dentry, name);
793 + error = removexattr(nd.dentry, name, nd.mnt);
797 @@ -346,7 +352,7 @@ sys_fremovexattr(int fd, char __user *na
801 - error = removexattr(f->f_dentry, name);
802 + error = removexattr(f->f_dentry, name, f->f_vfsmnt);
806 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/include/linux/fs.h linux-2.6.11.5-vs1.9.5.3-bme0.06.1/include/linux/fs.h
807 --- linux-2.6.11.5-vs1.9.5.3/include/linux/fs.h 2005-03-23 21:34:32 +0100
808 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/include/linux/fs.h 2005-03-26 00:24:49 +0100
810 #include <linux/config.h>
811 #include <linux/limits.h>
812 #include <linux/ioctl.h>
813 +#include <linux/mount.h>
816 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
817 @@ -149,7 +150,7 @@ extern int dir_notify_enable;
819 #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
821 -#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
822 +#define IS_RDONLY(inode) __IS_FLG(inode, MS_RDONLY)
823 #define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \
824 ((inode)->i_flags & S_SYNC))
825 #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
826 @@ -850,12 +851,12 @@ static inline void unlock_super(struct s
827 * VFS helper functions..
829 extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
830 -extern int vfs_mkdir(struct inode *, struct dentry *, int);
831 -extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
832 -extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
833 -extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
834 -extern int vfs_rmdir(struct inode *, struct dentry *);
835 -extern int vfs_unlink(struct inode *, struct dentry *);
836 +extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
837 +extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
838 +extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
839 +extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
840 +extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
841 +extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
842 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
845 @@ -1053,8 +1054,16 @@ static inline void mark_inode_dirty_sync
847 static inline void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
849 - /* per-mountpoint checks will go here */
850 - update_atime(dentry->d_inode);
851 + struct inode *inode = dentry->d_inode;
853 + if (MNT_IS_NOATIME(mnt))
855 + if (S_ISDIR(inode->i_mode) && MNT_IS_NODIRATIME(mnt))
857 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
860 + update_atime(inode);
863 static inline void file_accessed(struct file *file)
864 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/include/linux/mount.h linux-2.6.11.5-vs1.9.5.3-bme0.06.1/include/linux/mount.h
865 --- linux-2.6.11.5-vs1.9.5.3/include/linux/mount.h 2005-03-23 21:34:32 +0100
866 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/include/linux/mount.h 2005-03-26 00:21:46 +0100
871 +#define MNT_RDONLY 8
872 +#define MNT_NOATIME 16
873 +#define MNT_NODIRATIME 32
877 @@ -40,6 +43,10 @@ struct vfsmount
878 xid_t mnt_xid; /* xid tagging used for vfsmount */
881 +#define MNT_IS_RDONLY(m) ((m) && ((m)->mnt_flags & MNT_RDONLY))
882 +#define MNT_IS_NOATIME(m) ((m) && ((m)->mnt_flags & MNT_NOATIME))
883 +#define MNT_IS_NODIRATIME(m) ((m) && ((m)->mnt_flags & MNT_NODIRATIME))
885 static inline struct vfsmount *mntget(struct vfsmount *mnt)
888 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/ipc/mqueue.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/ipc/mqueue.c
889 --- linux-2.6.11.5-vs1.9.5.3/ipc/mqueue.c 2005-03-23 21:34:32 +0100
890 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/ipc/mqueue.c 2005-03-26 00:24:49 +0100
891 @@ -737,7 +737,7 @@ asmlinkage long sys_mq_unlink(const char
893 atomic_inc(&inode->i_count);
895 - err = vfs_unlink(dentry->d_parent->d_inode, dentry);
896 + err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
900 diff -NurpP --minimal linux-2.6.11.5-vs1.9.5.3/net/unix/af_unix.c linux-2.6.11.5-vs1.9.5.3-bme0.06.1/net/unix/af_unix.c
901 --- linux-2.6.11.5-vs1.9.5.3/net/unix/af_unix.c 2005-03-23 21:34:30 +0100
902 +++ linux-2.6.11.5-vs1.9.5.3-bme0.06.1/net/unix/af_unix.c 2005-03-26 00:24:49 +0100
903 @@ -797,7 +797,7 @@ static int unix_bind(struct socket *sock
906 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
907 - err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
908 + err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
911 up(&nd.dentry->d_inode->i_sem);