patch for NFS file size limits

Bill Hawes (whawes@transmeta.com)
Sat, 17 Oct 1998 10:06:32 -0700


This is a multi-part message in MIME format.
--------------FA34C7739FC5C98854FA2A5D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

The attached patch adds a check for the process filesize limit
(RLIMIT_FSIZE) for NFS (and SMBFS as well, as it uses the
generic_file_write routine.)

The limit check allows the filesize to grow to the specified limit, and
delivers the SIGXFSZ signal if all or part of the write is past the
limit. The return value is -EFBIG if no bytes could be written;
otherwise the partial write length is returned.

The patch has been reasonably well tested here and appears to be working
OK.

Regards,
Bill

--------------FA34C7739FC5C98854FA2A5D
Content-Type: text/plain; charset=us-ascii; name="nfs_file125-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="nfs_file125-patch"

--- linux-2.1.125/fs/nfs/file.c.old Wed Aug 26 13:20:32 1998
+++ linux-2.1.125/fs/nfs/file.c Fri Oct 9 08:15:43 1998
@@ -169,6 +169,7 @@
return status;
}

+
/*
* Write to a file (through the page cache).
*/
@@ -179,14 +180,10 @@
struct inode * inode = dentry->d_inode;
ssize_t result;

- dfprintk(VFS, "nfs: write(%s/%s (%d), %lu@%lu)\n",
+ dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
- inode->i_count, (unsigned long) count, (unsigned long) *ppos);
+ inode->i_ino, (unsigned long) count, (unsigned long) *ppos);

- if (!inode) {
- printk("nfs_file_write: inode = NULL\n");
- return -EINVAL;
- }
result = -EBUSY;
if (IS_SWAPFILE(inode))
goto out_swapfile;
@@ -194,14 +191,6 @@
if (result)
goto out;

-#ifdef NFS_PARANOIA
-/* N.B. This should be impossible now -- inodes can't change mode */
-if (!S_ISREG(inode->i_mode)) {
- printk("nfs_file_write: write to non-file, mode %07o\n",
- inode->i_mode);
- return -EINVAL;
-}
-#endif
result = count;
if (!count)
goto out;
@@ -214,7 +203,7 @@
return result;

out_swapfile:
- printk(KERN_ERR "NFS: attempt to write to active swap file!\n");
+ printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
goto out;
}

--- linux-2.1.125/mm/filemap.c.old Wed Aug 19 21:23:21 1998
+++ linux-2.1.125/mm/filemap.c Tue Oct 13 17:30:43 1998
@@ -1519,24 +1519,42 @@
{
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode;
+ unsigned long pos = *ppos;
+ unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
struct page *page, **hash;
unsigned long page_cache = 0;
unsigned long pgpos, offset;
unsigned long bytes, written;
- unsigned long pos;
long status, sync, didread;

if (!inode->i_op || !inode->i_op->updatepage)
return -EIO;

sync = file->f_flags & O_SYNC;
- pos = *ppos;
written = 0;
- status = 0;

if (file->f_flags & O_APPEND)
pos = inode->i_size;

+ /*
+ * Check whether we've reached the file size limit.
+ */
+ status = -EFBIG;
+ if (pos >= limit) {
+ send_sig(SIGXFSZ, current, 0);
+ goto out;
+ }
+
+ status = 0;
+ /*
+ * Check whether to truncate the write,
+ * and send the signal if we do.
+ */
+ if (count > limit - pos) {
+ send_sig(SIGXFSZ, current, 0);
+ count = limit - pos;
+ }
+
while (count) {
/*
* Try to find the page in the cache. If it isn't there,
@@ -1621,6 +1639,7 @@

if (page_cache)
free_page(page_cache);
+out:
return written ? written : status;
}

--------------FA34C7739FC5C98854FA2A5D--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/