X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fattr.c;h=04f5d0b19914520c43d5ceac4be3641d0c210ab9;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=5f78d75a8ddfd7ce5dd2e5a754369f8ad2d5a3ea;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/fs/attr.c b/fs/attr.c index 5f78d75a8..04f5d0b19 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -10,13 +10,14 @@ #include #include #include -#include +#include +#include #include #include #include -#include #include #include +#include /* Taken over from the old code... */ @@ -60,26 +61,25 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) } /* Check for evil vserver activity */ - if (vx_check(0, VX_ADMIN)) + if (vx_check(0, VS_ADMIN)) goto fine; if (IS_BARRIER(inode)) { - printk(KERN_WARNING - "VSW: xid=%d messing with the barrier.\n", + vxwprintk(1, "xid=%d messing with the barrier.", vx_current_xid()); goto error; } switch (inode->i_sb->s_magic) { case PROC_SUPER_MAGIC: - printk(KERN_WARNING - "VSW: xid=%d messing with the procfs.\n", + /* maybe allow that in the future? */ + vxwprintk(1, "xid=%d messing with the procfs.", vx_current_xid()); goto error; case DEVPTS_SUPER_MAGIC: - if (vx_check(inode->i_xid, VX_IDENT)) + /* devpts is xid tagged */ + if (vx_check((xid_t)inode->i_tag, VS_IDENT)) goto fine; - printk(KERN_WARNING - "VSW: xid=%d messing with the devpts.\n", + vxwprintk(1, "xid=%d messing with the devpts.", vx_current_xid()); goto error; } @@ -91,55 +91,32 @@ error: EXPORT_SYMBOL(inode_change_ok); -int inode_setattr_flags(struct inode *inode, unsigned int flags) -{ - unsigned int oldflags, newflags; - - oldflags = inode->i_flags; - newflags = oldflags & ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER); - if (flags & ATTR_FLAG_IMMUTABLE) - newflags |= S_IMMUTABLE; - if (flags & ATTR_FLAG_IUNLINK) - newflags |= S_IUNLINK; - if (flags & ATTR_FLAG_BARRIER) - newflags |= S_BARRIER; - - if (oldflags ^ newflags) - inode->i_flags = newflags; - return 0; -} - int inode_setattr(struct inode * inode, struct iattr * attr) { unsigned int ia_valid = attr->ia_valid; - int error = 0; - - if (ia_valid & ATTR_SIZE) { - if (attr->ia_size != i_size_read(inode)) { - error = vmtruncate(inode, attr->ia_size); - if (error || (ia_valid == ATTR_SIZE)) - goto out; - } else { - /* - * We skipped the truncate but must still update - * timestamps - */ - ia_valid |= ATTR_MTIME|ATTR_CTIME; - } + + if (ia_valid & ATTR_SIZE && + attr->ia_size != i_size_read(inode)) { + int error = vmtruncate(inode, attr->ia_size); + if (error) + return error; } if (ia_valid & ATTR_UID) inode->i_uid = attr->ia_uid; if (ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; - if (ia_valid & ATTR_XID) - inode->i_xid = attr->ia_xid; + if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode)) + inode->i_tag = attr->ia_tag; if (ia_valid & ATTR_ATIME) - inode->i_atime = attr->ia_atime; + inode->i_atime = timespec_trunc(attr->ia_atime, + inode->i_sb->s_time_gran); if (ia_valid & ATTR_MTIME) - inode->i_mtime = attr->ia_mtime; + inode->i_mtime = timespec_trunc(attr->ia_mtime, + inode->i_sb->s_time_gran); if (ia_valid & ATTR_CTIME) - inode->i_ctime = attr->ia_ctime; + inode->i_ctime = timespec_trunc(attr->ia_ctime, + inode->i_sb->s_time_gran); if (ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; @@ -147,49 +124,22 @@ int inode_setattr(struct inode * inode, struct iattr * attr) mode &= ~S_ISGID; inode->i_mode = mode; } - if (ia_valid & ATTR_ATTR_FLAG) - inode_setattr_flags(inode, attr->ia_attr_flags); mark_inode_dirty(inode); -out: - return error; -} - -EXPORT_SYMBOL(inode_setattr); - -int setattr_mask(unsigned int ia_valid) -{ - unsigned long dn_mask = 0; - if (ia_valid & ATTR_UID) - dn_mask |= DN_ATTRIB; - if (ia_valid & ATTR_GID) - dn_mask |= DN_ATTRIB; - if (ia_valid & ATTR_XID) - dn_mask |= DN_ATTRIB; - if (ia_valid & ATTR_SIZE) - dn_mask |= DN_MODIFY; - /* both times implies a utime(s) call */ - if ((ia_valid & (ATTR_ATIME|ATTR_MTIME)) == (ATTR_ATIME|ATTR_MTIME)) - dn_mask |= DN_ATTRIB; - else if (ia_valid & ATTR_ATIME) - dn_mask |= DN_ACCESS; - else if (ia_valid & ATTR_MTIME) - dn_mask |= DN_MODIFY; - if (ia_valid & ATTR_MODE) - dn_mask |= DN_ATTRIB; - return dn_mask; + return 0; } +EXPORT_SYMBOL(inode_setattr); int notify_change(struct dentry * dentry, struct iattr * attr) { struct inode *inode = dentry->d_inode; - mode_t mode = inode->i_mode; + mode_t mode; int error; - struct timespec now = CURRENT_TIME; + struct timespec now; unsigned int ia_valid = attr->ia_valid; - if (!inode) - BUG(); + mode = inode->i_mode; + now = current_fs_time(inode->i_sb); attr->ia_ctime = now; if (!(ia_valid & ATTR_ATIME_SET)) @@ -219,6 +169,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr) if (!attr->ia_valid) return 0; + if (ia_valid & ATTR_SIZE) + down_write(&dentry->d_inode->i_alloc_sem); + if (inode->i_op && inode->i_op->setattr) { error = security_inode_setattr(dentry, attr); if (!error) @@ -230,17 +183,19 @@ int notify_change(struct dentry * dentry, struct iattr * attr) if (!error) { if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || - (ia_valid & ATTR_XID && attr->ia_xid != inode->i_xid)) + (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; if (!error) error = inode_setattr(inode, attr); } } - if (!error) { - unsigned long dn_mask = setattr_mask(ia_valid); - if (dn_mask) - dnotify_parent(dentry, dn_mask); - } + + if (ia_valid & ATTR_SIZE) + up_write(&dentry->d_inode->i_alloc_sem); + + if (!error) + fsnotify_change(dentry, ia_valid); + return error; }