reiserfs_update_sd(&th, inode); 
mark_inode_dirty(inode); 
static ssize_t reiserfs_file_write(struct file *file,	/* the file we are going to write into */				   const char __user * buf,	/*  pointer to user supplied data								   (in userspace) */				   size_t count,	/* amount of bytes to write */				   loff_t * ppos	/* pointer to position in file that we start writing at. Should be updated to							 * new current position before returning. */				   ){	size_t already_written = 0;	// Number of bytes already written to the file.	loff_t pos;		// Current position in the file.	ssize_t res;		// return value of various functions that we call.	int err = 0;	struct inode *inode = file->f_dentry->d_inode;	// Inode of the file that we are writing to.	/* To simplify coding at this time, we store	   locked pages in array for now */	struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];	struct reiserfs_transaction_handle th;	th.t_trans_id = 0;	if (file->f_flags & O_DIRECT) {	// Direct IO needs treatment		ssize_t result, after_file_end = 0;		if ((*ppos + count >= inode->i_size)		    || (file->f_flags & O_APPEND)) {			/* If we are appending a file, we need to put this savelink in here.			   If we will crash while doing direct io, finish_unfinished will			   cut the garbage from the file end. */			reiserfs_write_lock(inode->i_sb);			err =			    journal_begin(&th, inode->i_sb,					  JOURNAL_PER_BALANCE_CNT);			if (err) {				reiserfs_write_unlock(inode->i_sb);				return err;			}			reiserfs_update_inode_transaction(inode);			add_save_link(&th, inode, 1 /* Truncate */ );			after_file_end = 1;			err =			    journal_end(&th, inode->i_sb,					JOURNAL_PER_BALANCE_CNT);			reiserfs_write_unlock(inode->i_sb);			if (err)				return err;		}		result = generic_file_write(file, buf, count, ppos);		if (after_file_end) {	/* Now update i_size and remove the savelink */			struct reiserfs_transaction_handle th;			reiserfs_write_lock(inode->i_sb);			err = journal_begin(&th, inode->i_sb, 1);			if (err) {				reiserfs_write_unlock(inode->i_sb);				return err;			}			reiserfs_update_inode_transaction(inode);			reiserfs_update_sd(&th, inode);			err = journal_end(&th, inode->i_sb, 1);			if (err) {				reiserfs_write_unlock(inode->i_sb);				return err;			}			err = remove_save_link(inode, 1 /* truncate */ );			reiserfs_write_unlock(inode->i_sb);			if (err)				return err;		}		return result;	}	if (unlikely((ssize_t) count < 0))		return -EINVAL;	if (unlikely(!access_ok(VERIFY_READ, buf, count)))		return -EFAULT;	down(&inode->i_sem);	// locks the entire file for just us	pos = *ppos;	/* Check if we can write to specified region of file, file	   is not overly big and this kind of stuff. Adjust pos and	   count, if needed */	res = generic_write_checks(file, &pos, &count, 0);	if (res)		goto out;	if (count == 0)		goto out;	res = remove_suid(file->f_dentry);	if (res)		goto out;	inode_update_time(inode, 1);	/* Both mtime and ctime */	// Ok, we are done with all the checks.	// Now we should start real work	/* If we are going to write past the file's packed tail or if we are going	   to overwrite part of the tail, we need that tail to be converted into	   unformatted node */	res = reiserfs_check_for_tail_and_convert(inode, pos, count);	if (res)		goto out;	while (count > 0) {		/* This is the main loop in which we running until some error occures		   or until we write all of the data. */		size_t num_pages;	/* amount of pages we are going to write this iteration */		size_t write_bytes;	/* amount of bytes to write during this iteration */		size_t blocks_to_allocate;	/* how much blocks we need to allocate for this iteration */		/*  (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos */		num_pages = !!((pos + count) & (PAGE_CACHE_SIZE - 1)) +	/* round up partial									   pages */		    ((count +		      (pos & (PAGE_CACHE_SIZE - 1))) >> PAGE_CACHE_SHIFT);		/* convert size to amount of		   pages */		reiserfs_write_lock(inode->i_sb);		if (num_pages > REISERFS_WRITE_PAGES_AT_A_TIME		    || num_pages > reiserfs_can_fit_pages(inode->i_sb)) {			/* If we were asked to write more data than we want to or if there			   is not that much space, then we shorten amount of data to write			   for this iteration. */			num_pages =			    min_t(size_t, REISERFS_WRITE_PAGES_AT_A_TIME,				  reiserfs_can_fit_pages(inode->i_sb));			/* Also we should not forget to set size in bytes accordingly */			write_bytes = (num_pages << PAGE_CACHE_SHIFT) -			    (pos & (PAGE_CACHE_SIZE - 1));			/* If position is not on the			   start of the page, we need			   to substract the offset			   within page */		} else			write_bytes = count;		/* reserve the blocks to be allocated later, so that later on		   we still have the space to write the blocks to */		reiserfs_claim_blocks_to_be_allocated(inode->i_sb,						      num_pages <<						      (PAGE_CACHE_SHIFT -						       inode->i_blkbits));		reiserfs_write_unlock(inode->i_sb);		if (!num_pages) {	/* If we do not have enough space even for a single page... */			if (pos >			    inode->i_size + inode->i_sb->s_blocksize -			    (pos & (inode->i_sb->s_blocksize - 1))) {				res = -ENOSPC;				break;	// In case we are writing past the end of the last file block, break.			}			// Otherwise we are possibly overwriting the file, so			// let's set write size to be equal or less than blocksize.			// This way we get it correctly for file holes.			// But overwriting files on absolutelly full volumes would not			// be very efficient. Well, people are not supposed to fill			// 100% of disk space anyway.			write_bytes =			    min_t(size_t, count,				  inode->i_sb->s_blocksize -				  (pos & (inode->i_sb->s_blocksize - 1)));			num_pages = 1;			// No blocks were claimed before, so do it now.			reiserfs_claim_blocks_to_be_allocated(inode->i_sb,							      1 <<							      (PAGE_CACHE_SHIFT							       -							       inode->							       i_blkbits));		}		/* Prepare for writing into the region, read in all the		   partially overwritten pages, if needed. And lock the pages,		   so that nobody else can access these until we are done.		   We get number of actual blocks needed as a result. */		blocks_to_allocate =		    reiserfs_prepare_file_region_for_write(inode, pos,							   num_pages,							   write_bytes,							   prepared_pages);		if (blocks_to_allocate < 0) {			res = blocks_to_allocate;			reiserfs_release_claimed_blocks(inode->i_sb,							num_pages <<							(PAGE_CACHE_SHIFT -							 inode->i_blkbits));			break;		}		/* First we correct our estimate of how many blocks we need */		reiserfs_release_claimed_blocks(inode->i_sb,						(num_pages <<						 (PAGE_CACHE_SHIFT -						  inode->i_sb->						  s_blocksize_bits)) -						blocks_to_allocate);		if (blocks_to_allocate > 0) {	/*We only allocate blocks if we need to */			/* Fill in all the possible holes and append the file if needed */			res =			    reiserfs_allocate_blocks_for_region(&th, inode, pos,								num_pages,								write_bytes,								prepared_pages,								blocks_to_allocate);		}		/* well, we have allocated the blocks, so it is time to free		   the reservation we made earlier. */		reiserfs_release_claimed_blocks(inode->i_sb,						blocks_to_allocate);		if (res) {			reiserfs_unprepare_pages(prepared_pages, num_pages);			break;		}/* NOTE that allocating blocks and filling blocks can be done in reverse order   and probably we would do that just to get rid of garbage in files after a   crash */		/* Copy data from user-supplied buffer to file's pages */		res =		    reiserfs_copy_from_user_to_file_region(pos, num_pages,							   write_bytes,							   prepared_pages, buf);		if (res) {			reiserfs_unprepare_pages(prepared_pages, num_pages);			break;		}		/* Send the pages to disk and unlock them. */		res =		    reiserfs_submit_file_region_for_write(&th, inode, pos,							  num_pages,							  write_bytes,							  prepared_pages);		if (res)			break;		already_written += write_bytes;		buf += write_bytes;		*ppos = pos += write_bytes;		count -= write_bytes;		balance_dirty_pages_ratelimited(inode->i_mapping);	}	/* this is only true on error */	if (th.t_trans_id) {		reiserfs_write_lock(inode->i_sb);		err = journal_end(&th, th.t_super, th.t_blocks_allocated);		reiserfs_write_unlock(inode->i_sb);		if (err) {			res = err;			goto out;		}	}	if ((file->f_flags & O_SYNC) || IS_SYNC(inode))		res =		    generic_osync_inode(inode, file->f_mapping,					OSYNC_METADATA | OSYNC_DATA);	up(&inode->i_sem);	reiserfs_async_progress_wait(inode->i_sb);	return (already_written != 0) ? already_written : res;      out:	up(&inode->i_sem);	// unlock the file on exit.	return res;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/9f03783ce5d851e4b98dfaf3e9eb177870f6c75d/file.c/clean/fs/reiserfs/file.c