diff -urN linux-2.4.36.6-wt/drivers/block/loop.c linux-2.4.36.6-bme/drivers/block/loop.c --- linux-2.4.36.6-wt/drivers/block/loop.c 2007-01-05 23:49:42 +0100 +++ linux-2.4.36.6-bme/drivers/block/loop.c 2008-07-18 15:58:35 +0200 @@ -669,8 +669,8 @@ get_file(file); - if (IS_RDONLY (inode) || is_read_only(lo_device) - || !(lo_file->f_mode & FMODE_WRITE)) + if (IS_RDONLY (inode) || MNT_IS_RDONLY(file->f_vfsmnt) + || is_read_only(lo_device) || !(lo_file->f_mode & FMODE_WRITE)) lo_flags |= LO_FLAGS_READ_ONLY; set_device_ro(dev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); diff -urN linux-2.4.36.6-wt/drivers/char/random.c linux-2.4.36.6-bme/drivers/char/random.c --- linux-2.4.36.6-wt/drivers/char/random.c 2007-08-03 15:47:52 +0200 +++ linux-2.4.36.6-bme/drivers/char/random.c 2008-07-18 15:58:35 +0200 @@ -1556,7 +1556,7 @@ * If we gave the user some bytes, update the access time. */ if (count != 0) { - UPDATE_ATIME(file->f_dentry->d_inode); + UPDATE_ATIME(file->f_dentry->d_inode, file->f_vfsmnt); } return (count ? count : retval); diff -urN linux-2.4.36.6-wt/drivers/usb/gadget/file_storage.c linux-2.4.36.6-bme/drivers/usb/gadget/file_storage.c --- linux-2.4.36.6-wt/drivers/usb/gadget/file_storage.c 2005-11-18 21:08:36 +0100 +++ linux-2.4.36.6-bme/drivers/usb/gadget/file_storage.c 2008-07-18 15:58:35 +0200 @@ -3469,7 +3469,8 @@ LINFO(curlun, "file not readable: %s\n", filename); goto out; } - if (IS_RDONLY(inode) || !filp->f_op->write) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt) + || !filp->f_op->write) ro = 1; num_sectors = size >> 9; // File size in 512-byte sectors diff -urN linux-2.4.36.6-wt/fs/autofs4/root.c linux-2.4.36.6-bme/fs/autofs4/root.c --- linux-2.4.36.6-wt/fs/autofs4/root.c 2003-08-25 13:44:43 +0200 +++ linux-2.4.36.6-bme/fs/autofs4/root.c 2008-07-18 15:58:35 +0200 @@ -62,7 +62,8 @@ struct autofs_info *ino = autofs4_dentry_ino(dentry); if (ino) { - update_atime(dentry->d_inode); + /* Al Viro said: unconditional */ + update_atime(dentry->d_inode, 0); ino->last_used = jiffies; } } diff -urN linux-2.4.36.6-wt/fs/bfs/dir.c linux-2.4.36.6-bme/fs/bfs/dir.c --- linux-2.4.36.6-wt/fs/bfs/dir.c 2003-08-25 13:44:43 +0200 +++ linux-2.4.36.6-bme/fs/bfs/dir.c 2008-07-18 15:58:35 +0200 @@ -61,7 +61,7 @@ brelse(bh); } - UPDATE_ATIME(dir); + UPDATE_ATIME(dir, f->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/ext2/dir.c linux-2.4.36.6-bme/fs/ext2/dir.c --- linux-2.4.36.6-wt/fs/ext2/dir.c 2008-07-18 11:13:50 +0200 +++ linux-2.4.36.6-bme/fs/ext2/dir.c 2008-07-18 15:59:25 +0200 @@ -298,7 +298,7 @@ done: filp->f_version = inode->i_version; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); return ret; } diff -urN linux-2.4.36.6-wt/fs/ext2/ioctl.c linux-2.4.36.6-bme/fs/ext2/ioctl.c --- linux-2.4.36.6-wt/fs/ext2/ioctl.c 2008-07-18 15:58:13 +0200 +++ linux-2.4.36.6-bme/fs/ext2/ioctl.c 2008-07-18 15:58:35 +0200 @@ -27,7 +27,7 @@ case EXT2_IOC_SETFLAGS: { unsigned int oldflags; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt)) return -EROFS; if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) @@ -65,7 +65,7 @@ case EXT2_IOC_SETVERSION: if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt)) return -EROFS; if (get_user(inode->i_generation, (int *) arg)) return -EFAULT; diff -urN linux-2.4.36.6-wt/fs/ext3/dir.c linux-2.4.36.6-bme/fs/ext3/dir.c --- linux-2.4.36.6-wt/fs/ext3/dir.c 2001-11-09 23:25:04 +0100 +++ linux-2.4.36.6-bme/fs/ext3/dir.c 2008-07-18 15:58:35 +0200 @@ -185,6 +185,6 @@ offset = 0; brelse (bh); } - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/ext3/ioctl.c linux-2.4.36.6-bme/fs/ext3/ioctl.c --- linux-2.4.36.6-wt/fs/ext3/ioctl.c 2008-07-18 15:58:13 +0200 +++ linux-2.4.36.6-bme/fs/ext3/ioctl.c 2008-07-18 15:58:35 +0200 @@ -33,7 +33,7 @@ unsigned int oldflags; unsigned int jflag; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt)) return -EROFS; if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) @@ -108,7 +108,7 @@ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt)) return -EROFS; if (get_user(generation, (int *) arg)) return -EFAULT; diff -urN linux-2.4.36.6-wt/fs/inode.c linux-2.4.36.6-bme/fs/inode.c --- linux-2.4.36.6-wt/fs/inode.c 2006-03-01 00:01:47 +0100 +++ linux-2.4.36.6-bme/fs/inode.c 2008-07-18 15:58:35 +0200 @@ -1357,15 +1357,16 @@ * as well as the "noatime" flag and inode specific "noatime" markers. */ -void update_atime (struct inode *inode) +void update_atime (struct inode *inode, struct vfsmount *mnt) { if (inode->i_atime == CURRENT_TIME) return; - if (IS_NOATIME(inode)) + if (IS_NOATIME(inode) || MNT_IS_NOATIME(mnt)) return; - if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode)) + if (S_ISDIR(inode->i_mode) && + (IS_NODIRATIME(inode) || MNT_IS_NODIRATIME(mnt))) return; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) return; inode->i_atime = CURRENT_TIME; mark_inode_dirty_sync (inode); @@ -1380,11 +1381,11 @@ * up-to-date or if the filesystem is readonly. */ -void update_mctime (struct inode *inode) +void update_mctime (struct inode *inode, struct vfsmount *mnt) { if (inode->i_mtime == CURRENT_TIME && inode->i_ctime == CURRENT_TIME) return; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) return; inode->i_ctime = inode->i_mtime = CURRENT_TIME; mark_inode_dirty (inode); diff -urN linux-2.4.36.6-wt/fs/minix/dir.c linux-2.4.36.6-bme/fs/minix/dir.c --- linux-2.4.36.6-wt/fs/minix/dir.c 2002-02-25 20:38:09 +0100 +++ linux-2.4.36.6-bme/fs/minix/dir.c 2008-07-18 15:58:35 +0200 @@ -114,7 +114,7 @@ done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/namei.c linux-2.4.36.6-bme/fs/namei.c --- linux-2.4.36.6-wt/fs/namei.c 2008-07-18 15:58:13 +0200 +++ linux-2.4.36.6-bme/fs/namei.c 2008-07-18 15:58:35 +0200 @@ -349,7 +349,7 @@ } current->link_count++; current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); + UPDATE_ATIME(dentry->d_inode, nd->mnt); err = dentry->d_inode->i_op->follow_link(dentry, nd); current->link_count--; return err; @@ -943,6 +943,24 @@ return permission(dir,MAY_WRITE | MAY_EXEC); } +static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) { + if (child->d_inode) + return -EEXIST; + if (IS_DEADDIR(dir)) + return -ENOENT; + if (mnt->mnt_flags & MNT_RDONLY) + return -EROFS; + return 0; +} + +static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) { + if (!child->d_inode) + return -ENOENT; + if (mnt->mnt_flags & MNT_RDONLY) + return -EROFS; + return 0; +} + /* * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security * reasons. @@ -1057,6 +1075,11 @@ /* Negative dentry, just create the file */ if (!dentry->d_inode) { + error = -EROFS; + if (MNT_IS_RDONLY(nd->mnt)) { + up(&dir->d_inode->i_sem); + goto exit; + } error = vfs_create(dir->d_inode, dentry, mode & ~current->fs->umask); up(&dir->d_inode->i_sem); @@ -1129,7 +1152,8 @@ flag &= ~O_TRUNC; } else { error = -EROFS; - if (IS_RDONLY(inode) && (flag & 2)) + if ((flag & FMODE_WRITE) && + (IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))) goto exit; } /* @@ -1193,7 +1217,7 @@ * stored in nd->last.name and we will have to putname() it when we * are done. Procfs-like symlinks just set LAST_BIND. */ - UPDATE_ATIME(dentry->d_inode); + UPDATE_ATIME(dentry->d_inode, nd->mnt); mnt = mntget(nd->mnt); error = dentry->d_inode->i_op->follow_link(dentry, nd); dput(dentry); @@ -1227,22 +1251,27 @@ static struct dentry *lookup_create(struct nameidata *nd, int is_dir) { struct dentry *dentry; + int error; down(&nd->dentry->d_inode->i_sem); - dentry = ERR_PTR(-EEXIST); + error = -EEXIST; if (nd->last_type != LAST_NORM) - goto fail; + goto out; dentry = lookup_hash(&nd->last, nd->dentry); if (IS_ERR(dentry)) + goto ret; + error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry); + if (error) goto fail; + error = -ENOENT; if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) - goto enoent; + goto fail; +ret: return dentry; -enoent: - dput(dentry); - dentry = ERR_PTR(-ENOENT); fail: - return dentry; + dput(dentry); +out: + return ERR_PTR(error); } int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) @@ -1468,7 +1497,11 @@ dentry = lookup_hash(&nd.last, nd.dentry); error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { + error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry); + if (error) + goto exit2; error = vfs_rmdir(nd.dentry->d_inode, dentry); + exit2: dput(dentry); } up(&nd.dentry->d_inode->i_sem); @@ -1537,7 +1570,9 @@ /* Why not before? Because we want correct error value */ if (nd.last.name[nd.last.len]) goto slashes; - error = vfs_unlink(nd.dentry->d_inode, dentry); + error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry); + if (!error) + error = vfs_unlink(nd.dentry->d_inode, dentry); exit2: dput(dentry); } @@ -1913,6 +1948,9 @@ if (newnd.last.name[newnd.last.len]) goto exit4; } + error = -EROFS; + if (MNT_IS_RDONLY(newnd.mnt)) + goto exit4; new_dentry = lookup_hash(&newnd.last, new_dir); error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) diff -urN linux-2.4.36.6-wt/fs/namespace.c linux-2.4.36.6-bme/fs/namespace.c --- linux-2.4.36.6-wt/fs/namespace.c 2004-02-18 14:36:31 +0100 +++ linux-2.4.36.6-bme/fs/namespace.c 2008-07-18 15:58:36 +0200 @@ -226,7 +226,7 @@ free_page((unsigned long) path_buf); seq_putc(m, ' '); mangle(m, mnt->mnt_sb->s_type->name); - seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); + seq_puts(m, (MNT_IS_RDONLY(mnt) || mnt->mnt_sb->s_flags & MS_RDONLY) ? " ro" : " rw"); for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { if (mnt->mnt_sb->s_flags & fs_infop->flag) seq_puts(m, fs_infop->str); @@ -484,11 +484,13 @@ /* * do loopback mount. */ -static int do_loopback(struct nameidata *nd, char *old_name, int recurse) +static int do_loopback(struct nameidata *nd, char *old_name, unsigned long flags, int mnt_flags) { struct nameidata old_nd; struct vfsmount *mnt = NULL; + int recurse = flags & MS_REC; int err = mount_is_safe(nd); + if (err) return err; if (!old_name || !*old_name) @@ -515,6 +517,7 @@ spin_unlock(&dcache_lock); } else mntput(mnt); + mnt->mnt_flags = mnt_flags; } up_write(¤t->namespace->sem); @@ -719,12 +722,18 @@ ((char *)data_page)[PAGE_SIZE - 1] = 0; /* Separate the per-mountpoint flags */ + if (flags & MS_RDONLY) + mnt_flags |= MNT_RDONLY; if (flags & MS_NOSUID) mnt_flags |= MNT_NOSUID; if (flags & MS_NODEV) mnt_flags |= MNT_NODEV; if (flags & MS_NOEXEC) mnt_flags |= MNT_NOEXEC; + if (flags & MS_NOATIME) + mnt_flags |= MNT_NOATIME; + if (flags & MS_NODIRATIME) + mnt_flags |= MNT_NODIRATIME; flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV); /* ... and get the mountpoint */ @@ -736,7 +745,7 @@ retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, data_page); else if (flags & MS_BIND) - retval = do_loopback(&nd, dev_name, flags & MS_REC); + retval = do_loopback(&nd, dev_name, flags, mnt_flags); else if (flags & MS_MOVE) retval = do_move_mount(&nd, dev_name); else diff -urN linux-2.4.36.6-wt/fs/ncpfs/file.c linux-2.4.36.6-bme/fs/ncpfs/file.c --- linux-2.4.36.6-wt/fs/ncpfs/file.c 2001-09-10 18:04:53 +0200 +++ linux-2.4.36.6-bme/fs/ncpfs/file.c 2008-07-18 15:58:36 +0200 @@ -176,7 +176,7 @@ *ppos = pos; - if (!IS_RDONLY(inode)) { + if (!IS_RDONLY(inode) && !MNT_IS_RDONLY(file->f_vfsmnt)) { inode->i_atime = CURRENT_TIME; } diff -urN linux-2.4.36.6-wt/fs/ncpfs/mmap.c linux-2.4.36.6-bme/fs/ncpfs/mmap.c --- linux-2.4.36.6-wt/fs/ncpfs/mmap.c 2008-07-18 11:13:50 +0200 +++ linux-2.4.36.6-bme/fs/ncpfs/mmap.c 2008-07-18 15:58:36 +0200 @@ -111,7 +111,7 @@ if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff > (1U << (32 - PAGE_SHIFT))) return -EFBIG; - if (!IS_RDONLY(inode)) { + if (!IS_RDONLY(inode) && !MNT_IS_RDONLY(file->f_vfsmnt)) { inode->i_atime = CURRENT_TIME; } diff -urN linux-2.4.36.6-wt/fs/nfsd/vfs.c linux-2.4.36.6-bme/fs/nfsd/vfs.c --- linux-2.4.36.6-wt/fs/nfsd/vfs.c 2008-07-18 15:58:13 +0200 +++ linux-2.4.36.6-bme/fs/nfsd/vfs.c 2008-07-18 15:58:36 +0200 @@ -1113,7 +1113,7 @@ if (!inode->i_op || !inode->i_op->readlink) goto out; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, fhp->fh_export->ex_mnt); /* N.B. Why does this call need a get_fs()?? * Remove the set_fs and watch the fireworks:-) --okir */ @@ -1537,7 +1537,8 @@ * on volumes exported read-only. */ if (!(acc & _NFSD_IRIX_BOGOSITY) && (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC))) { - if (EX_RDONLY(exp) || IS_RDONLY(inode)) + if (EX_RDONLY(exp) || IS_RDONLY(inode) + || MNT_IS_RDONLY(exp->ex_mnt)) return nfserr_rofs; if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode)) return nfserr_perm; diff -urN linux-2.4.36.6-wt/fs/open.c linux-2.4.36.6-bme/fs/open.c --- linux-2.4.36.6-wt/fs/open.c 2008-07-18 15:58:13 +0200 +++ linux-2.4.36.6-bme/fs/open.c 2008-07-18 15:58:36 +0200 @@ -144,7 +144,7 @@ goto dput_and_out; error = -EROFS; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) goto dput_and_out; error = -EPERM; @@ -268,7 +268,7 @@ inode = nd.dentry->d_inode; error = -EROFS; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) goto dput_and_out; /* Don't worry, the checks are done in inode_change_ok() */ @@ -319,7 +319,7 @@ inode = nd.dentry->d_inode; error = -EROFS; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) goto dput_and_out; /* Don't worry, the checks are done in inode_change_ok() */ @@ -383,8 +383,9 @@ if (!res) { res = permission(nd.dentry->d_inode, mode); /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) + if (!res && (mode & S_IWOTH) + && !special_file(nd.dentry->d_inode->i_mode) + && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))) res = -EROFS; path_release(&nd); } @@ -490,7 +491,7 @@ inode = dentry->d_inode; err = -EROFS; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt)) goto out_putf; err = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) @@ -523,7 +524,7 @@ inode = nd.dentry->d_inode; error = -EROFS; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) goto dput_and_out; error = -EPERM; @@ -545,7 +546,7 @@ return error; } -static int chown_common(struct dentry * dentry, uid_t user, gid_t group) +static int chown_common(struct vfsmount *mnt, struct dentry * dentry, uid_t user, gid_t group) { struct inode * inode; int error; @@ -557,7 +558,7 @@ goto out; } error = -EROFS; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) goto out; error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) @@ -612,7 +613,7 @@ error = user_path_walk(filename, &nd); if (!error) { - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.mnt, nd.dentry, user, group); path_release(&nd); } return error; @@ -625,7 +626,7 @@ error = user_path_walk_link(filename, &nd); if (!error) { - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.mnt, nd.dentry, user, group); path_release(&nd); } return error; @@ -639,7 +640,7 @@ file = fget(fd); if (file) { - error = chown_common(file->f_dentry, user, group); + error = chown_common(file->f_vfsmnt, file->f_dentry, user, group); fput(file); } return error; diff -urN linux-2.4.36.6-wt/fs/pipe.c linux-2.4.36.6-bme/fs/pipe.c --- linux-2.4.36.6-wt/fs/pipe.c 2003-08-25 13:44:43 +0200 +++ linux-2.4.36.6-bme/fs/pipe.c 2008-07-18 15:58:36 +0200 @@ -130,7 +130,7 @@ if (read) ret = read; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); return ret; } @@ -230,7 +230,7 @@ /* Signal readers asynchronously that there is more data. */ wake_up_interruptible(PIPE_WAIT(*inode)); - update_mctime(inode); + update_mctime(inode, filp->f_vfsmnt); out: up(PIPE_SEM(*inode)); diff -urN linux-2.4.36.6-wt/fs/qnx4/dir.c linux-2.4.36.6-bme/fs/qnx4/dir.c --- linux-2.4.36.6-wt/fs/qnx4/dir.c 2002-02-25 20:38:09 +0100 +++ linux-2.4.36.6-bme/fs/qnx4/dir.c 2008-07-18 15:58:36 +0200 @@ -73,7 +73,7 @@ } brelse(bh); } - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/readdir.c linux-2.4.36.6-bme/fs/readdir.c --- linux-2.4.36.6-wt/fs/readdir.c 2004-11-17 12:54:21 +0100 +++ linux-2.4.36.6-bme/fs/readdir.c 2008-07-18 15:58:36 +0200 @@ -146,7 +146,7 @@ } spin_unlock(&dcache_lock); } - UPDATE_ATIME(dentry->d_inode); + UPDATE_ATIME(dentry->d_inode, filp->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/reiserfs/dir.c linux-2.4.36.6-bme/fs/reiserfs/dir.c --- linux-2.4.36.6-wt/fs/reiserfs/dir.c 2003-08-25 13:44:43 +0200 +++ linux-2.4.36.6-bme/fs/reiserfs/dir.c 2008-07-18 15:58:36 +0200 @@ -181,7 +181,7 @@ filp->f_pos = next_pos; pathrelse (&path_to_entry); reiserfs_check_path(&path_to_entry) ; - UPDATE_ATIME(inode) ; + UPDATE_ATIME(inode, filp->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/reiserfs/ioctl.c linux-2.4.36.6-bme/fs/reiserfs/ioctl.c --- linux-2.4.36.6-wt/fs/reiserfs/ioctl.c 2008-07-18 15:58:14 +0200 +++ linux-2.4.36.6-bme/fs/reiserfs/ioctl.c 2008-07-18 15:58:36 +0200 @@ -44,7 +44,7 @@ case REISERFS_IOC_SETFLAGS: { unsigned int oldflags; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt)) return -EROFS; if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) @@ -84,7 +84,7 @@ case REISERFS_IOC_SETVERSION: if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt)) return -EROFS; if (get_user(inode->i_generation, (int *) arg)) return -EFAULT; diff -urN linux-2.4.36.6-wt/fs/stat.c linux-2.4.36.6-bme/fs/stat.c --- linux-2.4.36.6-wt/fs/stat.c 2004-08-08 01:26:06 +0200 +++ linux-2.4.36.6-bme/fs/stat.c 2008-07-18 15:58:36 +0200 @@ -264,7 +264,7 @@ error = -EINVAL; if (inode->i_op && inode->i_op->readlink && !(error = do_revalidate(nd.dentry))) { - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, nd.mnt); error = inode->i_op->readlink(nd.dentry, buf, bufsiz); } path_release(&nd); diff -urN linux-2.4.36.6-wt/fs/sysv/dir.c linux-2.4.36.6-bme/fs/sysv/dir.c --- linux-2.4.36.6-wt/fs/sysv/dir.c 2002-02-25 20:38:09 +0100 +++ linux-2.4.36.6-bme/fs/sysv/dir.c 2008-07-18 15:58:36 +0200 @@ -117,7 +117,7 @@ done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; filp->f_version = inode->i_version; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/udf/dir.c linux-2.4.36.6-bme/fs/udf/dir.c --- linux-2.4.36.6-wt/fs/udf/dir.c 2002-08-03 02:39:45 +0200 +++ linux-2.4.36.6-bme/fs/udf/dir.c 2008-07-18 15:58:36 +0200 @@ -91,7 +91,7 @@ } result = do_udf_readdir(dir, filp, filldir, dirent); - UPDATE_ATIME(dir); + UPDATE_ATIME(dir, filp->f_vfsmnt); return result; } diff -urN linux-2.4.36.6-wt/fs/ufs/dir.c linux-2.4.36.6-bme/fs/ufs/dir.c --- linux-2.4.36.6-wt/fs/ufs/dir.c 2002-02-25 20:38:09 +0100 +++ linux-2.4.36.6-bme/fs/ufs/dir.c 2008-07-18 15:58:36 +0200 @@ -160,7 +160,7 @@ offset = 0; brelse (bh); } - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); return 0; } diff -urN linux-2.4.36.6-wt/fs/xfs/linux-2.4/xfs_lrw.c linux-2.4.36.6-bme/fs/xfs/linux-2.4/xfs_lrw.c --- linux-2.4.36.6-wt/fs/xfs/linux-2.4/xfs_lrw.c 2005-01-27 18:57:33 +0100 +++ linux-2.4.36.6-bme/fs/xfs/linux-2.4/xfs_lrw.c 2008-07-18 15:58:36 +0200 @@ -329,7 +329,7 @@ buf, size, *offset, ioflags); ret = (*offset < ip->i_d.di_size) ? do_generic_direct_read(file, buf, size, offset) : 0; - UPDATE_ATIME(file->f_dentry->d_inode); + UPDATE_ATIME(file->f_dentry->d_inode, file->f_vfsmnt); } else { xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, buf, size, *offset, ioflags); diff -urN linux-2.4.36.6-wt/include/linux/fs.h linux-2.4.36.6-bme/include/linux/fs.h --- linux-2.4.36.6-wt/include/linux/fs.h 2008-07-18 15:58:14 +0200 +++ linux-2.4.36.6-bme/include/linux/fs.h 2008-07-18 15:58:36 +0200 @@ -207,9 +207,9 @@ #include #include -extern void update_atime (struct inode *); -extern void update_mctime (struct inode *); -#define UPDATE_ATIME(inode) update_atime (inode) +extern void update_atime (struct inode *, struct vfsmount *); +extern void update_mctime (struct inode *, struct vfsmount *); +#define UPDATE_ATIME(inode, mnt) update_atime (inode, mnt) extern void buffer_init(unsigned long); extern void inode_init(unsigned long); diff -urN linux-2.4.36.6-wt/include/linux/mount.h linux-2.4.36.6-bme/include/linux/mount.h --- linux-2.4.36.6-wt/include/linux/mount.h 2001-10-05 22:05:55 +0200 +++ linux-2.4.36.6-bme/include/linux/mount.h 2008-07-18 15:58:36 +0200 @@ -12,9 +12,12 @@ #define _LINUX_MOUNT_H #ifdef __KERNEL__ -#define MNT_NOSUID 1 -#define MNT_NODEV 2 -#define MNT_NOEXEC 4 +#define MNT_RDONLY 1 +#define MNT_NOSUID 2 +#define MNT_NODEV 4 +#define MNT_NOEXEC 8 +#define MNT_NOATIME 1024 +#define MNT_NODIRATIME 2048 struct vfsmount { @@ -31,6 +34,11 @@ struct list_head mnt_list; }; + /* remove (m) with fixmes */ +#define MNT_IS_RDONLY(m) ((m) && ((m)->mnt_flags & MNT_RDONLY)) +#define MNT_IS_NOATIME(m) ((m) && ((m)->mnt_flags & MNT_NOATIME)) +#define MNT_IS_NODIRATIME(m) ((m) && ((m)->mnt_flags & MNT_NODIRATIME)) + static inline struct vfsmount *mntget(struct vfsmount *mnt) { if (mnt) diff -urN linux-2.4.36.6-wt/ipc/shm.c linux-2.4.36.6-bme/ipc/shm.c --- linux-2.4.36.6-wt/ipc/shm.c 2006-06-19 09:01:32 +0200 +++ linux-2.4.36.6-bme/ipc/shm.c 2008-07-18 15:58:36 +0200 @@ -159,7 +159,7 @@ static int shm_mmap(struct file * file, struct vm_area_struct * vma) { - UPDATE_ATIME(file->f_dentry->d_inode); + UPDATE_ATIME(file->f_dentry->d_inode, file->f_vfsmnt); vma->vm_ops = &shm_vm_ops; if (!(vma->vm_flags & VM_WRITE)) vma->vm_flags &= ~VM_MAYWRITE; diff -urN linux-2.4.36.6-wt/mm/filemap.c linux-2.4.36.6-bme/mm/filemap.c --- linux-2.4.36.6-wt/mm/filemap.c 2007-01-05 23:49:45 +0100 +++ linux-2.4.36.6-bme/mm/filemap.c 2008-07-18 15:58:36 +0200 @@ -1613,7 +1613,7 @@ filp->f_reada = 1; if (cached_page) page_cache_release(cached_page); - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); } static inline int have_mapping_directIO(struct address_space * mapping) @@ -1810,7 +1810,7 @@ retval = do_generic_direct_read(filp, buf, count, ppos); up(&inode->i_sem); up_read(&inode->i_alloc_sem); - UPDATE_ATIME(filp->f_dentry->d_inode); + UPDATE_ATIME(filp->f_dentry->d_inode, filp->f_vfsmnt); goto out; } } @@ -2325,7 +2325,7 @@ } if (!mapping->a_ops->readpage) return -ENOEXEC; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, file->f_vfsmnt); vma->vm_ops = &generic_file_vm_ops; return 0; } diff -urN linux-2.4.36.6-wt/mm/shmem.c linux-2.4.36.6-bme/mm/shmem.c --- linux-2.4.36.6-wt/mm/shmem.c 2004-11-17 12:54:22 +0100 +++ linux-2.4.36.6-bme/mm/shmem.c 2008-07-18 15:58:36 +0200 @@ -847,7 +847,7 @@ ops = &shmem_vm_ops; if (!S_ISREG(inode->i_mode)) return -EACCES; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, file->f_vfsmnt); vma->vm_ops = ops; return 0; } @@ -1132,7 +1132,7 @@ *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; filp->f_reada = 1; - UPDATE_ATIME(inode); + UPDATE_ATIME(inode, filp->f_vfsmnt); } static ssize_t shmem_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos) diff -urN linux-2.4.36.6-wt/net/unix/af_unix.c linux-2.4.36.6-bme/net/unix/af_unix.c --- linux-2.4.36.6-wt/net/unix/af_unix.c 2008-07-18 15:58:15 +0200 +++ linux-2.4.36.6-bme/net/unix/af_unix.c 2008-07-18 15:58:36 +0200 @@ -598,7 +598,7 @@ goto put_fail; if (u->type == type) - UPDATE_ATIME(nd.dentry->d_inode); + UPDATE_ATIME(nd.dentry->d_inode, nd.mnt); path_release(&nd); @@ -614,7 +614,7 @@ struct dentry *dentry; dentry = u->protinfo.af_unix.dentry; if (dentry) - UPDATE_ATIME(dentry->d_inode); + UPDATE_ATIME(dentry->d_inode, nd.mnt); } else goto fail; }