[PATCH] LFS RLIMIT_FSIZE (in blocks)

From: Jakub Jelinek (jakub@redhat.com)
Date: Wed Feb 09 2000 - 02:30:27 EST


Hi!

This changes internal meaning of RLIMIT_SIZE from maximum file size in bytes
to maximum size in blocks (= 512B) and keeps binary compatibility on the
setrlimit/getrlimit calls. Like this, glibc can implement LFS
getrlimit64/setrlimit64 on top of the normal getrlimit/setrlimit system call
and allow users to set up limits up to 2TB (on i386) for maximum file size
below RLIM_INFINITY while keeping rlim_t 32bit in the kernel for 32bit
archs.
glibc is expected to use RLIMIT_FBSIZE internally in [gs]etrlimit64 to work
with RLIMIT_FSIZE resource.

--- linux/fs/minix/inode.c.jj Tue Jan 11 03:15:58 2000
+++ linux/fs/minix/inode.c Wed Feb 9 08:16:34 2000
@@ -521,8 +521,7 @@ repeat:
         {
                 unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
                 if (limit < RLIM_INFINITY) {
- limit >>= BLOCK_SIZE_BITS;
- if (new_block >= limit) {
+ if (new_block >= (limit >> 1)) {
                                 send_sig(SIGXFSZ, current, 0);
                                 *err = -EFBIG;
                                 return NULL;
@@ -604,8 +603,7 @@ repeat:
 
         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
         if (limit < RLIM_INFINITY) {
- limit >>= BLOCK_SIZE_BITS;
- if (new_block >= limit) {
+ if (new_block >= (limit >> 1)) {
                         send_sig(SIGXFSZ, current, 0);
                         goto out;
                 }
@@ -757,8 +755,7 @@ repeat:
         {
                 unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
                 if (limit < RLIM_INFINITY) {
- limit >>= BLOCK_SIZE_BITS;
- if (new_block >= limit) {
+ if (new_block >= (limit >> 1)) {
                                 send_sig(SIGXFSZ, current, 0);
                                 *err = -EFBIG;
                                 return NULL;
@@ -840,8 +837,7 @@ repeat:
 
         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
         if (limit < RLIM_INFINITY) {
- limit >>= BLOCK_SIZE_BITS;
- if (new_block >= limit) {
+ if (new_block >= (limit >> 1)) {
                         send_sig(SIGXFSZ, current, 0);
                         goto out;
                 }
--- linux/fs/ext2/inode.c.jj Thu Jan 20 19:48:35 2000
+++ linux/fs/ext2/inode.c Wed Feb 9 08:16:34 2000
@@ -219,7 +219,7 @@ repeat:
         {
                 unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
                 if (limit < RLIM_INFINITY) {
- limit >>= EXT2_BLOCK_SIZE_BITS(inode->i_sb);
+ limit >>= EXT2_BLOCK_SIZE_BITS(inode->i_sb) - 9;
                         if (new_block >= limit) {
                                 send_sig(SIGXFSZ, current, 0);
                                 *err = -EFBIG;
@@ -342,7 +342,7 @@ repeat:
 
         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
         if (limit < RLIM_INFINITY) {
- limit >>= EXT2_BLOCK_SIZE_BITS(inode->i_sb);
+ limit >>= EXT2_BLOCK_SIZE_BITS(inode->i_sb) - 9;
                 if (new_block >= limit) {
                         send_sig(SIGXFSZ, current, 0);
                         goto out;
--- linux/fs/sysv/inode.c.jj Tue Jan 11 03:15:58 2000
+++ linux/fs/sysv/inode.c Wed Feb 9 08:16:34 2000
@@ -711,7 +711,7 @@ repeat:
         {
                 unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
                 if (limit < RLIM_INFINITY) {
- limit >>= sb->sv_block_size_bits;
+ limit >>= sb->sv_block_size_bits - 9;
                         if (new_block >= limit) {
                                 send_sig(SIGXFSZ, current, 0);
                                 *err = -EFBIG;
@@ -795,7 +795,7 @@ repeat:
 
         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
         if (limit < RLIM_INFINITY) {
- limit >>= sb->sv_block_size_bits;
+ limit >>= sb->sv_block_size_bits - 9;
                 if (new_block >= limit) {
                         send_sig(SIGXFSZ, current, 0);
                         goto out;
--- linux/fs/ufs/inode.c.jj Tue Jan 11 03:15:58 2000
+++ linux/fs/ufs/inode.c Wed Feb 9 08:16:34 2000
@@ -224,7 +224,7 @@ repeat:
 
         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
         if (limit < RLIM_INFINITY) {
- limit >>= sb->s_blocksize_bits;
+ limit >>= sb->s_blocksize_bits - 9;
                 if (new_fragment >= limit) {
                         send_sig(SIGXFSZ, current, 0);
                         return NULL;
@@ -352,7 +352,7 @@ repeat:
         {
                 unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
                 if (limit < RLIM_INFINITY) {
- limit >>= sb->s_blocksize_bits;
+ limit >>= sb->s_blocksize_bits - 9;
                         if (new_fragment >= limit) {
                                 brelse (bh);
                                 send_sig(SIGXFSZ, current, 0);
--- linux/fs/udf/inode.c.jj Tue Jan 25 20:19:04 2000
+++ linux/fs/udf/inode.c Wed Feb 9 08:16:34 2000
@@ -457,7 +457,7 @@ static struct buffer_head * inode_getblk
                 unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
                 if (limit < RLIM_INFINITY)
                 {
- limit >>= inode->i_sb->s_blocksize_bits;
+ limit >>= inode->i_sb->s_blocksize_bits - 9;
                         if (block >= limit)
                         {
                                 send_sig(SIGXFSZ, current, 0);
--- linux/kernel/sys.c.jj Wed Feb 9 08:03:40 2000
+++ linux/kernel/sys.c Wed Feb 9 08:16:34 2000
@@ -894,10 +894,23 @@ asmlinkage long sys_setdomainname(char *
 
 asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim)
 {
- if (resource >= RLIM_NLIMITS)
+ struct rlimit x;
+ if (resource == RLIMIT_FSIZE) {
+ x = current->rlim[resource];
+ if (x.rlim_cur > (RLIM_INFINITY >> 9))
+ x.rlim_cur = RLIM_INFINITY;
+ else
+ x.rlim_cur <<= 9;
+ if (x.rlim_max > (RLIM_INFINITY >> 9))
+ x.rlim_max = RLIM_INFINITY;
+ else
+ x.rlim_max <<= 9;
+ return copy_to_user(rlim, &x, sizeof(x)) ? -EFAULT : 0;
+ }
+ if (resource >= RLIM_NLIMITS && resource != RLIMIT_FBSIZE)
                 return -EINVAL;
         else
- return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim))
+ return copy_to_user(rlim, current->rlim + (resource & RLIMIT_MASK), sizeof(*rlim))
                         ? -EFAULT : 0;
 }
 
@@ -910,10 +923,23 @@ asmlinkage long sys_getrlimit(unsigned i
 asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim)
 {
         struct rlimit x;
- if (resource >= RLIM_NLIMITS)
+
+ if (resource == RLIMIT_FSIZE) {
+ x = current->rlim[resource];
+ if (x.rlim_cur > (0x7FFFFFFF >> 9))
+ x.rlim_cur = 0x7FFFFFFF;
+ else
+ x.rlim_cur <<= 9;
+ if (x.rlim_max > (0x7FFFFFFF >> 9))
+ x.rlim_max = 0x7FFFFFFF;
+ else
+ x.rlim_max <<= 9;
+ return copy_to_user(rlim, &x, sizeof(x)) ? -EFAULT : 0;
+ }
+ if (resource >= RLIM_NLIMITS && resource != RLIMIT_FBSIZE)
                 return -EINVAL;
 
- memcpy(&x, current->rlim + resource, sizeof(*rlim));
+ x = current->rlim[resource & RLIMIT_MASK];
         if(x.rlim_cur > 0x7FFFFFFF)
                 x.rlim_cur = 0x7FFFFFFF;
         if(x.rlim_max > 0x7FFFFFFF)
@@ -927,13 +953,17 @@ asmlinkage long sys_setrlimit(unsigned i
 {
         struct rlimit new_rlim, *old_rlim;
 
- if (resource >= RLIM_NLIMITS)
+ if (resource >= RLIM_NLIMITS && resource != RLIMIT_FBSIZE)
                 return -EINVAL;
         if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
                 return -EFAULT;
- if (new_rlim.rlim_cur < 0 || new_rlim.rlim_max < 0)
- return -EINVAL;
- old_rlim = current->rlim + resource;
+ old_rlim = current->rlim + (resource & RLIMIT_MASK);
+ if (resource == RLIMIT_FSIZE) {
+ if (new_rlim.rlim_cur != RLIM_INFINITY)
+ new_rlim.rlim_cur = (new_rlim.rlim_cur + 511) >> 9;
+ if (new_rlim.rlim_max != RLIM_INFINITY)
+ new_rlim.rlim_max = (new_rlim.rlim_max + 511) >> 9;
+ }
         if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
              (new_rlim.rlim_max > old_rlim->rlim_max)) &&
             !capable(CAP_SYS_RESOURCE))
--- linux/mm/filemap.c.jj Wed Feb 9 08:03:40 2000
+++ linux/mm/filemap.c Wed Feb 9 08:16:34 2000
@@ -1839,7 +1839,7 @@ generic_file_write(struct file *file, co
 {
         struct dentry *dentry = file->f_dentry;
         struct inode *inode = dentry->d_inode;
- unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+ unsigned long long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
         loff_t pos;
         struct page *page, *cached_page;
         unsigned long written;
@@ -1871,6 +1871,7 @@ generic_file_write(struct file *file, co
          */
         err = -EFBIG;
         if (limit != RLIM_INFINITY) {
+ limit <<= 9;
                 if (pos >= limit) {
                         send_sig(SIGXFSZ, current, 0);
                         goto out;
--- linux/include/asm-i386/resource.h.jj Thu Dec 9 22:29:05 1999
+++ linux/include/asm-i386/resource.h Wed Feb 9 08:16:34 2000
@@ -15,6 +15,10 @@
 #define RLIMIT_NOFILE 7 /* max number of open files */
 #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
 #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
--- linux/include/asm-mips/resource.h.jj Thu Dec 9 22:29:06 1999
+++ linux/include/asm-mips/resource.h Wed Feb 9 08:16:34 2000
@@ -22,6 +22,10 @@
 #define RLIMIT_RSS 7 /* max resident set size */
 #define RLIMIT_NPROC 8 /* max number of processes */
 #define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10 /* Number of limit flavors. */
 
--- linux/include/asm-alpha/resource.h.jj Thu Dec 9 22:29:05 1999
+++ linux/include/asm-alpha/resource.h Wed Feb 9 08:16:34 2000
@@ -15,6 +15,10 @@
 #define RLIMIT_AS 7 /* address space limit(?) */
 #define RLIMIT_NPROC 8 /* max number of processes */
 #define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
--- linux/include/asm-m68k/resource.h.jj Thu Dec 9 22:29:06 1999
+++ linux/include/asm-m68k/resource.h Wed Feb 9 08:16:34 2000
@@ -15,6 +15,10 @@
 #define RLIMIT_NOFILE 7 /* max number of open files */
 #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space*/
 #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
--- linux/include/asm-sparc/resource.h.jj Tue Dec 21 07:05:52 1999
+++ linux/include/asm-sparc/resource.h Wed Feb 9 08:16:34 2000
@@ -21,6 +21,10 @@
 #define RLIMIT_NPROC 7 /* max number of processes */
 #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
 #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
@@ -29,7 +33,7 @@
  * We make this unsigned, but keep the
  * old value.
  */
-#define RLIM_INFINITY 0x7fffffff
+#define RLIM_INFINITY 0x7fffffffU
 
 #ifdef __KERNEL__
 #define INIT_RLIMITS \
--- linux/include/asm-ppc/resource.h.jj Thu Dec 9 22:29:06 1999
+++ linux/include/asm-ppc/resource.h Wed Feb 9 08:16:34 2000
@@ -11,6 +11,10 @@
 #define RLIMIT_NOFILE 7 /* max number of open files */
 #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
 #define RLIMIT_AS 9 /* address space limit(?) */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
--- linux/include/asm-sparc64/resource.h.jj Tue Dec 21 07:05:52 1999
+++ linux/include/asm-sparc64/resource.h Wed Feb 9 08:16:34 2000
@@ -21,6 +21,10 @@
 #define RLIMIT_NPROC 7 /* max number of processes */
 #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
 #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
--- linux/include/asm-arm/resource.h.jj Thu Dec 9 22:29:05 1999
+++ linux/include/asm-arm/resource.h Wed Feb 9 08:16:34 2000
@@ -15,6 +15,10 @@
 #define RLIMIT_NOFILE 7 /* max number of open files */
 #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
 #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
--- linux/include/asm-sh/resource.h.jj Thu Dec 9 22:29:06 1999
+++ linux/include/asm-sh/resource.h Wed Feb 9 08:16:34 2000
@@ -15,6 +15,10 @@
 #define RLIMIT_NOFILE 7 /* max number of open files */
 #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
 #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_FBSIZE 0x101 /* Maximum filesize in blocks */
+#ifdef __KERNEL__
+#define RLIMIT_MASK 0xff
+#endif
 
 #define RLIM_NLIMITS 10
 
--- linux/arch/sparc64/kernel/sys_sparc32.c.jj Wed Feb 9 08:07:36 2000
+++ linux/arch/sparc64/kernel/sys_sparc32.c Wed Feb 9 08:16:34 2000
@@ -2201,7 +2201,7 @@ asmlinkage long sys32_times(struct tms32
         return ret;
 }
 
-#define RLIM_INFINITY32 0x7fffffff
+#define RLIM_INFINITY32 0x7fffffffU
 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
 struct rlimit32 {
@@ -2235,7 +2235,8 @@ asmlinkage int sys32_setrlimit(unsigned
         int ret;
         mm_segment_t old_fs = get_fs ();
 
- if (resource >= RLIM_NLIMITS) return -EINVAL;
+ if (resource >= RLIM_NLIMITS && resource != RLIMIT_FBSIZE)
+ return -EINVAL;
         if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
             __get_user (r.rlim_max, &rlim->rlim_max))
                 return -EFAULT;

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.43 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________

-
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/



This archive was generated by hypermail 2b29 : Tue Feb 15 2000 - 21:00:14 EST