[PATCH] tmpfs 1/4 symlink unwind

From: Hugh Dickins (hugh@veritas.com)
Date: Tue Jun 11 2002 - 21:51:58 EST


shmem_symlink error path forgot to unwind. The failed symlink left
over could be unlinked, but long ones were left on the shmem_inodes
list, causing oops in swapoff at shutdown if not earlier.

--- 2.4.19-pre10/mm/shmem.c Tue Jun 4 13:54:20 2002
+++ linux/mm/shmem.c Tue Jun 11 19:02:30 2002
@@ -1123,17 +1123,20 @@
                 return error;
 
         len = strlen(symname) + 1;
- if (len > PAGE_CACHE_SIZE)
- return -ENAMETOOLONG;
-
         inode = dentry->d_inode;
         info = SHMEM_I(inode);
         inode->i_size = len-1;
+ inode->i_op = &shmem_symlink_inline_operations;
+
         if (len <= sizeof(struct shmem_inode_info)) {
                 /* do it inline */
                 memcpy(info, symname, len);
- inode->i_op = &shmem_symlink_inline_operations;
         } else {
+ if (len > PAGE_CACHE_SIZE) {
+ error = -ENAMETOOLONG;
+ goto rmnod;
+ }
+ inode->i_op = &shmem_symlink_inode_operations;
                 spin_lock (&shmem_ilock);
                 list_add (&info->list, &shmem_inodes);
                 spin_unlock (&shmem_ilock);
@@ -1141,7 +1144,8 @@
                 page = shmem_getpage_locked(info, inode, 0);
                 if (IS_ERR(page)) {
                         up(&info->sem);
- return PTR_ERR(page);
+ error = PTR_ERR(page);
+ goto rmnod;
                 }
                 kaddr = kmap(page);
                 memcpy(kaddr, symname, len);
@@ -1150,10 +1154,14 @@
                 UnlockPage(page);
                 page_cache_release(page);
                 up(&info->sem);
- inode->i_op = &shmem_symlink_inode_operations;
         }
         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
         return 0;
+
+rmnod:
+ if (!shmem_unlink(dir, dentry))
+ d_delete(dentry);
+ return error;
 }
 
 static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)

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



This archive was generated by hypermail 2b29 : Sat Jun 15 2002 - 22:00:24 EST