public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Oleg Drokin <green@namesys.com>
To: mason@suse.com
Cc: szepe@pinerecords.com, linux-kernel@vger.kernel.org,
	reiserfs-dev@namesys.com
Subject: Re: [reiserfs-dev] Re: [PATCH] sparc32: wrong type of nlink_t
Date: Thu, 5 Sep 2002 17:57:11 +0400	[thread overview]
Message-ID: <20020905175711.B32687@namesys.com> (raw)
In-Reply-To: <20020905174902.A32687@namesys.com>

Hello!

On Thu, Sep 05, 2002 at 05:49:02PM +0400, Oleg Drokin wrote:

> > Ok, since I really like this approach, below is the patch (for 2.4) that
> > demonstrates my solution.
> > Also it correctly calculates maximal number given type may hold ( does not work
> > with unsigned long long, though) with my own way ;)
> Version that actually works is now here ;)

Heh, diffed against wrong tree :(
Corrected diff is here.

Also I trimmed CC list since I afraid Marcelo, DaveM adn jfs people are not very
interested in this reiserfs only patch.

Bye,
    Oleg

===== fs/reiserfs/inode.c 1.35 vs edited =====
--- 1.35/fs/reiserfs/inode.c	Fri Aug  9 19:22:33 2002
+++ edited/fs/reiserfs/inode.c	Thu Sep  5 13:43:26 2002
@@ -891,7 +891,8 @@
 	set_inode_item_key_version (inode, KEY_FORMAT_3_5);
         set_inode_sd_version (inode, STAT_DATA_V1);
 	inode->i_mode  = sd_v1_mode(sd);
-	inode->i_nlink = sd_v1_nlink(sd);
+	inode->i_nlink = ( sd_v1_nlink(sd) > REISERFS_LINK_MAX ) ? REISERFS_LINK_MAX:sd_v1_nlink(sd);
+	inode->u.reiserfs_i.i_nlink_real = sd_v1_nlink(sd);
 	inode->i_uid   = sd_v1_uid(sd);
 	inode->i_gid   = sd_v1_gid(sd);
 	inode->i_size  = sd_v1_size(sd);
@@ -923,7 +924,8 @@
 	struct stat_data * sd = (struct stat_data *)B_I_PITEM (bh, ih);
 
 	inode->i_mode   = sd_v2_mode(sd);
-	inode->i_nlink  = sd_v2_nlink(sd);
+	inode->i_nlink  = (sd_v2_nlink(sd)>REISERFS_LINK_MAX)?REISERFS_LINK_MAX:sd_v2_nlink(sd);
+	inode->u.reiserfs_i.i_nlink_real = sd_v2_nlink(sd);
 	inode->i_uid    = sd_v2_uid(sd);
 	inode->i_size   = sd_v2_size(sd);
 	inode->i_gid    = sd_v2_gid(sd);
@@ -975,7 +977,7 @@
     __u16 flags;
 
     set_sd_v2_mode(sd_v2, inode->i_mode );
-    set_sd_v2_nlink(sd_v2, inode->i_nlink );
+    set_sd_v2_nlink(sd_v2, inode->u.reiserfs_i.i_nlink_real );
     set_sd_v2_uid(sd_v2, inode->i_uid );
     set_sd_v2_size(sd_v2, inode->i_size );
     set_sd_v2_gid(sd_v2, inode->i_gid );
@@ -1001,7 +1003,7 @@
     set_sd_v1_mode(sd_v1, inode->i_mode );
     set_sd_v1_uid(sd_v1, inode->i_uid );
     set_sd_v1_gid(sd_v1, inode->i_gid );
-    set_sd_v1_nlink(sd_v1, inode->i_nlink );
+    set_sd_v1_nlink(sd_v1, inode->u.reiserfs_i.i_nlink_real );
     set_sd_v1_size(sd_v1, inode->i_size );
     set_sd_v1_atime(sd_v1, inode->i_atime );
     set_sd_v1_ctime(sd_v1, inode->i_ctime );
@@ -1537,7 +1539,7 @@
 
     /* fill stat data */
     inode->i_mode = mode;
-    inode->i_nlink = (S_ISDIR (mode) ? 2 : 1);
+    inode->u.reiserfs_i.i_nlink_real = inode->i_nlink = (S_ISDIR (mode) ? 2 : 1);
     inode->i_uid = current->fsuid;
     if (dir->i_mode & S_ISGID) {
 	inode->i_gid = dir->i_gid;
===== fs/reiserfs/namei.c 1.24 vs edited =====
--- 1.24/fs/reiserfs/namei.c	Fri Aug  9 19:22:33 2002
+++ edited/fs/reiserfs/namei.c	Thu Sep  5 16:33:04 2002
@@ -8,8 +8,16 @@
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
 
-#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
-#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
+#define INC_INODE_NLINK(i) { if (i->i_nlink < REISERFS_LINK_MAX) i->i_nlink++; i->u.reiserfs_i.i_nlink_real++; }
+#define DEC_INODE_NLINK(i) {if ( --i->u.reiserfs_i.i_nlink_real < REISERFS_LINK_MAX) i->i_nlink--;}
+
+// v3.5 files have 16bit nlink_t, v3.6 files have 32bit nlink_t.
+#define CAN_INCREASE_NLINK(i) ( i->u.reiserfs_i.i_nlink_real < ((get_inode_sd_version (i) != KEY_FORMAT_3_5)?MAX_UL_INT:MAX_US_INT)) 
+
+// Compatibility stuff with old trick that allowed to have lots of subdirs in
+// one dir. Such dirs had 1 as their nlink count.
+#define INC_DIR_INODE_NLINK(i) { if (i->i_nlink != 1) INC_INODE_NLINK(i);}
+#define DEC_DIR_INODE_NLINK(i) { if (i->i_nlink != 1) DEC_INODE_NLINK(i);}
 
 // directory item contains array of entry headers. This performs
 // binary search through that array
@@ -518,7 +526,7 @@
     retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 
 				inode, 1/*visible*/);
     if (retval) {
-	inode->i_nlink--;
+	DEC_INODE_NLINK(inode);
 	reiserfs_update_sd (&th, inode);
 	pop_journal_writer(windex) ;
 	// FIXME: should we put iput here and have stat data deleted
@@ -569,7 +577,7 @@
     retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 
 				 inode, 1/*visible*/);
     if (retval) {
-	inode->i_nlink--;
+	DEC_INODE_NLINK(inode);
 	reiserfs_update_sd (&th, inode);
 	pop_journal_writer(windex) ;
 	journal_end(&th, dir->i_sb, jbegin_count) ;
@@ -592,6 +600,9 @@
     struct reiserfs_transaction_handle th ;
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
 
+    if ( !CAN_INCREASE_NLINK(dir) )
+	return -EMLINK;
+
     if (!(inode = new_inode(dir->i_sb))) {
 	return -ENOMEM ;
     }
@@ -613,7 +624,7 @@
 				dentry, inode, &retval);
     if (!inode) {
 	pop_journal_writer(windex) ;
-	dir->i_nlink-- ;
+	DEC_DIR_INODE_NLINK(dir);
 	journal_end(&th, dir->i_sb, jbegin_count) ;
 	return retval;
     }
@@ -627,7 +638,7 @@
     retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 
 				inode, 1/*visible*/);
     if (retval) {
-	inode->i_nlink = 0;
+	inode->u.reiserfs_i.i_nlink_real = inode->i_nlink = 0;
 	DEC_DIR_INODE_NLINK(dir);
 	reiserfs_update_sd (&th, inode);
 	pop_journal_writer(windex) ;
@@ -711,7 +722,7 @@
     if ( inode->i_nlink != 2 && inode->i_nlink != 1 )
 	printk ("reiserfs_rmdir: empty directory has nlink != 2 (%d)\n", inode->i_nlink);
 
-    inode->i_nlink = 0;
+    inode->u.reiserfs_i.i_nlink_real = inode->i_nlink = 0;
     inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
     reiserfs_update_sd (&th, inode);
 
@@ -780,14 +791,14 @@
     if (!inode->i_nlink) {
 	printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
 	       kdevname(inode->i_dev), inode->i_ino, inode->i_nlink);
-	inode->i_nlink = 1;
+	inode->u.reiserfs_i.i_nlink_real = inode->i_nlink = 1;
     }
 
     retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, NULL, 0);
     if (retval < 0)
 	goto end_unlink;
 
-    inode->i_nlink--;
+    DEC_INODE_NLINK(inode);
     inode->i_ctime = CURRENT_TIME;
     reiserfs_update_sd (&th, inode);
 
@@ -868,7 +879,7 @@
     retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name, dentry->d_name.len, 
 				 inode, 1/*visible*/);
     if (retval) {
-	inode->i_nlink--;
+	DEC_INODE_NLINK(inode);
 	reiserfs_update_sd (&th, inode);
 	pop_journal_writer(windex) ;
 	journal_end(&th, parent_dir->i_sb, jbegin_count) ;
@@ -896,8 +907,7 @@
     if (S_ISDIR(inode->i_mode))
 	return -EPERM;
   
-    if (inode->i_nlink >= REISERFS_LINK_MAX) {
-	//FIXME: sd_nlink is 32 bit for new files
+    if (!CAN_INCREASE_NLINK(inode)) {
 	return -EMLINK;
     }
 
@@ -917,7 +927,7 @@
 	return retval;
     }
 
-    inode->i_nlink++;
+    INC_INODE_NLINK(inode);
     ctime = CURRENT_TIME;
     inode->i_ctime = ctime;
     reiserfs_update_sd (&th, inode);
@@ -1021,6 +1031,8 @@
 	// and that its new parent directory has not too many links
 	// already
 
+	if ( !CAN_INCREASE_NLINK(new_dir) )
+	    return -EMLINK;
 	if (new_dentry_inode) {
 	    if (!reiserfs_empty_dir(new_dentry_inode)) {
 		return -ENOTEMPTY;
@@ -1157,9 +1169,9 @@
     if (new_dentry_inode) {
 	// adjust link number of the victim
 	if (S_ISDIR(new_dentry_inode->i_mode)) {
-	    new_dentry_inode->i_nlink  = 0;
+	    new_dentry_inode->u.reiserfs_i.i_nlink_real = new_dentry_inode->i_nlink  = 0;
 	} else {
-	    new_dentry_inode->i_nlink--;
+	    DEC_INODE_NLINK(new_dentry_inode);
 	}
 	ctime = CURRENT_TIME;
 	new_dentry_inode->i_ctime = ctime;
===== include/linux/reiserfs_fs.h 1.22 vs edited =====
--- 1.22/include/linux/reiserfs_fs.h	Tue Aug 20 13:40:53 2002
+++ edited/include/linux/reiserfs_fs.h	Thu Sep  5 17:52:50 2002
@@ -1163,7 +1163,6 @@
 #define INODE_PKEY(inode) ((struct key *)((inode)->u.reiserfs_i.i_key))
 
 #define MAX_UL_INT 0xffffffff
-#define MAX_INT    0x7ffffff
 #define MAX_US_INT 0xffff
 
 // reiserfs version 2 has max offset 60 bits. Version 1 - 32 bit offset
@@ -1186,8 +1185,9 @@
 #define MAX_FC_NUM MAX_US_INT
 
 
-/* the purpose is to detect overflow of an unsigned short */
-#define REISERFS_LINK_MAX (MAX_US_INT - 1000)
+/* Find maximal number, that nlink_t can hold. GCC is able to calculate this
+   value at compile time, so do not worry about extra CPU overhead. */
+#define REISERFS_LINK_MAX (nlink_t)((((nlink_t) -1) > 0)?~0:((1u<<(sizeof(nlink_t)*8-1))-1))
 
 
 /* The following defines are used in reiserfs_insert_item and reiserfs_append_item  */
===== include/linux/reiserfs_fs_i.h 1.8 vs edited =====
--- 1.8/include/linux/reiserfs_fs_i.h	Fri Aug  9 19:22:34 2002
+++ edited/include/linux/reiserfs_fs_i.h	Thu Sep  5 13:41:01 2002
@@ -53,6 +53,8 @@
     ** flushed */
     unsigned long i_trans_id ;
     unsigned long i_trans_index ;
+    unsigned int i_nlink_real; /* We store real nlink number since field in
+				  struct inode is too short for us */
 };
 
 #endif

  reply	other threads:[~2002-09-05 13:52 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-09-01  8:55 [PATCH] sparc32: wrong type of nlink_t Tomas Szepe
2002-09-01  8:52 ` David S. Miller
2002-09-01  9:44   ` Tomas Szepe
2002-09-04 20:18     ` Dave Kleikamp
2002-09-04 20:29       ` [reiserfs-dev] " Chris Mason
2002-09-04 23:34         ` David S. Miller
2002-09-06  8:52           ` David Woodhouse
2002-09-04 20:31       ` Hans Reiser
2002-09-04 21:18         ` Tomas Szepe
2002-09-04 21:44           ` Thunder from the hill
2002-09-04 21:57             ` Thunder from the hill
2002-09-04 23:35         ` David S. Miller
2002-09-05  0:36           ` Hans Reiser
2002-09-05  0:32             ` David S. Miller
2002-09-05  0:49             ` Chris Mason
2002-09-05  5:40               ` Tomas Szepe
2002-09-05  5:36                 ` David S. Miller
2002-09-05  5:48                   ` Tomas Szepe
2002-09-05  5:45                     ` David S. Miller
2002-09-05  9:46                       ` Nikita Danilov
2002-09-05  5:56                     ` Oleg Drokin
2002-09-05  5:52                       ` David S. Miller
2002-09-05  6:07                         ` Oleg Drokin
2002-09-05  5:59                       ` Tomas Szepe
2002-09-05  9:54                   ` Oleg Drokin
2002-09-05 10:50                     ` David S. Miller
2002-09-05 13:49                     ` Oleg Drokin
2002-09-05 13:57                       ` Oleg Drokin [this message]
2002-09-05 14:03                       ` Chris Mason
2002-09-05 14:17                         ` Oleg Drokin
2002-09-05 16:45                           ` Chris Mason
2002-09-05 17:25                             ` Oleg Drokin
2002-09-05 21:18                               ` jw schultz
2002-09-05 22:02                                 ` Ragnar Kjørstad
2002-09-05 22:57                                   ` jw schultz
2002-09-06  0:01                                     ` Ragnar Kjørstad
2002-09-06  1:41                                       ` jw schultz
2002-09-06  2:29                                         ` Ragnar Kjørstad
2002-09-05 16:09                     ` Dave Kleikamp
2002-09-05 16:13                       ` Oleg Drokin
2002-09-05 17:58                         ` Dave Kleikamp
2002-09-06 13:54                           ` Oleg Drokin
2002-09-05 17:24                     ` Linus Torvalds
2002-09-04 23:33       ` David S. Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020905175711.B32687@namesys.com \
    --to=green@namesys.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mason@suse.com \
    --cc=reiserfs-dev@namesys.com \
    --cc=szepe@pinerecords.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox