if (err || !iap->ia_valid) 
if (err) 
nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,	     int check_guard, time_t guardtime){	struct dentry	*dentry;	struct inode	*inode;	int		accmode = MAY_SATTR;	int		ftype = 0;	int		imode;	int		err;	int		size_change = 0;	if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))		accmode |= MAY_WRITE|MAY_OWNER_OVERRIDE;	if (iap->ia_valid & ATTR_SIZE)		ftype = S_IFREG;	/* Get inode */	err = fh_verify(rqstp, fhp, ftype, accmode);	if (err || !iap->ia_valid)		goto out;	dentry = fhp->fh_dentry;	inode = dentry->d_inode;	/* NFSv2 does not differentiate between "set-[ac]time-to-now"	 * which only requires access, and "set-[ac]time-to-X" which	 * requires ownership.	 * So if it looks like it might be "set both to the same time which	 * is close to now", and if inode_change_ok fails, then we	 * convert to "set to now" instead of "set to explicit time"	 *	 * We only call inode_change_ok as the last test as technically	 * it is not an interface that we should be using.  It is only	 * valid if the filesystem does not define it's own i_op->setattr.	 */#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)#define	MAX_TOUCH_TIME_ERROR (30*60)	if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET	    && iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec	    ) {	    /* Looks probable.  Now just make sure time is in the right ballpark.	     * Solaris, at least, doesn't seem to care what the time request is.	     * We require it be within 30 minutes of now.	     */	    time_t delta = iap->ia_atime.tv_sec - get_seconds();	    if (delta<0) delta = -delta;	    if (delta < MAX_TOUCH_TIME_ERROR &&		inode_change_ok(inode, iap) != 0) {		/* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME		 * this will cause notify_change to set these times to "now"		 */		iap->ia_valid &= ~BOTH_TIME_SET;	    }	}	    	/* The size case is special. It changes the file as well as the attributes.  */	if (iap->ia_valid & ATTR_SIZE) {		if (iap->ia_size < inode->i_size) {			err = nfsd_permission(fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE);			if (err)				goto out;		}		/*		 * If we are changing the size of the file, then		 * we need to break all leases.		 */		err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);		if (err == -EWOULDBLOCK)			err = -ETIMEDOUT;		if (err) /* ENOMEM or EWOULDBLOCK */			goto out_nfserr;		err = get_write_access(inode);		if (err)			goto out_nfserr;		size_change = 1;		err = locks_verify_truncate(inode, NULL, iap->ia_size);		if (err) {			put_write_access(inode);			goto out_nfserr;		}		DQUOT_INIT(inode);	}	imode = inode->i_mode;	if (iap->ia_valid & ATTR_MODE) {		iap->ia_mode &= S_IALLUGO;		imode = iap->ia_mode |= (imode & ~S_IALLUGO);	}	/* Revoke setuid/setgid bit on chown/chgrp */	if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)		iap->ia_valid |= ATTR_KILL_SUID;	if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)		iap->ia_valid |= ATTR_KILL_SGID;	/* Change the attributes. */	iap->ia_valid |= ATTR_CTIME;	err = nfserr_notsync;	if (!check_guard || guardtime == inode->i_ctime.tv_sec) {		fh_lock(fhp);		err = notify_change(dentry, iap);		err = nfserrno(err);		fh_unlock(fhp);	}	if (size_change)		put_write_access(inode);	if (!err)		if (EX_ISSYNC(fhp->fh_export))			write_inode_now(inode, 1);out:	return err;out_nfserr:	err = nfserrno(err);	goto out;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/15b7a1b86d663ef40108b1ba322973e32d5b62d6/vfs.c/buggy/fs/nfsd/vfs.c