aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/affs/affs.h4
-rw-r--r--fs/affs/file.c25
-rw-r--r--fs/affs/inode.c34
-rw-r--r--fs/affs/namei.c6
-rw-r--r--fs/affs/super.c18
-rw-r--r--fs/bio.c3
-rw-r--r--fs/inode.c5
-rw-r--r--fs/locks.c17
-rw-r--r--fs/pipe.c21
-rw-r--r--fs/proc/task_mmu.c2
-rw-r--r--fs/proc/task_nommu.c1
-rw-r--r--fs/splice.c31
-rw-r--r--fs/udf/namei.c145
-rw-r--r--fs/udf/partition.c4
-rw-r--r--fs/udf/super.c1
-rw-r--r--fs/udf/udfdecl.h1
16 files changed, 239 insertions, 79 deletions
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index d5bd497ab9cb..223b1917093e 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -48,7 +48,7 @@ struct affs_ext_key {
48 * affs fs inode data in memory 48 * affs fs inode data in memory
49 */ 49 */
50struct affs_inode_info { 50struct affs_inode_info {
51 u32 i_opencnt; 51 atomic_t i_opencnt;
52 struct semaphore i_link_lock; /* Protects internal inode access. */ 52 struct semaphore i_link_lock; /* Protects internal inode access. */
53 struct semaphore i_ext_lock; /* Protects internal inode access. */ 53 struct semaphore i_ext_lock; /* Protects internal inode access. */
54#define i_hash_lock i_ext_lock 54#define i_hash_lock i_ext_lock
@@ -170,8 +170,6 @@ extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry,
170extern unsigned long affs_parent_ino(struct inode *dir); 170extern unsigned long affs_parent_ino(struct inode *dir);
171extern struct inode *affs_new_inode(struct inode *dir); 171extern struct inode *affs_new_inode(struct inode *dir);
172extern int affs_notify_change(struct dentry *dentry, struct iattr *attr); 172extern int affs_notify_change(struct dentry *dentry, struct iattr *attr);
173extern void affs_put_inode(struct inode *inode);
174extern void affs_drop_inode(struct inode *inode);
175extern void affs_delete_inode(struct inode *inode); 173extern void affs_delete_inode(struct inode *inode);
176extern void affs_clear_inode(struct inode *inode); 174extern void affs_clear_inode(struct inode *inode);
177extern struct inode *affs_iget(struct super_block *sb, 175extern struct inode *affs_iget(struct super_block *sb,
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 1a4f092f24ef..6eac7bdeec94 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -48,8 +48,9 @@ affs_file_open(struct inode *inode, struct file *filp)
48{ 48{
49 if (atomic_read(&filp->f_count) != 1) 49 if (atomic_read(&filp->f_count) != 1)
50 return 0; 50 return 0;
51 pr_debug("AFFS: open(%d)\n", AFFS_I(inode)->i_opencnt); 51 pr_debug("AFFS: open(%lu,%d)\n",
52 AFFS_I(inode)->i_opencnt++; 52 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
53 atomic_inc(&AFFS_I(inode)->i_opencnt);
53 return 0; 54 return 0;
54} 55}
55 56
@@ -58,10 +59,16 @@ affs_file_release(struct inode *inode, struct file *filp)
58{ 59{
59 if (atomic_read(&filp->f_count) != 0) 60 if (atomic_read(&filp->f_count) != 0)
60 return 0; 61 return 0;
61 pr_debug("AFFS: release(%d)\n", AFFS_I(inode)->i_opencnt); 62 pr_debug("AFFS: release(%lu, %d)\n",
62 AFFS_I(inode)->i_opencnt--; 63 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
63 if (!AFFS_I(inode)->i_opencnt) 64
65 if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) {
66 mutex_lock(&inode->i_mutex);
67 if (inode->i_size != AFFS_I(inode)->mmu_private)
68 affs_truncate(inode);
64 affs_free_prealloc(inode); 69 affs_free_prealloc(inode);
70 mutex_unlock(&inode->i_mutex);
71 }
65 72
66 return 0; 73 return 0;
67} 74}
@@ -180,7 +187,7 @@ affs_get_extblock(struct inode *inode, u32 ext)
180 /* inline the simplest case: same extended block as last time */ 187 /* inline the simplest case: same extended block as last time */
181 struct buffer_head *bh = AFFS_I(inode)->i_ext_bh; 188 struct buffer_head *bh = AFFS_I(inode)->i_ext_bh;
182 if (ext == AFFS_I(inode)->i_ext_last) 189 if (ext == AFFS_I(inode)->i_ext_last)
183 atomic_inc(&bh->b_count); 190 get_bh(bh);
184 else 191 else
185 /* we have to do more (not inlined) */ 192 /* we have to do more (not inlined) */
186 bh = affs_get_extblock_slow(inode, ext); 193 bh = affs_get_extblock_slow(inode, ext);
@@ -306,7 +313,7 @@ store_ext:
306 affs_brelse(AFFS_I(inode)->i_ext_bh); 313 affs_brelse(AFFS_I(inode)->i_ext_bh);
307 AFFS_I(inode)->i_ext_last = ext; 314 AFFS_I(inode)->i_ext_last = ext;
308 AFFS_I(inode)->i_ext_bh = bh; 315 AFFS_I(inode)->i_ext_bh = bh;
309 atomic_inc(&bh->b_count); 316 get_bh(bh);
310 317
311 return bh; 318 return bh;
312 319
@@ -324,7 +331,6 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
324 331
325 pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block); 332 pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block);
326 333
327
328 BUG_ON(block > (sector_t)0x7fffffffUL); 334 BUG_ON(block > (sector_t)0x7fffffffUL);
329 335
330 if (block >= AFFS_I(inode)->i_blkcnt) { 336 if (block >= AFFS_I(inode)->i_blkcnt) {
@@ -827,6 +833,8 @@ affs_truncate(struct inode *inode)
827 res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata); 833 res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
828 if (!res) 834 if (!res)
829 res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata); 835 res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
836 else
837 inode->i_size = AFFS_I(inode)->mmu_private;
830 mark_inode_dirty(inode); 838 mark_inode_dirty(inode);
831 return; 839 return;
832 } else if (inode->i_size == AFFS_I(inode)->mmu_private) 840 } else if (inode->i_size == AFFS_I(inode)->mmu_private)
@@ -862,6 +870,7 @@ affs_truncate(struct inode *inode)
862 blk++; 870 blk++;
863 } else 871 } else
864 AFFS_HEAD(ext_bh)->first_data = 0; 872 AFFS_HEAD(ext_bh)->first_data = 0;
873 AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i);
865 size = AFFS_SB(sb)->s_hashsize; 874 size = AFFS_SB(sb)->s_hashsize;
866 if (size > blkcnt - blk + i) 875 if (size > blkcnt - blk + i)
867 size = blkcnt - blk + i; 876 size = blkcnt - blk + i;
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 27fe6cbe43ae..a13b334a3910 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -58,7 +58,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
58 AFFS_I(inode)->i_extcnt = 1; 58 AFFS_I(inode)->i_extcnt = 1;
59 AFFS_I(inode)->i_ext_last = ~1; 59 AFFS_I(inode)->i_ext_last = ~1;
60 AFFS_I(inode)->i_protect = prot; 60 AFFS_I(inode)->i_protect = prot;
61 AFFS_I(inode)->i_opencnt = 0; 61 atomic_set(&AFFS_I(inode)->i_opencnt, 0);
62 AFFS_I(inode)->i_blkcnt = 0; 62 AFFS_I(inode)->i_blkcnt = 0;
63 AFFS_I(inode)->i_lc = NULL; 63 AFFS_I(inode)->i_lc = NULL;
64 AFFS_I(inode)->i_lc_size = 0; 64 AFFS_I(inode)->i_lc_size = 0;
@@ -108,8 +108,6 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
108 inode->i_mode |= S_IFDIR; 108 inode->i_mode |= S_IFDIR;
109 } else 109 } else
110 inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR; 110 inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
111 if (tail->link_chain)
112 inode->i_nlink = 2;
113 /* Maybe it should be controlled by mount parameter? */ 111 /* Maybe it should be controlled by mount parameter? */
114 //inode->i_mode |= S_ISVTX; 112 //inode->i_mode |= S_ISVTX;
115 inode->i_op = &affs_dir_inode_operations; 113 inode->i_op = &affs_dir_inode_operations;
@@ -245,31 +243,12 @@ out:
245} 243}
246 244
247void 245void
248affs_put_inode(struct inode *inode)
249{
250 pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
251 affs_free_prealloc(inode);
252}
253
254void
255affs_drop_inode(struct inode *inode)
256{
257 mutex_lock(&inode->i_mutex);
258 if (inode->i_size != AFFS_I(inode)->mmu_private)
259 affs_truncate(inode);
260 mutex_unlock(&inode->i_mutex);
261
262 generic_drop_inode(inode);
263}
264
265void
266affs_delete_inode(struct inode *inode) 246affs_delete_inode(struct inode *inode)
267{ 247{
268 pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); 248 pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
269 truncate_inode_pages(&inode->i_data, 0); 249 truncate_inode_pages(&inode->i_data, 0);
270 inode->i_size = 0; 250 inode->i_size = 0;
271 if (S_ISREG(inode->i_mode)) 251 affs_truncate(inode);
272 affs_truncate(inode);
273 clear_inode(inode); 252 clear_inode(inode);
274 affs_free_block(inode->i_sb, inode->i_ino); 253 affs_free_block(inode->i_sb, inode->i_ino);
275} 254}
@@ -277,9 +256,12 @@ affs_delete_inode(struct inode *inode)
277void 256void
278affs_clear_inode(struct inode *inode) 257affs_clear_inode(struct inode *inode)
279{ 258{
280 unsigned long cache_page = (unsigned long) AFFS_I(inode)->i_lc; 259 unsigned long cache_page;
281 260
282 pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); 261 pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
262
263 affs_free_prealloc(inode);
264 cache_page = (unsigned long)AFFS_I(inode)->i_lc;
283 if (cache_page) { 265 if (cache_page) {
284 pr_debug("AFFS: freeing ext cache\n"); 266 pr_debug("AFFS: freeing ext cache\n");
285 AFFS_I(inode)->i_lc = NULL; 267 AFFS_I(inode)->i_lc = NULL;
@@ -316,7 +298,7 @@ affs_new_inode(struct inode *dir)
316 inode->i_ino = block; 298 inode->i_ino = block;
317 inode->i_nlink = 1; 299 inode->i_nlink = 1;
318 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; 300 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
319 AFFS_I(inode)->i_opencnt = 0; 301 atomic_set(&AFFS_I(inode)->i_opencnt, 0);
320 AFFS_I(inode)->i_blkcnt = 0; 302 AFFS_I(inode)->i_blkcnt = 0;
321 AFFS_I(inode)->i_lc = NULL; 303 AFFS_I(inode)->i_lc = NULL;
322 AFFS_I(inode)->i_lc_size = 0; 304 AFFS_I(inode)->i_lc_size = 0;
@@ -369,12 +351,12 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
369 switch (type) { 351 switch (type) {
370 case ST_LINKFILE: 352 case ST_LINKFILE:
371 case ST_LINKDIR: 353 case ST_LINKDIR:
372 inode_bh = bh;
373 retval = -ENOSPC; 354 retval = -ENOSPC;
374 block = affs_alloc_block(dir, dir->i_ino); 355 block = affs_alloc_block(dir, dir->i_ino);
375 if (!block) 356 if (!block)
376 goto err; 357 goto err;
377 retval = -EIO; 358 retval = -EIO;
359 inode_bh = bh;
378 bh = affs_getzeroblk(sb, block); 360 bh = affs_getzeroblk(sb, block);
379 if (!bh) 361 if (!bh)
380 goto err; 362 goto err;
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 2218f1ee71ce..cfcf1b6cf82b 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -234,7 +234,8 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
234int 234int
235affs_unlink(struct inode *dir, struct dentry *dentry) 235affs_unlink(struct inode *dir, struct dentry *dentry)
236{ 236{
237 pr_debug("AFFS: unlink(dir=%d, \"%.*s\")\n", (u32)dir->i_ino, 237 pr_debug("AFFS: unlink(dir=%d, %lu \"%.*s\")\n", (u32)dir->i_ino,
238 dentry->d_inode->i_ino,
238 (int)dentry->d_name.len, dentry->d_name.name); 239 (int)dentry->d_name.len, dentry->d_name.name);
239 240
240 return affs_remove_header(dentry); 241 return affs_remove_header(dentry);
@@ -302,7 +303,8 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
302int 303int
303affs_rmdir(struct inode *dir, struct dentry *dentry) 304affs_rmdir(struct inode *dir, struct dentry *dentry)
304{ 305{
305 pr_debug("AFFS: rmdir(dir=%u, \"%.*s\")\n", (u32)dir->i_ino, 306 pr_debug("AFFS: rmdir(dir=%u, %lu \"%.*s\")\n", (u32)dir->i_ino,
307 dentry->d_inode->i_ino,
306 (int)dentry->d_name.len, dentry->d_name.name); 308 (int)dentry->d_name.len, dentry->d_name.name);
307 309
308 return affs_remove_header(dentry); 310 return affs_remove_header(dentry);
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 01d25d532541..d214837d5e42 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -71,12 +71,18 @@ static struct kmem_cache * affs_inode_cachep;
71 71
72static struct inode *affs_alloc_inode(struct super_block *sb) 72static struct inode *affs_alloc_inode(struct super_block *sb)
73{ 73{
74 struct affs_inode_info *ei; 74 struct affs_inode_info *i;
75 ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); 75
76 if (!ei) 76 i = kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL);
77 if (!i)
77 return NULL; 78 return NULL;
78 ei->vfs_inode.i_version = 1; 79
79 return &ei->vfs_inode; 80 i->vfs_inode.i_version = 1;
81 i->i_lc = NULL;
82 i->i_ext_bh = NULL;
83 i->i_pa_cnt = 0;
84
85 return &i->vfs_inode;
80} 86}
81 87
82static void affs_destroy_inode(struct inode *inode) 88static void affs_destroy_inode(struct inode *inode)
@@ -114,8 +120,6 @@ static const struct super_operations affs_sops = {
114 .alloc_inode = affs_alloc_inode, 120 .alloc_inode = affs_alloc_inode,
115 .destroy_inode = affs_destroy_inode, 121 .destroy_inode = affs_destroy_inode,
116 .write_inode = affs_write_inode, 122 .write_inode = affs_write_inode,
117 .put_inode = affs_put_inode,
118 .drop_inode = affs_drop_inode,
119 .delete_inode = affs_delete_inode, 123 .delete_inode = affs_delete_inode,
120 .clear_inode = affs_clear_inode, 124 .clear_inode = affs_clear_inode,
121 .put_super = affs_put_super, 125 .put_super = affs_put_super,
diff --git a/fs/bio.c b/fs/bio.c
index 799f86deff24..78562574cb52 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -158,7 +158,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
158 158
159 bio_init(bio); 159 bio_init(bio);
160 if (likely(nr_iovecs)) { 160 if (likely(nr_iovecs)) {
161 unsigned long idx = 0; /* shut up gcc */ 161 unsigned long uninitialized_var(idx);
162 162
163 bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs); 163 bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
164 if (unlikely(!bvl)) { 164 if (unlikely(!bvl)) {
@@ -963,6 +963,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
963 * @data: pointer to buffer to copy 963 * @data: pointer to buffer to copy
964 * @len: length in bytes 964 * @len: length in bytes
965 * @gfp_mask: allocation flags for bio and page allocation 965 * @gfp_mask: allocation flags for bio and page allocation
966 * @reading: data direction is READ
966 * 967 *
967 * copy the kernel address into a bio suitable for io to a block 968 * copy the kernel address into a bio suitable for io to a block
968 * device. Returns an error pointer in case of error. 969 * device. Returns an error pointer in case of error.
diff --git a/fs/inode.c b/fs/inode.c
index bf6478130424..c36d9480335c 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1149,13 +1149,8 @@ static inline void iput_final(struct inode *inode)
1149void iput(struct inode *inode) 1149void iput(struct inode *inode)
1150{ 1150{
1151 if (inode) { 1151 if (inode) {
1152 const struct super_operations *op = inode->i_sb->s_op;
1153
1154 BUG_ON(inode->i_state == I_CLEAR); 1152 BUG_ON(inode->i_state == I_CLEAR);
1155 1153
1156 if (op && op->put_inode)
1157 op->put_inode(inode);
1158
1159 if (atomic_dec_and_lock(&inode->i_count, &inode_lock)) 1154 if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
1160 iput_final(inode); 1155 iput_final(inode);
1161 } 1156 }
diff --git a/fs/locks.c b/fs/locks.c
index 663c069b59b3..0ac6b92cb0b6 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1753,6 +1753,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
1753 struct file_lock *file_lock = locks_alloc_lock(); 1753 struct file_lock *file_lock = locks_alloc_lock();
1754 struct flock flock; 1754 struct flock flock;
1755 struct inode *inode; 1755 struct inode *inode;
1756 struct file *f;
1756 int error; 1757 int error;
1757 1758
1758 if (file_lock == NULL) 1759 if (file_lock == NULL)
@@ -1825,7 +1826,15 @@ again:
1825 * Attempt to detect a close/fcntl race and recover by 1826 * Attempt to detect a close/fcntl race and recover by
1826 * releasing the lock that was just acquired. 1827 * releasing the lock that was just acquired.
1827 */ 1828 */
1828 if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { 1829 /*
1830 * we need that spin_lock here - it prevents reordering between
1831 * update of inode->i_flock and check for it done in close().
1832 * rcu_read_lock() wouldn't do.
1833 */
1834 spin_lock(&current->files->file_lock);
1835 f = fcheck(fd);
1836 spin_unlock(&current->files->file_lock);
1837 if (!error && f != filp && flock.l_type != F_UNLCK) {
1829 flock.l_type = F_UNLCK; 1838 flock.l_type = F_UNLCK;
1830 goto again; 1839 goto again;
1831 } 1840 }
@@ -1881,6 +1890,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
1881 struct file_lock *file_lock = locks_alloc_lock(); 1890 struct file_lock *file_lock = locks_alloc_lock();
1882 struct flock64 flock; 1891 struct flock64 flock;
1883 struct inode *inode; 1892 struct inode *inode;
1893 struct file *f;
1884 int error; 1894 int error;
1885 1895
1886 if (file_lock == NULL) 1896 if (file_lock == NULL)
@@ -1953,7 +1963,10 @@ again:
1953 * Attempt to detect a close/fcntl race and recover by 1963 * Attempt to detect a close/fcntl race and recover by
1954 * releasing the lock that was just acquired. 1964 * releasing the lock that was just acquired.
1955 */ 1965 */
1956 if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { 1966 spin_lock(&current->files->file_lock);
1967 f = fcheck(fd);
1968 spin_unlock(&current->files->file_lock);
1969 if (!error && f != filp && flock.l_type != F_UNLCK) {
1957 flock.l_type = F_UNLCK; 1970 flock.l_type = F_UNLCK;
1958 goto again; 1971 goto again;
1959 } 1972 }
diff --git a/fs/pipe.c b/fs/pipe.c
index f73492b6817e..ec228bc9f882 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -17,6 +17,7 @@
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <linux/pagemap.h> 18#include <linux/pagemap.h>
19#include <linux/audit.h> 19#include <linux/audit.h>
20#include <linux/syscalls.h>
20 21
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include <asm/ioctls.h> 23#include <asm/ioctls.h>
@@ -1076,6 +1077,26 @@ int do_pipe(int *fd)
1076} 1077}
1077 1078
1078/* 1079/*
1080 * sys_pipe() is the normal C calling standard for creating
1081 * a pipe. It's not the way Unix traditionally does this, though.
1082 */
1083asmlinkage long __weak sys_pipe(int __user *fildes)
1084{
1085 int fd[2];
1086 int error;
1087
1088 error = do_pipe(fd);
1089 if (!error) {
1090 if (copy_to_user(fildes, fd, sizeof(fd))) {
1091 sys_close(fd[0]);
1092 sys_close(fd[1]);
1093 error = -EFAULT;
1094 }
1095 }
1096 return error;
1097}
1098
1099/*
1079 * pipefs should _never_ be mounted by userland - too much of security hassle, 1100 * pipefs should _never_ be mounted by userland - too much of security hassle,
1080 * no real gain from having the whole whorehouse mounted. So we don't need 1101 * no real gain from having the whole whorehouse mounted. So we don't need
1081 * any operations on the root directory. However, we need a non-trivial 1102 * any operations on the root directory. However, we need a non-trivial
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index e2b8e769f510..88717c0f941b 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -5,11 +5,9 @@
5#include <linux/highmem.h> 5#include <linux/highmem.h>
6#include <linux/ptrace.h> 6#include <linux/ptrace.h>
7#include <linux/pagemap.h> 7#include <linux/pagemap.h>
8#include <linux/ptrace.h>
9#include <linux/mempolicy.h> 8#include <linux/mempolicy.h>
10#include <linux/swap.h> 9#include <linux/swap.h>
11#include <linux/swapops.h> 10#include <linux/swapops.h>
12#include <linux/seq_file.h>
13 11
14#include <asm/elf.h> 12#include <asm/elf.h>
15#include <asm/uaccess.h> 13#include <asm/uaccess.h>
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 4b733f108455..4b4f9cc2f186 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -1,6 +1,7 @@
1 1
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/file.h> 3#include <linux/file.h>
4#include <linux/fdtable.h>
4#include <linux/mount.h> 5#include <linux/mount.h>
5#include <linux/ptrace.h> 6#include <linux/ptrace.h>
6#include <linux/seq_file.h> 7#include <linux/seq_file.h>
diff --git a/fs/splice.c b/fs/splice.c
index 633f58ebfb72..78150038b584 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -811,24 +811,19 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
811{ 811{
812 struct address_space *mapping = out->f_mapping; 812 struct address_space *mapping = out->f_mapping;
813 struct inode *inode = mapping->host; 813 struct inode *inode = mapping->host;
814 int killsuid, killpriv; 814 struct splice_desc sd = {
815 .total_len = len,
816 .flags = flags,
817 .pos = *ppos,
818 .u.file = out,
819 };
815 ssize_t ret; 820 ssize_t ret;
816 int err = 0;
817
818 killpriv = security_inode_need_killpriv(out->f_path.dentry);
819 killsuid = should_remove_suid(out->f_path.dentry);
820 if (unlikely(killsuid || killpriv)) {
821 mutex_lock(&inode->i_mutex);
822 if (killpriv)
823 err = security_inode_killpriv(out->f_path.dentry);
824 if (!err && killsuid)
825 err = __remove_suid(out->f_path.dentry, killsuid);
826 mutex_unlock(&inode->i_mutex);
827 if (err)
828 return err;
829 }
830 821
831 ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); 822 inode_double_lock(inode, pipe->inode);
823 ret = remove_suid(out->f_path.dentry);
824 if (likely(!ret))
825 ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
826 inode_double_unlock(inode, pipe->inode);
832 if (ret > 0) { 827 if (ret > 0) {
833 unsigned long nr_pages; 828 unsigned long nr_pages;
834 829
@@ -840,6 +835,8 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
840 * sync it. 835 * sync it.
841 */ 836 */
842 if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { 837 if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
838 int err;
839
843 mutex_lock(&inode->i_mutex); 840 mutex_lock(&inode->i_mutex);
844 err = generic_osync_inode(inode, mapping, 841 err = generic_osync_inode(inode, mapping,
845 OSYNC_METADATA|OSYNC_DATA); 842 OSYNC_METADATA|OSYNC_DATA);
@@ -1075,7 +1072,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1075 1072
1076 ret = splice_direct_to_actor(in, &sd, direct_splice_actor); 1073 ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
1077 if (ret > 0) 1074 if (ret > 0)
1078 *ppos = sd.pos; 1075 *ppos += ret;
1079 1076
1080 return ret; 1077 return ret;
1081} 1078}
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 2b34c8ca6c83..d3231947db19 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -32,6 +32,7 @@
32#include <linux/buffer_head.h> 32#include <linux/buffer_head.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/crc-itu-t.h> 34#include <linux/crc-itu-t.h>
35#include <linux/exportfs.h>
35 36
36static inline int udf_match(int len1, const char *name1, int len2, 37static inline int udf_match(int len1, const char *name1, int len2,
37 const char *name2) 38 const char *name2)
@@ -158,6 +159,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
158 sector_t offset; 159 sector_t offset;
159 struct extent_position epos = {}; 160 struct extent_position epos = {};
160 struct udf_inode_info *dinfo = UDF_I(dir); 161 struct udf_inode_info *dinfo = UDF_I(dir);
162 int isdotdot = dentry->d_name.len == 2 &&
163 dentry->d_name.name[0] == '.' && dentry->d_name.name[1] == '.';
161 164
162 size = udf_ext0_offset(dir) + dir->i_size; 165 size = udf_ext0_offset(dir) + dir->i_size;
163 f_pos = udf_ext0_offset(dir); 166 f_pos = udf_ext0_offset(dir);
@@ -225,6 +228,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
225 continue; 228 continue;
226 } 229 }
227 230
231 if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) &&
232 isdotdot) {
233 brelse(epos.bh);
234 return fi;
235 }
236
228 if (!lfi) 237 if (!lfi)
229 continue; 238 continue;
230 239
@@ -286,9 +295,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
286 } 295 }
287 } 296 }
288 unlock_kernel(); 297 unlock_kernel();
289 d_add(dentry, inode);
290 298
291 return NULL; 299 return d_splice_alias(inode, dentry);
292} 300}
293 301
294static struct fileIdentDesc *udf_add_entry(struct inode *dir, 302static struct fileIdentDesc *udf_add_entry(struct inode *dir,
@@ -307,7 +315,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
307 uint16_t liu; 315 uint16_t liu;
308 int block; 316 int block;
309 kernel_lb_addr eloc; 317 kernel_lb_addr eloc;
310 uint32_t elen; 318 uint32_t elen = 0;
311 sector_t offset; 319 sector_t offset;
312 struct extent_position epos = {}; 320 struct extent_position epos = {};
313 struct udf_inode_info *dinfo; 321 struct udf_inode_info *dinfo;
@@ -398,7 +406,8 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
398 } 406 }
399 407
400add: 408add:
401 if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { 409 /* Is there any extent whose size we need to round up? */
410 if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) {
402 elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); 411 elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
403 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 412 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
404 epos.offset -= sizeof(short_ad); 413 epos.offset -= sizeof(short_ad);
@@ -1232,6 +1241,134 @@ end_rename:
1232 return retval; 1241 return retval;
1233} 1242}
1234 1243
1244static struct dentry *udf_get_parent(struct dentry *child)
1245{
1246 struct dentry *parent;
1247 struct inode *inode = NULL;
1248 struct dentry dotdot;
1249 struct fileIdentDesc cfi;
1250 struct udf_fileident_bh fibh;
1251
1252 dotdot.d_name.name = "..";
1253 dotdot.d_name.len = 2;
1254
1255 lock_kernel();
1256 if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi))
1257 goto out_unlock;
1258
1259 if (fibh.sbh != fibh.ebh)
1260 brelse(fibh.ebh);
1261 brelse(fibh.sbh);
1262
1263 inode = udf_iget(child->d_inode->i_sb,
1264 lelb_to_cpu(cfi.icb.extLocation));
1265 if (!inode)
1266 goto out_unlock;
1267 unlock_kernel();
1268
1269 parent = d_alloc_anon(inode);
1270 if (!parent) {
1271 iput(inode);
1272 parent = ERR_PTR(-ENOMEM);
1273 }
1274
1275 return parent;
1276out_unlock:
1277 unlock_kernel();
1278 return ERR_PTR(-EACCES);
1279}
1280
1281
1282static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
1283 u16 partref, __u32 generation)
1284{
1285 struct inode *inode;
1286 struct dentry *result;
1287 kernel_lb_addr loc;
1288
1289 if (block == 0)
1290 return ERR_PTR(-ESTALE);
1291
1292 loc.logicalBlockNum = block;
1293 loc.partitionReferenceNum = partref;
1294 inode = udf_iget(sb, loc);
1295
1296 if (inode == NULL)
1297 return ERR_PTR(-ENOMEM);
1298
1299 if (generation && inode->i_generation != generation) {
1300 iput(inode);
1301 return ERR_PTR(-ESTALE);
1302 }
1303 result = d_alloc_anon(inode);
1304 if (!result) {
1305 iput(inode);
1306 return ERR_PTR(-ENOMEM);
1307 }
1308 return result;
1309}
1310
1311static struct dentry *udf_fh_to_dentry(struct super_block *sb,
1312 struct fid *fid, int fh_len, int fh_type)
1313{
1314 if ((fh_len != 3 && fh_len != 5) ||
1315 (fh_type != FILEID_UDF_WITH_PARENT &&
1316 fh_type != FILEID_UDF_WITHOUT_PARENT))
1317 return NULL;
1318
1319 return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref,
1320 fid->udf.generation);
1321}
1322
1323static struct dentry *udf_fh_to_parent(struct super_block *sb,
1324 struct fid *fid, int fh_len, int fh_type)
1325{
1326 if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT)
1327 return NULL;
1328
1329 return udf_nfs_get_inode(sb, fid->udf.parent_block,
1330 fid->udf.parent_partref,
1331 fid->udf.parent_generation);
1332}
1333static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
1334 int connectable)
1335{
1336 int len = *lenp;
1337 struct inode *inode = de->d_inode;
1338 kernel_lb_addr location = UDF_I(inode)->i_location;
1339 struct fid *fid = (struct fid *)fh;
1340 int type = FILEID_UDF_WITHOUT_PARENT;
1341
1342 if (len < 3 || (connectable && len < 5))
1343 return 255;
1344
1345 *lenp = 3;
1346 fid->udf.block = location.logicalBlockNum;
1347 fid->udf.partref = location.partitionReferenceNum;
1348 fid->udf.generation = inode->i_generation;
1349
1350 if (connectable && !S_ISDIR(inode->i_mode)) {
1351 spin_lock(&de->d_lock);
1352 inode = de->d_parent->d_inode;
1353 location = UDF_I(inode)->i_location;
1354 fid->udf.parent_block = location.logicalBlockNum;
1355 fid->udf.parent_partref = location.partitionReferenceNum;
1356 fid->udf.parent_generation = inode->i_generation;
1357 spin_unlock(&de->d_lock);
1358 *lenp = 5;
1359 type = FILEID_UDF_WITH_PARENT;
1360 }
1361
1362 return type;
1363}
1364
1365const struct export_operations udf_export_ops = {
1366 .encode_fh = udf_encode_fh,
1367 .fh_to_dentry = udf_fh_to_dentry,
1368 .fh_to_parent = udf_fh_to_parent,
1369 .get_parent = udf_get_parent,
1370};
1371
1235const struct inode_operations udf_dir_inode_operations = { 1372const struct inode_operations udf_dir_inode_operations = {
1236 .lookup = udf_lookup, 1373 .lookup = udf_lookup,
1237 .create = udf_create, 1374 .create = udf_create,
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 63610f026ae1..96dfd207c3d6 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -27,8 +27,8 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/buffer_head.h> 28#include <linux/buffer_head.h>
29 29
30inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, 30uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
31 uint16_t partition, uint32_t offset) 31 uint16_t partition, uint32_t offset)
32{ 32{
33 struct udf_sb_info *sbi = UDF_SB(sb); 33 struct udf_sb_info *sbi = UDF_SB(sb);
34 struct udf_part_map *map; 34 struct udf_part_map *map;
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 9fb18a340fc1..7a5f69be6ac2 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1933,6 +1933,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
1933 1933
1934 /* Fill in the rest of the superblock */ 1934 /* Fill in the rest of the superblock */
1935 sb->s_op = &udf_sb_ops; 1935 sb->s_op = &udf_sb_ops;
1936 sb->s_export_op = &udf_export_ops;
1936 sb->dq_op = NULL; 1937 sb->dq_op = NULL;
1937 sb->s_dirt = 0; 1938 sb->s_dirt = 0;
1938 sb->s_magic = UDF_SUPER_MAGIC; 1939 sb->s_magic = UDF_SUPER_MAGIC;
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index f3f45d029277..8fa9c2d70911 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -73,6 +73,7 @@ struct task_struct;
73struct buffer_head; 73struct buffer_head;
74struct super_block; 74struct super_block;
75 75
76extern const struct export_operations udf_export_ops;
76extern const struct inode_operations udf_dir_inode_operations; 77extern const struct inode_operations udf_dir_inode_operations;
77extern const struct file_operations udf_dir_operations; 78extern const struct file_operations udf_dir_operations;
78extern const struct inode_operations udf_file_inode_operations; 79extern const struct inode_operations udf_file_inode_operations;