kernels/linux-2.6.24/mm/filemap.c
/*
 * Performs necessary checks before doing a write
 *
 * Can adjust writing position or amount of bytes to write.
 * Returns appropriate error code that caller should return or
 * zero in case that write should be allowed.
 */
Performs necessary checks before doing a write
Can adjust writing position or amount of bytes to write.
Returns appropriate error code that caller should return or
zero in case that write should be allowed.
Performs necessary checks before doing a write Can adjust writing position or amount of bytes to write . Returns appropriate error code that caller should return or zero in case that write should be allowed .
inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk)
{
	struct inode *inode = file->f_mapping->host;
	unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
        if (unlikely(*pos < 0))
                return -EINVAL;
	if (!isblk) {
		if (file->f_flags & O_APPEND)
                        *pos = i_size_read(inode);
		if (limit != RLIM_INFINITY) {
			if (*pos >= limit) {
				send_sig(SIGXFSZ, current, 0);
				return -EFBIG;
			}
			if (*count > limit - (typeof(limit))*pos) {
				*count = limit - (typeof(limit))*pos;
			}
		}
	}
	if (unlikely(*pos + *count > MAX_NON_LFS &&
				!(file->f_flags & O_LARGEFILE))) {
		if (*pos >= MAX_NON_LFS) {
			return -EFBIG;
		}
		if (*count > MAX_NON_LFS - (unsigned long)*pos) {
			*count = MAX_NON_LFS - (unsigned long)*pos;
		}
	}
	if (likely(!isblk)) {
		if (unlikely(*pos >= inode->i_sb->s_maxbytes)) {
			if (*count || *pos > inode->i_sb->s_maxbytes) {
				return -EFBIG;
			}
		}
		if (unlikely(*pos + *count > inode->i_sb->s_maxbytes))
			*count = inode->i_sb->s_maxbytes - *pos;
	} else {
#ifdef CONFIG_BLOCK
		loff_t isize;
		if (bdev_read_only(I_BDEV(inode)))
			return -EPERM;
		isize = i_size_read(inode);
		if (*pos >= isize) {
			if (*count || *pos > isize)
				return -ENOSPC;
		}
		if (*pos + *count > isize)
			*count = isize - *pos;
#else
		return -EPERM;
#endif
	}
	return 0;
}
inline int generic_write_checks ( struct file * file , loff_t * pos , size_t * count , int isblk ) { struct inode * inode = file -> f_mapping -> host ; unsigned long limit = current -> signal -> rlim [ RLIMIT_FSIZE ] . rlim_cur ; if ( unlikely ( * pos < 0 ) ) return - EINVAL ; if ( ! isblk ) { if ( file -> f_flags & O_APPEND ) * pos = i_size_read ( inode ) ; if ( limit != RLIM_INFINITY ) { if ( * pos >= limit ) { send_sig ( SIGXFSZ , current , 0 ) ; return - EFBIG ; } if ( * count > limit - ( typeof ( limit ) ) * pos ) { * count = limit - ( typeof ( limit ) ) * pos ; } } } if ( unlikely ( * pos + * count > MAX_NON_LFS && ! ( file -> f_flags & O_LARGEFILE ) ) ) { if ( * pos >= MAX_NON_LFS ) { return - EFBIG ; } if ( * count > MAX_NON_LFS - ( unsigned long ) * pos ) { * count = MAX_NON_LFS - ( unsigned long ) * pos ; } } if ( likely ( ! isblk ) ) { if ( unlikely ( * pos >= inode -> i_sb -> s_maxbytes ) ) { if ( * count || * pos > inode -> i_sb -> s_maxbytes ) { return - EFBIG ; } } if ( unlikely ( * pos + * count > inode -> i_sb -> s_maxbytes ) ) * count = inode -> i_sb -> s_maxbytes - * pos ; } else { #ifdef CONFIG_BLOCK loff_t isize ; if ( bdev_read_only ( I_BDEV ( inode ) ) ) return - EPERM ; isize = i_size_read ( inode ) ; if ( * pos >= isize ) { if ( * count || * pos > isize ) return - ENOSPC ; } if ( * pos + * count > isize ) * count = isize - * pos ; #else return - EPERM ; #endif } return 0 ; }
Performs necessary checks before doing a write
 Can adjust writing position or amount of bytes to write.
Performs necessary checks before doing a write Can adjust writing position or amount of bytes to write .
/* FIXME: this is for backwards compatibility with 2.4 */ /*
	 * LFS rule
	 */ /*
	 * Are we about to exceed the fs block limit ?
	 *
	 * If we have written data it becomes a short write.  If we have
	 * exceeded without writing data we send a signal and return EFBIG.
	 * Linus frestrict idea will clean these up nicely..
	 */ /* zero-length writes at ->s_maxbytes are OK */