diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 22:37:45 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 22:37:45 -0400 |
| commit | e8bebe2f71d26871b0970ae1d9cf0ed3cdd9569d (patch) | |
| tree | c0d82cbd11daaf579b74121c6641d58947091094 | |
| parent | 6109e2ce2600e2db26cd0424bb9c6ed019723288 (diff) | |
| parent | 82f3952c02add60b15eea9151d4d99b6b82066c6 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (69 commits)
fix handling of offsets in cris eeprom.c, get rid of fake on-stack files
get rid of home-grown mutex in cris eeprom.c
switch ecryptfs_write() to struct inode *, kill on-stack fake files
switch ecryptfs_get_locked_page() to struct inode *
simplify access to ecryptfs inodes in ->readpage() and friends
AFS: Don't put struct file on the stack
Ban ecryptfs over ecryptfs
logfs: replace inode uid,gid,mode initialization with helper function
ufs: replace inode uid,gid,mode initialization with helper function
udf: replace inode uid,gid,mode init with helper
ubifs: replace inode uid,gid,mode initialization with helper function
sysv: replace inode uid,gid,mode initialization with helper function
reiserfs: replace inode uid,gid,mode initialization with helper function
ramfs: replace inode uid,gid,mode initialization with helper function
omfs: replace inode uid,gid,mode initialization with helper function
bfs: replace inode uid,gid,mode initialization with helper function
ocfs2: replace inode uid,gid,mode initialization with helper function
nilfs2: replace inode uid,gid,mode initialization with helper function
minix: replace inode uid,gid,mode init with helper
ext4: replace inode uid,gid,mode init with helper
...
Trivial conflict in fs/fs-writeback.c (mark bitfields unsigned)
119 files changed, 907 insertions, 1294 deletions
diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index 1f2ae909d3e..c3405507a3d 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c | |||
| @@ -73,8 +73,7 @@ struct eeprom_type | |||
| 73 | int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */ | 73 | int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */ |
| 74 | 74 | ||
| 75 | /* this one is to keep the read/write operations atomic */ | 75 | /* this one is to keep the read/write operations atomic */ |
| 76 | wait_queue_head_t wait_q; | 76 | struct mutex lock; |
| 77 | volatile int busy; | ||
| 78 | int retry_cnt_addr; /* Used to keep track of number of retries for | 77 | int retry_cnt_addr; /* Used to keep track of number of retries for |
| 79 | adaptive timing adjustments */ | 78 | adaptive timing adjustments */ |
| 80 | int retry_cnt_read; | 79 | int retry_cnt_read; |
| @@ -115,8 +114,7 @@ const struct file_operations eeprom_fops = | |||
| 115 | 114 | ||
| 116 | int __init eeprom_init(void) | 115 | int __init eeprom_init(void) |
| 117 | { | 116 | { |
| 118 | init_waitqueue_head(&eeprom.wait_q); | 117 | mutex_init(&eeprom.lock); |
| 119 | eeprom.busy = 0; | ||
| 120 | 118 | ||
| 121 | #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE | 119 | #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE |
| 122 | #define EETEXT "Found" | 120 | #define EETEXT "Found" |
| @@ -439,10 +437,7 @@ static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig) | |||
| 439 | 437 | ||
| 440 | static int eeprom_read_buf(loff_t addr, char * buf, int count) | 438 | static int eeprom_read_buf(loff_t addr, char * buf, int count) |
| 441 | { | 439 | { |
| 442 | struct file f; | 440 | return eeprom_read(NULL, buf, count, &addr); |
| 443 | |||
| 444 | f.f_pos = addr; | ||
| 445 | return eeprom_read(&f, buf, count, &addr); | ||
| 446 | } | 441 | } |
| 447 | 442 | ||
| 448 | 443 | ||
| @@ -452,7 +447,7 @@ static int eeprom_read_buf(loff_t addr, char * buf, int count) | |||
| 452 | static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off) | 447 | static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off) |
| 453 | { | 448 | { |
| 454 | int read=0; | 449 | int read=0; |
| 455 | unsigned long p = file->f_pos; | 450 | unsigned long p = *off; |
| 456 | 451 | ||
| 457 | unsigned char page; | 452 | unsigned char page; |
| 458 | 453 | ||
| @@ -461,12 +456,9 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t | |||
| 461 | return -EFAULT; | 456 | return -EFAULT; |
| 462 | } | 457 | } |
| 463 | 458 | ||
| 464 | wait_event_interruptible(eeprom.wait_q, !eeprom.busy); | 459 | if (mutex_lock_interruptible(&eeprom.lock)) |
| 465 | if (signal_pending(current)) | ||
| 466 | return -EINTR; | 460 | return -EINTR; |
| 467 | 461 | ||
| 468 | eeprom.busy++; | ||
| 469 | |||
| 470 | page = (unsigned char) (p >> 8); | 462 | page = (unsigned char) (p >> 8); |
| 471 | 463 | ||
| 472 | if(!eeprom_address(p)) | 464 | if(!eeprom_address(p)) |
| @@ -476,8 +468,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t | |||
| 476 | i2c_stop(); | 468 | i2c_stop(); |
| 477 | 469 | ||
| 478 | /* don't forget to wake them up */ | 470 | /* don't forget to wake them up */ |
| 479 | eeprom.busy--; | 471 | mutex_unlock(&eeprom.lock); |
| 480 | wake_up_interruptible(&eeprom.wait_q); | ||
| 481 | return -EFAULT; | 472 | return -EFAULT; |
| 482 | } | 473 | } |
| 483 | 474 | ||
| @@ -501,11 +492,10 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t | |||
| 501 | 492 | ||
| 502 | if(read > 0) | 493 | if(read > 0) |
| 503 | { | 494 | { |
| 504 | file->f_pos += read; | 495 | *off += read; |
| 505 | } | 496 | } |
| 506 | 497 | ||
| 507 | eeprom.busy--; | 498 | mutex_unlock(&eeprom.lock); |
| 508 | wake_up_interruptible(&eeprom.wait_q); | ||
| 509 | return read; | 499 | return read; |
| 510 | } | 500 | } |
| 511 | 501 | ||
| @@ -513,11 +503,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t | |||
| 513 | 503 | ||
| 514 | static int eeprom_write_buf(loff_t addr, const char * buf, int count) | 504 | static int eeprom_write_buf(loff_t addr, const char * buf, int count) |
| 515 | { | 505 | { |
| 516 | struct file f; | 506 | return eeprom_write(NULL, buf, count, &addr); |
| 517 | |||
| 518 | f.f_pos = addr; | ||
| 519 | |||
| 520 | return eeprom_write(&f, buf, count, &addr); | ||
| 521 | } | 507 | } |
| 522 | 508 | ||
| 523 | 509 | ||
| @@ -534,16 +520,14 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, | |||
| 534 | return -EFAULT; | 520 | return -EFAULT; |
| 535 | } | 521 | } |
| 536 | 522 | ||
| 537 | wait_event_interruptible(eeprom.wait_q, !eeprom.busy); | ||
| 538 | /* bail out if we get interrupted */ | 523 | /* bail out if we get interrupted */ |
| 539 | if (signal_pending(current)) | 524 | if (mutex_lock_interruptible(&eeprom.lock)) |
| 540 | return -EINTR; | 525 | return -EINTR; |
| 541 | eeprom.busy++; | ||
| 542 | for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++) | 526 | for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++) |
| 543 | { | 527 | { |
| 544 | restart = 0; | 528 | restart = 0; |
| 545 | written = 0; | 529 | written = 0; |
| 546 | p = file->f_pos; | 530 | p = *off; |
| 547 | 531 | ||
| 548 | 532 | ||
| 549 | while( (written < count) && (p < eeprom.size)) | 533 | while( (written < count) && (p < eeprom.size)) |
| @@ -556,8 +540,7 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, | |||
| 556 | i2c_stop(); | 540 | i2c_stop(); |
| 557 | 541 | ||
| 558 | /* don't forget to wake them up */ | 542 | /* don't forget to wake them up */ |
| 559 | eeprom.busy--; | 543 | mutex_unlock(&eeprom.lock); |
| 560 | wake_up_interruptible(&eeprom.wait_q); | ||
| 561 | return -EFAULT; | 544 | return -EFAULT; |
| 562 | } | 545 | } |
| 563 | #ifdef EEPROM_ADAPTIVE_TIMING | 546 | #ifdef EEPROM_ADAPTIVE_TIMING |
| @@ -669,12 +652,11 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, | |||
| 669 | } /* while */ | 652 | } /* while */ |
| 670 | } /* for */ | 653 | } /* for */ |
| 671 | 654 | ||
| 672 | eeprom.busy--; | 655 | mutex_unlock(&eeprom.lock); |
| 673 | wake_up_interruptible(&eeprom.wait_q); | 656 | if (written == 0 && p >= eeprom.size){ |
| 674 | if (written == 0 && file->f_pos >= eeprom.size){ | ||
| 675 | return -ENOSPC; | 657 | return -ENOSPC; |
| 676 | } | 658 | } |
| 677 | file->f_pos += written; | 659 | *off = p; |
| 678 | return written; | 660 | return written; |
| 679 | } | 661 | } |
| 680 | 662 | ||
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a90e83c9be9..6120922f459 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
| @@ -485,7 +485,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
| 485 | goto out; | 485 | goto out; |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | ret = vfs_fsync(file, file->f_path.dentry, 0); | 488 | ret = vfs_fsync(file, 0); |
| 489 | if (unlikely(ret)) { | 489 | if (unlikely(ret)) { |
| 490 | ret = -EIO; | 490 | ret = -EIO; |
| 491 | goto out; | 491 | goto out; |
| @@ -495,7 +495,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
| 495 | ret = lo_send(lo, bio, pos); | 495 | ret = lo_send(lo, bio, pos); |
| 496 | 496 | ||
| 497 | if (barrier && !ret) { | 497 | if (barrier && !ret) { |
| 498 | ret = vfs_fsync(file, file->f_path.dentry, 0); | 498 | ret = vfs_fsync(file, 0); |
| 499 | if (unlikely(ret)) | 499 | if (unlikely(ret)) |
| 500 | ret = -EIO; | 500 | ret = -EIO; |
| 501 | } | 501 | } |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 23d1d54b12a..1742435ce3a 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -1699,7 +1699,7 @@ int bitmap_create(mddev_t *mddev) | |||
| 1699 | * and bypass the page cache, we must sync the file | 1699 | * and bypass the page cache, we must sync the file |
| 1700 | * first. | 1700 | * first. |
| 1701 | */ | 1701 | */ |
| 1702 | vfs_fsync(file, file->f_dentry, 1); | 1702 | vfs_fsync(file, 1); |
| 1703 | } | 1703 | } |
| 1704 | /* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */ | 1704 | /* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */ |
| 1705 | if (!mddev->bitmap_info.external) | 1705 | if (!mddev->bitmap_info.external) |
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 868d8ee8675..04c462ff0ea 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
| @@ -654,7 +654,7 @@ static int fsg_lun_fsync_sub(struct fsg_lun *curlun) | |||
| 654 | 654 | ||
| 655 | if (curlun->ro || !filp) | 655 | if (curlun->ro || !filp) |
| 656 | return 0; | 656 | return 0; |
| 657 | return vfs_fsync(filp, filp->f_path.dentry, 1); | 657 | return vfs_fsync(filp, 1); |
| 658 | } | 658 | } |
| 659 | 659 | ||
| 660 | static void store_cdrom_address(u8 *dest, int msf, u32 addr) | 660 | static void store_cdrom_address(u8 *dest, int msf, u32 addr) |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index f2434fc9d2c..6d4d86187c5 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -253,9 +253,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
| 253 | return ERR_PTR(-ENOMEM); | 253 | return ERR_PTR(-ENOMEM); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | inode->i_mode = mode; | 256 | inode_init_owner(inode, NULL, mode); |
| 257 | inode->i_uid = current_fsuid(); | ||
| 258 | inode->i_gid = current_fsgid(); | ||
| 259 | inode->i_blocks = 0; | 257 | inode->i_blocks = 0; |
| 260 | inode->i_rdev = 0; | 258 | inode->i_rdev = 0; |
| 261 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 259 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/Makefile b/fs/Makefile index 97f340f14ba..e6ec1d309b1 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
| @@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \ | |||
| 11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ | 11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ |
| 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ | 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ |
| 13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ | 13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ |
| 14 | stack.o fs_struct.o | 14 | stack.o fs_struct.o statfs.o |
| 15 | 15 | ||
| 16 | ifeq ($(CONFIG_BLOCK),y) | 16 | ifeq ($(CONFIG_BLOCK),y) |
| 17 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o | 17 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index adc1cb771b5..b42d5cc1d6d 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
| @@ -189,13 +189,9 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index, | |||
| 189 | struct key *key) | 189 | struct key *key) |
| 190 | { | 190 | { |
| 191 | struct page *page; | 191 | struct page *page; |
| 192 | struct file file = { | ||
| 193 | .private_data = key, | ||
| 194 | }; | ||
| 195 | |||
| 196 | _enter("{%lu},%lu", dir->i_ino, index); | 192 | _enter("{%lu},%lu", dir->i_ino, index); |
| 197 | 193 | ||
| 198 | page = read_mapping_page(dir->i_mapping, index, &file); | 194 | page = read_cache_page(dir->i_mapping, index, afs_page_filler, key); |
| 199 | if (!IS_ERR(page)) { | 195 | if (!IS_ERR(page)) { |
| 200 | kmap(page); | 196 | kmap(page); |
| 201 | if (!PageChecked(page)) | 197 | if (!PageChecked(page)) |
diff --git a/fs/afs/file.c b/fs/afs/file.c index 0df9bc2b724..14d89fa58fe 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
| @@ -121,34 +121,19 @@ static void afs_file_readpage_read_complete(struct page *page, | |||
| 121 | #endif | 121 | #endif |
| 122 | 122 | ||
| 123 | /* | 123 | /* |
| 124 | * AFS read page from file, directory or symlink | 124 | * read page from file, directory or symlink, given a key to use |
| 125 | */ | 125 | */ |
| 126 | static int afs_readpage(struct file *file, struct page *page) | 126 | int afs_page_filler(void *data, struct page *page) |
| 127 | { | 127 | { |
| 128 | struct afs_vnode *vnode; | 128 | struct inode *inode = page->mapping->host; |
| 129 | struct inode *inode; | 129 | struct afs_vnode *vnode = AFS_FS_I(inode); |
| 130 | struct key *key; | 130 | struct key *key = data; |
| 131 | size_t len; | 131 | size_t len; |
| 132 | off_t offset; | 132 | off_t offset; |
| 133 | int ret; | 133 | int ret; |
| 134 | 134 | ||
| 135 | inode = page->mapping->host; | ||
| 136 | |||
| 137 | if (file) { | ||
| 138 | key = file->private_data; | ||
| 139 | ASSERT(key != NULL); | ||
| 140 | } else { | ||
| 141 | key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); | ||
| 142 | if (IS_ERR(key)) { | ||
| 143 | ret = PTR_ERR(key); | ||
| 144 | goto error_nokey; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); | 135 | _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); |
| 149 | 136 | ||
| 150 | vnode = AFS_FS_I(inode); | ||
| 151 | |||
| 152 | BUG_ON(!PageLocked(page)); | 137 | BUG_ON(!PageLocked(page)); |
| 153 | 138 | ||
| 154 | ret = -ESTALE; | 139 | ret = -ESTALE; |
| @@ -214,31 +199,56 @@ static int afs_readpage(struct file *file, struct page *page) | |||
| 214 | unlock_page(page); | 199 | unlock_page(page); |
| 215 | } | 200 | } |
| 216 | 201 | ||
| 217 | if (!file) | ||
| 218 | key_put(key); | ||
| 219 | _leave(" = 0"); | 202 | _leave(" = 0"); |
| 220 | return 0; | 203 | return 0; |
| 221 | 204 | ||
| 222 | error: | 205 | error: |
| 223 | SetPageError(page); | 206 | SetPageError(page); |
| 224 | unlock_page(page); | 207 | unlock_page(page); |
| 225 | if (!file) | ||
| 226 | key_put(key); | ||
| 227 | error_nokey: | ||
| 228 | _leave(" = %d", ret); | 208 | _leave(" = %d", ret); |
| 229 | return ret; | 209 | return ret; |
| 230 | } | 210 | } |
| 231 | 211 | ||
| 232 | /* | 212 | /* |
| 213 | * read page from file, directory or symlink, given a file to nominate the key | ||
| 214 | * to be used | ||
| 215 | */ | ||
| 216 | static int afs_readpage(struct file *file, struct page *page) | ||
| 217 | { | ||
| 218 | struct key *key; | ||
| 219 | int ret; | ||
| 220 | |||
| 221 | if (file) { | ||
| 222 | key = file->private_data; | ||
| 223 | ASSERT(key != NULL); | ||
| 224 | ret = afs_page_filler(key, page); | ||
| 225 | } else { | ||
| 226 | struct inode *inode = page->mapping->host; | ||
| 227 | key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); | ||
| 228 | if (IS_ERR(key)) { | ||
| 229 | ret = PTR_ERR(key); | ||
| 230 | } else { | ||
| 231 | ret = afs_page_filler(key, page); | ||
| 232 | key_put(key); | ||
| 233 | } | ||
| 234 | } | ||
| 235 | return ret; | ||
| 236 | } | ||
| 237 | |||
| 238 | /* | ||
| 233 | * read a set of pages | 239 | * read a set of pages |
| 234 | */ | 240 | */ |
| 235 | static int afs_readpages(struct file *file, struct address_space *mapping, | 241 | static int afs_readpages(struct file *file, struct address_space *mapping, |
| 236 | struct list_head *pages, unsigned nr_pages) | 242 | struct list_head *pages, unsigned nr_pages) |
| 237 | { | 243 | { |
| 244 | struct key *key = file->private_data; | ||
| 238 | struct afs_vnode *vnode; | 245 | struct afs_vnode *vnode; |
| 239 | int ret = 0; | 246 | int ret = 0; |
| 240 | 247 | ||
| 241 | _enter(",{%lu},,%d", mapping->host->i_ino, nr_pages); | 248 | _enter("{%d},{%lu},,%d", |
| 249 | key_serial(key), mapping->host->i_ino, nr_pages); | ||
| 250 | |||
| 251 | ASSERT(key != NULL); | ||
| 242 | 252 | ||
| 243 | vnode = AFS_FS_I(mapping->host); | 253 | vnode = AFS_FS_I(mapping->host); |
| 244 | if (vnode->flags & AFS_VNODE_DELETED) { | 254 | if (vnode->flags & AFS_VNODE_DELETED) { |
| @@ -279,7 +289,7 @@ static int afs_readpages(struct file *file, struct address_space *mapping, | |||
| 279 | } | 289 | } |
| 280 | 290 | ||
| 281 | /* load the missing pages from the network */ | 291 | /* load the missing pages from the network */ |
| 282 | ret = read_cache_pages(mapping, pages, (void *) afs_readpage, file); | 292 | ret = read_cache_pages(mapping, pages, afs_page_filler, key); |
| 283 | 293 | ||
| 284 | _leave(" = %d [netting]", ret); | 294 | _leave(" = %d [netting]", ret); |
| 285 | return ret; | 295 | return ret; |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index a10f2582844..807f284cc75 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
| @@ -494,6 +494,7 @@ extern const struct file_operations afs_file_operations; | |||
| 494 | 494 | ||
| 495 | extern int afs_open(struct inode *, struct file *); | 495 | extern int afs_open(struct inode *, struct file *); |
| 496 | extern int afs_release(struct inode *, struct file *); | 496 | extern int afs_release(struct inode *, struct file *); |
| 497 | extern int afs_page_filler(void *, struct page *); | ||
| 497 | 498 | ||
| 498 | /* | 499 | /* |
| 499 | * flock.c | 500 | * flock.c |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index b3feddc4f7d..a9e23039ea3 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
| @@ -49,9 +49,6 @@ static unsigned long afs_mntpt_expiry_timeout = 10 * 60; | |||
| 49 | */ | 49 | */ |
| 50 | int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) | 50 | int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) |
| 51 | { | 51 | { |
| 52 | struct file file = { | ||
| 53 | .private_data = key, | ||
| 54 | }; | ||
| 55 | struct page *page; | 52 | struct page *page; |
| 56 | size_t size; | 53 | size_t size; |
| 57 | char *buf; | 54 | char *buf; |
| @@ -61,7 +58,8 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) | |||
| 61 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); | 58 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); |
| 62 | 59 | ||
| 63 | /* read the contents of the symlink into the pagecache */ | 60 | /* read the contents of the symlink into the pagecache */ |
| 64 | page = read_mapping_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0, &file); | 61 | page = read_cache_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0, |
| 62 | afs_page_filler, key); | ||
| 65 | if (IS_ERR(page)) { | 63 | if (IS_ERR(page)) { |
| 66 | ret = PTR_ERR(page); | 64 | ret = PTR_ERR(page); |
| 67 | goto out; | 65 | goto out; |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index e4b75d6eda8..9bd4b3876c9 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
| @@ -205,7 +205,7 @@ static struct inode *anon_inode_mkinode(void) | |||
| 205 | * that it already _is_ on the dirty list. | 205 | * that it already _is_ on the dirty list. |
| 206 | */ | 206 | */ |
| 207 | inode->i_state = I_DIRTY; | 207 | inode->i_state = I_DIRTY; |
| 208 | inode->i_mode = S_IRUSR | S_IWUSR; | 208 | inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR; |
| 209 | inode->i_uid = current_fsuid(); | 209 | inode->i_uid = current_fsuid(); |
| 210 | inode->i_gid = current_fsgid(); | 210 | inode->i_gid = current_fsgid(); |
| 211 | inode->i_flags |= S_PRIVATE; | 211 | inode->i_flags |= S_PRIVATE; |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 1e41aadb106..8f73841fc97 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
| @@ -105,14 +105,12 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
| 105 | } | 105 | } |
| 106 | set_bit(ino, info->si_imap); | 106 | set_bit(ino, info->si_imap); |
| 107 | info->si_freei--; | 107 | info->si_freei--; |
| 108 | inode->i_uid = current_fsuid(); | 108 | inode_init_owner(inode, dir, mode); |
| 109 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid(); | ||
| 110 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 109 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
| 111 | inode->i_blocks = 0; | 110 | inode->i_blocks = 0; |
| 112 | inode->i_op = &bfs_file_inops; | 111 | inode->i_op = &bfs_file_inops; |
| 113 | inode->i_fop = &bfs_file_operations; | 112 | inode->i_fop = &bfs_file_operations; |
| 114 | inode->i_mapping->a_ops = &bfs_aops; | 113 | inode->i_mapping->a_ops = &bfs_aops; |
| 115 | inode->i_mode = mode; | ||
| 116 | inode->i_ino = ino; | 114 | inode->i_ino = ino; |
| 117 | BFS_I(inode)->i_dsk_ino = ino; | 115 | BFS_I(inode)->i_dsk_ino = ino; |
| 118 | BFS_I(inode)->i_sblock = 0; | 116 | BFS_I(inode)->i_sblock = 0; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 55dcb7884f4..26e5f502662 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -245,37 +245,14 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
| 245 | sb = get_active_super(bdev); | 245 | sb = get_active_super(bdev); |
| 246 | if (!sb) | 246 | if (!sb) |
| 247 | goto out; | 247 | goto out; |
| 248 | if (sb->s_flags & MS_RDONLY) { | 248 | error = freeze_super(sb); |
| 249 | sb->s_frozen = SB_FREEZE_TRANS; | 249 | if (error) { |
| 250 | up_write(&sb->s_umount); | 250 | deactivate_super(sb); |
| 251 | bdev->bd_fsfreeze_count--; | ||
| 251 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 252 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 252 | return sb; | 253 | return ERR_PTR(error); |
| 253 | } | ||
| 254 | |||
| 255 | sb->s_frozen = SB_FREEZE_WRITE; | ||
| 256 | smp_wmb(); | ||
| 257 | |||
| 258 | sync_filesystem(sb); | ||
| 259 | |||
| 260 | sb->s_frozen = SB_FREEZE_TRANS; | ||
| 261 | smp_wmb(); | ||
| 262 | |||
| 263 | sync_blockdev(sb->s_bdev); | ||
| 264 | |||
| 265 | if (sb->s_op->freeze_fs) { | ||
| 266 | error = sb->s_op->freeze_fs(sb); | ||
| 267 | if (error) { | ||
| 268 | printk(KERN_ERR | ||
| 269 | "VFS:Filesystem freeze failed\n"); | ||
| 270 | sb->s_frozen = SB_UNFROZEN; | ||
| 271 | deactivate_locked_super(sb); | ||
| 272 | bdev->bd_fsfreeze_count--; | ||
| 273 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
| 274 | return ERR_PTR(error); | ||
| 275 | } | ||
| 276 | } | 254 | } |
| 277 | up_write(&sb->s_umount); | 255 | deactivate_super(sb); |
| 278 | |||
| 279 | out: | 256 | out: |
| 280 | sync_blockdev(bdev); | 257 | sync_blockdev(bdev); |
| 281 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 258 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| @@ -296,40 +273,22 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb) | |||
| 296 | 273 | ||
| 297 | mutex_lock(&bdev->bd_fsfreeze_mutex); | 274 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
| 298 | if (!bdev->bd_fsfreeze_count) | 275 | if (!bdev->bd_fsfreeze_count) |
| 299 | goto out_unlock; | 276 | goto out; |
| 300 | 277 | ||
| 301 | error = 0; | 278 | error = 0; |
| 302 | if (--bdev->bd_fsfreeze_count > 0) | 279 | if (--bdev->bd_fsfreeze_count > 0) |
| 303 | goto out_unlock; | 280 | goto out; |
| 304 | 281 | ||
| 305 | if (!sb) | 282 | if (!sb) |
| 306 | goto out_unlock; | 283 | goto out; |
| 307 | |||
| 308 | BUG_ON(sb->s_bdev != bdev); | ||
| 309 | down_write(&sb->s_umount); | ||
| 310 | if (sb->s_flags & MS_RDONLY) | ||
| 311 | goto out_unfrozen; | ||
| 312 | |||
| 313 | if (sb->s_op->unfreeze_fs) { | ||
| 314 | error = sb->s_op->unfreeze_fs(sb); | ||
| 315 | if (error) { | ||
| 316 | printk(KERN_ERR | ||
| 317 | "VFS:Filesystem thaw failed\n"); | ||
| 318 | sb->s_frozen = SB_FREEZE_TRANS; | ||
| 319 | bdev->bd_fsfreeze_count++; | ||
| 320 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
| 321 | return error; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | out_unfrozen: | ||
| 326 | sb->s_frozen = SB_UNFROZEN; | ||
| 327 | smp_wmb(); | ||
| 328 | wake_up(&sb->s_wait_unfrozen); | ||
| 329 | 284 | ||
| 330 | if (sb) | 285 | error = thaw_super(sb); |
| 331 | deactivate_locked_super(sb); | 286 | if (error) { |
| 332 | out_unlock: | 287 | bdev->bd_fsfreeze_count++; |
| 288 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
| 289 | return error; | ||
| 290 | } | ||
| 291 | out: | ||
| 333 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 292 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 334 | return 0; | 293 | return 0; |
| 335 | } | 294 | } |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 6ef7b26724e..8d432cd9d58 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
| @@ -282,14 +282,14 @@ int btrfs_acl_chmod(struct inode *inode) | |||
| 282 | return ret; | 282 | return ret; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | struct xattr_handler btrfs_xattr_acl_default_handler = { | 285 | const struct xattr_handler btrfs_xattr_acl_default_handler = { |
| 286 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 286 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 287 | .flags = ACL_TYPE_DEFAULT, | 287 | .flags = ACL_TYPE_DEFAULT, |
| 288 | .get = btrfs_xattr_acl_get, | 288 | .get = btrfs_xattr_acl_get, |
| 289 | .set = btrfs_xattr_acl_set, | 289 | .set = btrfs_xattr_acl_set, |
| 290 | }; | 290 | }; |
| 291 | 291 | ||
| 292 | struct xattr_handler btrfs_xattr_acl_access_handler = { | 292 | const struct xattr_handler btrfs_xattr_acl_access_handler = { |
| 293 | .prefix = POSIX_ACL_XATTR_ACCESS, | 293 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 294 | .flags = ACL_TYPE_ACCESS, | 294 | .flags = ACL_TYPE_ACCESS, |
| 295 | .get = btrfs_xattr_acl_get, | 295 | .get = btrfs_xattr_acl_get, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2bfdc641d4e..d601629b85d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -4121,16 +4121,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 4121 | if (ret != 0) | 4121 | if (ret != 0) |
| 4122 | goto fail; | 4122 | goto fail; |
| 4123 | 4123 | ||
| 4124 | inode->i_uid = current_fsuid(); | 4124 | inode_init_owner(inode, dir, mode); |
| 4125 | |||
| 4126 | if (dir && (dir->i_mode & S_ISGID)) { | ||
| 4127 | inode->i_gid = dir->i_gid; | ||
| 4128 | if (S_ISDIR(mode)) | ||
| 4129 | mode |= S_ISGID; | ||
| 4130 | } else | ||
| 4131 | inode->i_gid = current_fsgid(); | ||
| 4132 | |||
| 4133 | inode->i_mode = mode; | ||
| 4134 | inode->i_ino = objectid; | 4125 | inode->i_ino = objectid; |
| 4135 | inode_set_bytes(inode, 0); | 4126 | inode_set_bytes(inode, 0); |
| 4136 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 4127 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 193b58f7d3f..59acd3eb288 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
| @@ -282,7 +282,7 @@ err: | |||
| 282 | * List of handlers for synthetic system.* attributes. All real ondisk | 282 | * List of handlers for synthetic system.* attributes. All real ondisk |
| 283 | * attributes are handled directly. | 283 | * attributes are handled directly. |
| 284 | */ | 284 | */ |
| 285 | struct xattr_handler *btrfs_xattr_handlers[] = { | 285 | const struct xattr_handler *btrfs_xattr_handlers[] = { |
| 286 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | 286 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
| 287 | &btrfs_xattr_acl_access_handler, | 287 | &btrfs_xattr_acl_access_handler, |
| 288 | &btrfs_xattr_acl_default_handler, | 288 | &btrfs_xattr_acl_default_handler, |
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h index 721efa0346e..7a43fd640bb 100644 --- a/fs/btrfs/xattr.h +++ b/fs/btrfs/xattr.h | |||
| @@ -21,9 +21,9 @@ | |||
| 21 | 21 | ||
| 22 | #include <linux/xattr.h> | 22 | #include <linux/xattr.h> |
| 23 | 23 | ||
| 24 | extern struct xattr_handler btrfs_xattr_acl_access_handler; | 24 | extern const struct xattr_handler btrfs_xattr_acl_access_handler; |
| 25 | extern struct xattr_handler btrfs_xattr_acl_default_handler; | 25 | extern const struct xattr_handler btrfs_xattr_acl_default_handler; |
| 26 | extern struct xattr_handler *btrfs_xattr_handlers[]; | 26 | extern const struct xattr_handler *btrfs_xattr_handlers[]; |
| 27 | 27 | ||
| 28 | extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | 28 | extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, |
| 29 | void *buffer, size_t size); | 29 | void *buffer, size_t size); |
diff --git a/fs/buffer.c b/fs/buffer.c index 08e422d5699..e8aa7081d25 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -561,26 +561,17 @@ repeat: | |||
| 561 | return err; | 561 | return err; |
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | static void do_thaw_all(struct work_struct *work) | 564 | static void do_thaw_one(struct super_block *sb, void *unused) |
| 565 | { | 565 | { |
| 566 | struct super_block *sb; | ||
| 567 | char b[BDEVNAME_SIZE]; | 566 | char b[BDEVNAME_SIZE]; |
| 567 | while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb)) | ||
| 568 | printk(KERN_WARNING "Emergency Thaw on %s\n", | ||
| 569 | bdevname(sb->s_bdev, b)); | ||
| 570 | } | ||
| 568 | 571 | ||
| 569 | spin_lock(&sb_lock); | 572 | static void do_thaw_all(struct work_struct *work) |
| 570 | restart: | 573 | { |
| 571 | list_for_each_entry(sb, &super_blocks, s_list) { | 574 | iterate_supers(do_thaw_one, NULL); |
| 572 | sb->s_count++; | ||
| 573 | spin_unlock(&sb_lock); | ||
| 574 | down_read(&sb->s_umount); | ||
| 575 | while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb)) | ||
| 576 | printk(KERN_WARNING "Emergency Thaw on %s\n", | ||
| 577 | bdevname(sb->s_bdev, b)); | ||
| 578 | up_read(&sb->s_umount); | ||
| 579 | spin_lock(&sb_lock); | ||
| 580 | if (__put_super_and_need_restart(sb)) | ||
| 581 | goto restart; | ||
| 582 | } | ||
| 583 | spin_unlock(&sb_lock); | ||
| 584 | kfree(work); | 575 | kfree(work); |
| 585 | printk(KERN_WARNING "Emergency Thaw complete\n"); | 576 | printk(KERN_WARNING "Emergency Thaw complete\n"); |
| 586 | } | 577 | } |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index ed6f19721d6..7d634938edc 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
| @@ -844,8 +844,7 @@ retry_snap: | |||
| 844 | if ((ret >= 0 || ret == -EIOCBQUEUED) && | 844 | if ((ret >= 0 || ret == -EIOCBQUEUED) && |
| 845 | ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) | 845 | ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) |
| 846 | || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) { | 846 | || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) { |
| 847 | err = vfs_fsync_range(file, file->f_path.dentry, | 847 | err = vfs_fsync_range(file, pos, pos + ret - 1, 1); |
| 848 | pos, pos + ret - 1, 1); | ||
| 849 | if (err < 0) | 848 | if (err < 0) |
| 850 | ret = err; | 849 | ret = err; |
| 851 | } | 850 | } |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 110857ba926..9307bbee6fb 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
| @@ -952,8 +952,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, | |||
| 952 | 952 | ||
| 953 | out_splat: | 953 | out_splat: |
| 954 | ceph_mdsc_close_sessions(&client->mdsc); | 954 | ceph_mdsc_close_sessions(&client->mdsc); |
| 955 | up_write(&sb->s_umount); | 955 | deactivate_locked_super(sb); |
| 956 | deactivate_super(sb); | ||
| 957 | goto out_final; | 956 | goto out_final; |
| 958 | 957 | ||
| 959 | out: | 958 | out: |
diff --git a/fs/coda/file.c b/fs/coda/file.c index 4c813f2cdc5..7196077b168 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
| @@ -217,7 +217,7 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync) | |||
| 217 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | 217 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); |
| 218 | host_file = cfi->cfi_container; | 218 | host_file = cfi->cfi_container; |
| 219 | 219 | ||
| 220 | err = vfs_fsync(host_file, host_file->f_path.dentry, datasync); | 220 | err = vfs_fsync(host_file, datasync); |
| 221 | if ( !err && !datasync ) { | 221 | if ( !err && !datasync ) { |
| 222 | lock_kernel(); | 222 | lock_kernel(); |
| 223 | err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); | 223 | err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); |
diff --git a/fs/dcache.c b/fs/dcache.c index f1358e5c3a5..d96047b4a63 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -536,7 +536,7 @@ restart: | |||
| 536 | */ | 536 | */ |
| 537 | static void prune_dcache(int count) | 537 | static void prune_dcache(int count) |
| 538 | { | 538 | { |
| 539 | struct super_block *sb; | 539 | struct super_block *sb, *n; |
| 540 | int w_count; | 540 | int w_count; |
| 541 | int unused = dentry_stat.nr_unused; | 541 | int unused = dentry_stat.nr_unused; |
| 542 | int prune_ratio; | 542 | int prune_ratio; |
| @@ -545,13 +545,14 @@ static void prune_dcache(int count) | |||
| 545 | if (unused == 0 || count == 0) | 545 | if (unused == 0 || count == 0) |
| 546 | return; | 546 | return; |
| 547 | spin_lock(&dcache_lock); | 547 | spin_lock(&dcache_lock); |
| 548 | restart: | ||
| 549 | if (count >= unused) | 548 | if (count >= unused) |
| 550 | prune_ratio = 1; | 549 | prune_ratio = 1; |
| 551 | else | 550 | else |
| 552 | prune_ratio = unused / count; | 551 | prune_ratio = unused / count; |
| 553 | spin_lock(&sb_lock); | 552 | spin_lock(&sb_lock); |
| 554 | list_for_each_entry(sb, &super_blocks, s_list) { | 553 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { |
| 554 | if (list_empty(&sb->s_instances)) | ||
| 555 | continue; | ||
| 555 | if (sb->s_nr_dentry_unused == 0) | 556 | if (sb->s_nr_dentry_unused == 0) |
| 556 | continue; | 557 | continue; |
| 557 | sb->s_count++; | 558 | sb->s_count++; |
| @@ -590,14 +591,10 @@ restart: | |||
| 590 | } | 591 | } |
| 591 | spin_lock(&sb_lock); | 592 | spin_lock(&sb_lock); |
| 592 | count -= pruned; | 593 | count -= pruned; |
| 593 | /* | 594 | __put_super(sb); |
| 594 | * restart only when sb is no longer on the list and | 595 | /* more work left to do? */ |
| 595 | * we have more work to do. | 596 | if (count <= 0) |
| 596 | */ | 597 | break; |
| 597 | if (__put_super_and_need_restart(sb) && count > 0) { | ||
| 598 | spin_unlock(&sb_lock); | ||
| 599 | goto restart; | ||
| 600 | } | ||
| 601 | } | 598 | } |
| 602 | spin_unlock(&sb_lock); | 599 | spin_unlock(&sb_lock); |
| 603 | spin_unlock(&dcache_lock); | 600 | spin_unlock(&dcache_lock); |
| @@ -1529,6 +1526,7 @@ void d_delete(struct dentry * dentry) | |||
| 1529 | spin_lock(&dentry->d_lock); | 1526 | spin_lock(&dentry->d_lock); |
| 1530 | isdir = S_ISDIR(dentry->d_inode->i_mode); | 1527 | isdir = S_ISDIR(dentry->d_inode->i_mode); |
| 1531 | if (atomic_read(&dentry->d_count) == 1) { | 1528 | if (atomic_read(&dentry->d_count) == 1) { |
| 1529 | dentry->d_flags &= ~DCACHE_CANT_MOUNT; | ||
| 1532 | dentry_iput(dentry); | 1530 | dentry_iput(dentry); |
| 1533 | fsnotify_nameremove(dentry, isdir); | 1531 | fsnotify_nameremove(dentry, isdir); |
| 1534 | return; | 1532 | return; |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 0120247b41c..8b3ffd5b523 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
| @@ -384,18 +384,15 @@ static int devpts_get_sb(struct file_system_type *fs_type, | |||
| 384 | s->s_flags |= MS_ACTIVE; | 384 | s->s_flags |= MS_ACTIVE; |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | simple_set_mnt(mnt, s); | ||
| 388 | |||
| 389 | memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts)); | 387 | memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts)); |
| 390 | 388 | ||
| 391 | error = mknod_ptmx(s); | 389 | error = mknod_ptmx(s); |
| 392 | if (error) | 390 | if (error) |
| 393 | goto out_dput; | 391 | goto out_undo_sget; |
| 394 | 392 | ||
| 395 | return 0; | 393 | simple_set_mnt(mnt, s); |
| 396 | 394 | ||
| 397 | out_dput: | 395 | return 0; |
| 398 | dput(s->s_root); /* undo dget() in simple_set_mnt() */ | ||
| 399 | 396 | ||
| 400 | out_undo_sget: | 397 | out_undo_sget: |
| 401 | deactivate_locked_super(s); | 398 | deactivate_locked_super(s); |
diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 31f4b0e6d72..83c4f600786 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | /* A global variable is a bit ugly, but it keeps the code simple */ | 12 | /* A global variable is a bit ugly, but it keeps the code simple */ |
| 13 | int sysctl_drop_caches; | 13 | int sysctl_drop_caches; |
| 14 | 14 | ||
| 15 | static void drop_pagecache_sb(struct super_block *sb) | 15 | static void drop_pagecache_sb(struct super_block *sb, void *unused) |
| 16 | { | 16 | { |
| 17 | struct inode *inode, *toput_inode = NULL; | 17 | struct inode *inode, *toput_inode = NULL; |
| 18 | 18 | ||
| @@ -33,26 +33,6 @@ static void drop_pagecache_sb(struct super_block *sb) | |||
| 33 | iput(toput_inode); | 33 | iput(toput_inode); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static void drop_pagecache(void) | ||
| 37 | { | ||
| 38 | struct super_block *sb; | ||
| 39 | |||
| 40 | spin_lock(&sb_lock); | ||
| 41 | restart: | ||
| 42 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
| 43 | sb->s_count++; | ||
| 44 | spin_unlock(&sb_lock); | ||
| 45 | down_read(&sb->s_umount); | ||
| 46 | if (sb->s_root) | ||
| 47 | drop_pagecache_sb(sb); | ||
| 48 | up_read(&sb->s_umount); | ||
| 49 | spin_lock(&sb_lock); | ||
| 50 | if (__put_super_and_need_restart(sb)) | ||
| 51 | goto restart; | ||
| 52 | } | ||
| 53 | spin_unlock(&sb_lock); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void drop_slab(void) | 36 | static void drop_slab(void) |
| 57 | { | 37 | { |
| 58 | int nr_objects; | 38 | int nr_objects; |
| @@ -68,7 +48,7 @@ int drop_caches_sysctl_handler(ctl_table *table, int write, | |||
| 68 | proc_dointvec_minmax(table, write, buffer, length, ppos); | 48 | proc_dointvec_minmax(table, write, buffer, length, ppos); |
| 69 | if (write) { | 49 | if (write) { |
| 70 | if (sysctl_drop_caches & 1) | 50 | if (sysctl_drop_caches & 1) |
| 71 | drop_pagecache(); | 51 | iterate_supers(drop_pagecache_sb, NULL); |
| 72 | if (sysctl_drop_caches & 2) | 52 | if (sysctl_drop_caches & 2) |
| 73 | drop_slab(); | 53 | drop_slab(); |
| 74 | } | 54 | } |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index bfc2e0f78f0..0032a9f5a3a 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
| @@ -731,15 +731,14 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | |||
| 731 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | 731 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, |
| 732 | struct page *page_for_lower, | 732 | struct page *page_for_lower, |
| 733 | size_t offset_in_page, size_t size); | 733 | size_t offset_in_page, size_t size); |
| 734 | int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | 734 | int ecryptfs_write(struct inode *inode, char *data, loff_t offset, size_t size); |
| 735 | size_t size); | ||
| 736 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | 735 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, |
| 737 | struct inode *ecryptfs_inode); | 736 | struct inode *ecryptfs_inode); |
| 738 | int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | 737 | int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, |
| 739 | pgoff_t page_index, | 738 | pgoff_t page_index, |
| 740 | size_t offset_in_page, size_t size, | 739 | size_t offset_in_page, size_t size, |
| 741 | struct inode *ecryptfs_inode); | 740 | struct inode *ecryptfs_inode); |
| 742 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); | 741 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index); |
| 743 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); | 742 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); |
| 744 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | 743 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, |
| 745 | struct user_namespace *user_ns); | 744 | struct user_namespace *user_ns); |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index e7440a6f5eb..3bdddbcc785 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
| @@ -276,9 +276,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
| 276 | static int | 276 | static int |
| 277 | ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 277 | ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) |
| 278 | { | 278 | { |
| 279 | return vfs_fsync(ecryptfs_file_to_lower(file), | 279 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); |
| 280 | ecryptfs_dentry_to_lower(dentry), | ||
| 281 | datasync); | ||
| 282 | } | 280 | } |
| 283 | 281 | ||
| 284 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | 282 | static int ecryptfs_fasync(int fd, struct file *file, int flag) |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index e2d4418affa..65dee2f336a 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -142,19 +142,10 @@ out: | |||
| 142 | static int grow_file(struct dentry *ecryptfs_dentry) | 142 | static int grow_file(struct dentry *ecryptfs_dentry) |
| 143 | { | 143 | { |
| 144 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | 144 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; |
| 145 | struct file fake_file; | ||
| 146 | struct ecryptfs_file_info tmp_file_info; | ||
| 147 | char zero_virt[] = { 0x00 }; | 145 | char zero_virt[] = { 0x00 }; |
| 148 | int rc = 0; | 146 | int rc = 0; |
| 149 | 147 | ||
| 150 | memset(&fake_file, 0, sizeof(fake_file)); | 148 | rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1); |
| 151 | fake_file.f_path.dentry = ecryptfs_dentry; | ||
| 152 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); | ||
| 153 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); | ||
| 154 | ecryptfs_set_file_lower( | ||
| 155 | &fake_file, | ||
| 156 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file); | ||
| 157 | rc = ecryptfs_write(&fake_file, zero_virt, 0, 1); | ||
| 158 | i_size_write(ecryptfs_inode, 0); | 149 | i_size_write(ecryptfs_inode, 0); |
| 159 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | 150 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); |
| 160 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= | 151 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= |
| @@ -784,8 +775,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 784 | { | 775 | { |
| 785 | int rc = 0; | 776 | int rc = 0; |
| 786 | struct inode *inode = dentry->d_inode; | 777 | struct inode *inode = dentry->d_inode; |
| 787 | struct dentry *lower_dentry; | ||
| 788 | struct file fake_ecryptfs_file; | ||
| 789 | struct ecryptfs_crypt_stat *crypt_stat; | 778 | struct ecryptfs_crypt_stat *crypt_stat; |
| 790 | loff_t i_size = i_size_read(inode); | 779 | loff_t i_size = i_size_read(inode); |
| 791 | loff_t lower_size_before_truncate; | 780 | loff_t lower_size_before_truncate; |
| @@ -796,23 +785,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 796 | goto out; | 785 | goto out; |
| 797 | } | 786 | } |
| 798 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 787 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
| 799 | /* Set up a fake ecryptfs file, this is used to interface with | ||
| 800 | * the file in the underlying filesystem so that the | ||
| 801 | * truncation has an effect there as well. */ | ||
| 802 | memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file)); | ||
| 803 | fake_ecryptfs_file.f_path.dentry = dentry; | ||
| 804 | /* Released at out_free: label */ | ||
| 805 | ecryptfs_set_file_private(&fake_ecryptfs_file, | ||
| 806 | kmem_cache_alloc(ecryptfs_file_info_cache, | ||
| 807 | GFP_KERNEL)); | ||
| 808 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { | ||
| 809 | rc = -ENOMEM; | ||
| 810 | goto out; | ||
| 811 | } | ||
| 812 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 813 | ecryptfs_set_file_lower( | ||
| 814 | &fake_ecryptfs_file, | ||
| 815 | ecryptfs_inode_to_private(dentry->d_inode)->lower_file); | ||
| 816 | /* Switch on growing or shrinking file */ | 788 | /* Switch on growing or shrinking file */ |
| 817 | if (ia->ia_size > i_size) { | 789 | if (ia->ia_size > i_size) { |
| 818 | char zero[] = { 0x00 }; | 790 | char zero[] = { 0x00 }; |
| @@ -822,7 +794,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 822 | * this triggers code that will fill in 0's throughout | 794 | * this triggers code that will fill in 0's throughout |
| 823 | * the intermediate portion of the previous end of the | 795 | * the intermediate portion of the previous end of the |
| 824 | * file and the new and of the file */ | 796 | * file and the new and of the file */ |
| 825 | rc = ecryptfs_write(&fake_ecryptfs_file, zero, | 797 | rc = ecryptfs_write(inode, zero, |
| 826 | (ia->ia_size - 1), 1); | 798 | (ia->ia_size - 1), 1); |
| 827 | } else { /* ia->ia_size < i_size_read(inode) */ | 799 | } else { /* ia->ia_size < i_size_read(inode) */ |
| 828 | /* We're chopping off all the pages down to the page | 800 | /* We're chopping off all the pages down to the page |
| @@ -835,10 +807,10 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 835 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 807 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
| 836 | rc = vmtruncate(inode, ia->ia_size); | 808 | rc = vmtruncate(inode, ia->ia_size); |
| 837 | if (rc) | 809 | if (rc) |
| 838 | goto out_free; | 810 | goto out; |
| 839 | lower_ia->ia_size = ia->ia_size; | 811 | lower_ia->ia_size = ia->ia_size; |
| 840 | lower_ia->ia_valid |= ATTR_SIZE; | 812 | lower_ia->ia_valid |= ATTR_SIZE; |
| 841 | goto out_free; | 813 | goto out; |
| 842 | } | 814 | } |
| 843 | if (num_zeros) { | 815 | if (num_zeros) { |
| 844 | char *zeros_virt; | 816 | char *zeros_virt; |
| @@ -846,16 +818,16 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 846 | zeros_virt = kzalloc(num_zeros, GFP_KERNEL); | 818 | zeros_virt = kzalloc(num_zeros, GFP_KERNEL); |
| 847 | if (!zeros_virt) { | 819 | if (!zeros_virt) { |
| 848 | rc = -ENOMEM; | 820 | rc = -ENOMEM; |
| 849 | goto out_free; | 821 | goto out; |
| 850 | } | 822 | } |
| 851 | rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt, | 823 | rc = ecryptfs_write(inode, zeros_virt, |
| 852 | ia->ia_size, num_zeros); | 824 | ia->ia_size, num_zeros); |
| 853 | kfree(zeros_virt); | 825 | kfree(zeros_virt); |
| 854 | if (rc) { | 826 | if (rc) { |
| 855 | printk(KERN_ERR "Error attempting to zero out " | 827 | printk(KERN_ERR "Error attempting to zero out " |
| 856 | "the remainder of the end page on " | 828 | "the remainder of the end page on " |
| 857 | "reducing truncate; rc = [%d]\n", rc); | 829 | "reducing truncate; rc = [%d]\n", rc); |
| 858 | goto out_free; | 830 | goto out; |
| 859 | } | 831 | } |
| 860 | } | 832 | } |
| 861 | vmtruncate(inode, ia->ia_size); | 833 | vmtruncate(inode, ia->ia_size); |
| @@ -864,7 +836,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 864 | printk(KERN_ERR "Problem with " | 836 | printk(KERN_ERR "Problem with " |
| 865 | "ecryptfs_write_inode_size_to_metadata; " | 837 | "ecryptfs_write_inode_size_to_metadata; " |
| 866 | "rc = [%d]\n", rc); | 838 | "rc = [%d]\n", rc); |
| 867 | goto out_free; | 839 | goto out; |
| 868 | } | 840 | } |
| 869 | /* We are reducing the size of the ecryptfs file, and need to | 841 | /* We are reducing the size of the ecryptfs file, and need to |
| 870 | * know if we need to reduce the size of the lower file. */ | 842 | * know if we need to reduce the size of the lower file. */ |
| @@ -878,10 +850,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 878 | } else | 850 | } else |
| 879 | lower_ia->ia_valid &= ~ATTR_SIZE; | 851 | lower_ia->ia_valid &= ~ATTR_SIZE; |
| 880 | } | 852 | } |
| 881 | out_free: | ||
| 882 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) | ||
| 883 | kmem_cache_free(ecryptfs_file_info_cache, | ||
| 884 | ecryptfs_file_to_private(&fake_ecryptfs_file)); | ||
| 885 | out: | 853 | out: |
| 886 | return rc; | 854 | return rc; |
| 887 | } | 855 | } |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 760983d0f25..cbd4e18adb2 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -281,7 +281,7 @@ static void ecryptfs_init_mount_crypt_stat( | |||
| 281 | * | 281 | * |
| 282 | * Returns zero on success; non-zero on error | 282 | * Returns zero on success; non-zero on error |
| 283 | */ | 283 | */ |
| 284 | static int ecryptfs_parse_options(struct super_block *sb, char *options) | 284 | static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
| 285 | { | 285 | { |
| 286 | char *p; | 286 | char *p; |
| 287 | int rc = 0; | 287 | int rc = 0; |
| @@ -293,7 +293,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 293 | int fn_cipher_key_bytes; | 293 | int fn_cipher_key_bytes; |
| 294 | int fn_cipher_key_bytes_set = 0; | 294 | int fn_cipher_key_bytes_set = 0; |
| 295 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 295 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
| 296 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; | 296 | &sbi->mount_crypt_stat; |
| 297 | substring_t args[MAX_OPT_ARGS]; | 297 | substring_t args[MAX_OPT_ARGS]; |
| 298 | int token; | 298 | int token; |
| 299 | char *sig_src; | 299 | char *sig_src; |
| @@ -483,68 +483,7 @@ out: | |||
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | struct kmem_cache *ecryptfs_sb_info_cache; | 485 | struct kmem_cache *ecryptfs_sb_info_cache; |
| 486 | 486 | static struct file_system_type ecryptfs_fs_type; | |
| 487 | /** | ||
| 488 | * ecryptfs_fill_super | ||
| 489 | * @sb: The ecryptfs super block | ||
| 490 | * @raw_data: The options passed to mount | ||
| 491 | * @silent: Not used but required by function prototype | ||
| 492 | * | ||
| 493 | * Sets up what we can of the sb, rest is done in ecryptfs_read_super | ||
| 494 | * | ||
| 495 | * Returns zero on success; non-zero otherwise | ||
| 496 | */ | ||
| 497 | static int | ||
| 498 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | ||
| 499 | { | ||
| 500 | struct ecryptfs_sb_info *esi; | ||
| 501 | int rc = 0; | ||
| 502 | |||
| 503 | /* Released in ecryptfs_put_super() */ | ||
| 504 | ecryptfs_set_superblock_private(sb, | ||
| 505 | kmem_cache_zalloc(ecryptfs_sb_info_cache, | ||
| 506 | GFP_KERNEL)); | ||
| 507 | esi = ecryptfs_superblock_to_private(sb); | ||
| 508 | if (!esi) { | ||
| 509 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | ||
| 510 | rc = -ENOMEM; | ||
| 511 | goto out; | ||
| 512 | } | ||
| 513 | |||
| 514 | rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
| 515 | if (rc) | ||
| 516 | goto out; | ||
| 517 | |||
| 518 | sb->s_bdi = &esi->bdi; | ||
| 519 | sb->s_op = &ecryptfs_sops; | ||
| 520 | /* Released through deactivate_super(sb) from get_sb_nodev */ | ||
| 521 | sb->s_root = d_alloc(NULL, &(const struct qstr) { | ||
| 522 | .hash = 0,.name = "/",.len = 1}); | ||
| 523 | if (!sb->s_root) { | ||
| 524 | ecryptfs_printk(KERN_ERR, "d_alloc failed\n"); | ||
| 525 | rc = -ENOMEM; | ||
| 526 | goto out; | ||
| 527 | } | ||
| 528 | sb->s_root->d_op = &ecryptfs_dops; | ||
| 529 | sb->s_root->d_sb = sb; | ||
| 530 | sb->s_root->d_parent = sb->s_root; | ||
| 531 | /* Released in d_release when dput(sb->s_root) is called */ | ||
| 532 | /* through deactivate_super(sb) from get_sb_nodev() */ | ||
| 533 | ecryptfs_set_dentry_private(sb->s_root, | ||
| 534 | kmem_cache_zalloc(ecryptfs_dentry_info_cache, | ||
| 535 | GFP_KERNEL)); | ||
| 536 | if (!ecryptfs_dentry_to_private(sb->s_root)) { | ||
| 537 | ecryptfs_printk(KERN_ERR, | ||
| 538 | "dentry_info_cache alloc failed\n"); | ||
| 539 | rc = -ENOMEM; | ||
| 540 | goto out; | ||
| 541 | } | ||
| 542 | rc = 0; | ||
| 543 | out: | ||
| 544 | /* Should be able to rely on deactivate_super called from | ||
| 545 | * get_sb_nodev */ | ||
| 546 | return rc; | ||
| 547 | } | ||
| 548 | 487 | ||
| 549 | /** | 488 | /** |
| 550 | * ecryptfs_read_super | 489 | * ecryptfs_read_super |
| @@ -565,6 +504,13 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) | |||
| 565 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); | 504 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); |
| 566 | goto out; | 505 | goto out; |
| 567 | } | 506 | } |
| 507 | if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) { | ||
| 508 | rc = -EINVAL; | ||
| 509 | printk(KERN_ERR "Mount on filesystem of type " | ||
| 510 | "eCryptfs explicitly disallowed due to " | ||
| 511 | "known incompatibilities\n"); | ||
| 512 | goto out_free; | ||
| 513 | } | ||
| 568 | ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); | 514 | ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); |
| 569 | sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; | 515 | sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
| 570 | sb->s_blocksize = path.dentry->d_sb->s_blocksize; | 516 | sb->s_blocksize = path.dentry->d_sb->s_blocksize; |
| @@ -588,11 +534,8 @@ out: | |||
| 588 | * @dev_name: The path to mount over | 534 | * @dev_name: The path to mount over |
| 589 | * @raw_data: The options passed into the kernel | 535 | * @raw_data: The options passed into the kernel |
| 590 | * | 536 | * |
| 591 | * The whole ecryptfs_get_sb process is broken into 4 functions: | 537 | * The whole ecryptfs_get_sb process is broken into 3 functions: |
| 592 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any | 538 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any |
| 593 | * ecryptfs_fill_super(): used by get_sb_nodev, fills out the super_block | ||
| 594 | * with as much information as it can before needing | ||
| 595 | * the lower filesystem. | ||
| 596 | * ecryptfs_read_super(): this accesses the lower filesystem and uses | 539 | * ecryptfs_read_super(): this accesses the lower filesystem and uses |
| 597 | * ecryptfs_interpose to perform most of the linking | 540 | * ecryptfs_interpose to perform most of the linking |
| 598 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) | 541 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) |
| @@ -601,30 +544,78 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, | |||
| 601 | const char *dev_name, void *raw_data, | 544 | const char *dev_name, void *raw_data, |
| 602 | struct vfsmount *mnt) | 545 | struct vfsmount *mnt) |
| 603 | { | 546 | { |
| 547 | struct super_block *s; | ||
| 548 | struct ecryptfs_sb_info *sbi; | ||
| 549 | struct ecryptfs_dentry_info *root_info; | ||
| 550 | const char *err = "Getting sb failed"; | ||
| 604 | int rc; | 551 | int rc; |
| 605 | struct super_block *sb; | ||
| 606 | 552 | ||
| 607 | rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt); | 553 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
| 608 | if (rc < 0) { | 554 | if (!sbi) { |
| 609 | printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc); | 555 | rc = -ENOMEM; |
| 610 | goto out; | 556 | goto out; |
| 611 | } | 557 | } |
| 612 | sb = mnt->mnt_sb; | 558 | |
| 613 | rc = ecryptfs_parse_options(sb, raw_data); | 559 | rc = ecryptfs_parse_options(sbi, raw_data); |
| 614 | if (rc) { | 560 | if (rc) { |
| 615 | printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc); | 561 | err = "Error parsing options"; |
| 616 | goto out_abort; | 562 | goto out; |
| 563 | } | ||
| 564 | |||
| 565 | s = sget(fs_type, NULL, set_anon_super, NULL); | ||
| 566 | if (IS_ERR(s)) { | ||
| 567 | rc = PTR_ERR(s); | ||
| 568 | goto out; | ||
| 617 | } | 569 | } |
| 618 | rc = ecryptfs_read_super(sb, dev_name); | 570 | |
| 571 | s->s_flags = flags; | ||
| 572 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
| 619 | if (rc) { | 573 | if (rc) { |
| 620 | printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc); | 574 | deactivate_locked_super(s); |
| 621 | goto out_abort; | 575 | goto out; |
| 622 | } | 576 | } |
| 623 | goto out; | 577 | |
| 624 | out_abort: | 578 | ecryptfs_set_superblock_private(s, sbi); |
| 625 | dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */ | 579 | s->s_bdi = &sbi->bdi; |
| 626 | deactivate_locked_super(sb); | 580 | |
| 581 | /* ->kill_sb() will take care of sbi after that point */ | ||
| 582 | sbi = NULL; | ||
| 583 | s->s_op = &ecryptfs_sops; | ||
| 584 | |||
| 585 | rc = -ENOMEM; | ||
| 586 | s->s_root = d_alloc(NULL, &(const struct qstr) { | ||
| 587 | .hash = 0,.name = "/",.len = 1}); | ||
| 588 | if (!s->s_root) { | ||
| 589 | deactivate_locked_super(s); | ||
| 590 | goto out; | ||
| 591 | } | ||
| 592 | s->s_root->d_op = &ecryptfs_dops; | ||
| 593 | s->s_root->d_sb = s; | ||
| 594 | s->s_root->d_parent = s->s_root; | ||
| 595 | |||
| 596 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); | ||
| 597 | if (!root_info) { | ||
| 598 | deactivate_locked_super(s); | ||
| 599 | goto out; | ||
| 600 | } | ||
| 601 | /* ->kill_sb() will take care of root_info */ | ||
| 602 | ecryptfs_set_dentry_private(s->s_root, root_info); | ||
| 603 | s->s_flags |= MS_ACTIVE; | ||
| 604 | rc = ecryptfs_read_super(s, dev_name); | ||
| 605 | if (rc) { | ||
| 606 | deactivate_locked_super(s); | ||
| 607 | err = "Reading sb failed"; | ||
| 608 | goto out; | ||
| 609 | } | ||
| 610 | simple_set_mnt(mnt, s); | ||
| 611 | return 0; | ||
| 612 | |||
| 627 | out: | 613 | out: |
| 614 | if (sbi) { | ||
| 615 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); | ||
| 616 | kmem_cache_free(ecryptfs_sb_info_cache, sbi); | ||
| 617 | } | ||
| 618 | printk(KERN_ERR "%s; rc = [%d]\n", err, rc); | ||
| 628 | return rc; | 619 | return rc; |
| 629 | } | 620 | } |
| 630 | 621 | ||
| @@ -633,11 +624,16 @@ out: | |||
| 633 | * @sb: The ecryptfs super block | 624 | * @sb: The ecryptfs super block |
| 634 | * | 625 | * |
| 635 | * Used to bring the superblock down and free the private data. | 626 | * Used to bring the superblock down and free the private data. |
| 636 | * Private data is free'd in ecryptfs_put_super() | ||
| 637 | */ | 627 | */ |
| 638 | static void ecryptfs_kill_block_super(struct super_block *sb) | 628 | static void ecryptfs_kill_block_super(struct super_block *sb) |
| 639 | { | 629 | { |
| 640 | generic_shutdown_super(sb); | 630 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); |
| 631 | kill_anon_super(sb); | ||
| 632 | if (!sb_info) | ||
| 633 | return; | ||
| 634 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | ||
| 635 | bdi_destroy(&sb_info->bdi); | ||
| 636 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | ||
| 641 | } | 637 | } |
| 642 | 638 | ||
| 643 | static struct file_system_type ecryptfs_fs_type = { | 639 | static struct file_system_type ecryptfs_fs_type = { |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 2ee9a3a7b68..b1d82756544 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
| @@ -44,17 +44,9 @@ | |||
| 44 | * Returns locked and up-to-date page (if ok), with increased | 44 | * Returns locked and up-to-date page (if ok), with increased |
| 45 | * refcnt. | 45 | * refcnt. |
| 46 | */ | 46 | */ |
| 47 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index) | 47 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index) |
| 48 | { | 48 | { |
| 49 | struct dentry *dentry; | 49 | struct page *page = read_mapping_page(inode->i_mapping, index, NULL); |
| 50 | struct inode *inode; | ||
| 51 | struct address_space *mapping; | ||
| 52 | struct page *page; | ||
| 53 | |||
| 54 | dentry = file->f_path.dentry; | ||
| 55 | inode = dentry->d_inode; | ||
| 56 | mapping = inode->i_mapping; | ||
| 57 | page = read_mapping_page(mapping, index, (void *)file); | ||
| 58 | if (!IS_ERR(page)) | 50 | if (!IS_ERR(page)) |
| 59 | lock_page(page); | 51 | lock_page(page); |
| 60 | return page; | 52 | return page; |
| @@ -198,7 +190,7 @@ out: | |||
| 198 | static int ecryptfs_readpage(struct file *file, struct page *page) | 190 | static int ecryptfs_readpage(struct file *file, struct page *page) |
| 199 | { | 191 | { |
| 200 | struct ecryptfs_crypt_stat *crypt_stat = | 192 | struct ecryptfs_crypt_stat *crypt_stat = |
| 201 | &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat; | 193 | &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; |
| 202 | int rc = 0; | 194 | int rc = 0; |
| 203 | 195 | ||
| 204 | if (!crypt_stat | 196 | if (!crypt_stat |
| @@ -300,8 +292,7 @@ static int ecryptfs_write_begin(struct file *file, | |||
| 300 | 292 | ||
| 301 | if (!PageUptodate(page)) { | 293 | if (!PageUptodate(page)) { |
| 302 | struct ecryptfs_crypt_stat *crypt_stat = | 294 | struct ecryptfs_crypt_stat *crypt_stat = |
| 303 | &ecryptfs_inode_to_private( | 295 | &ecryptfs_inode_to_private(mapping->host)->crypt_stat; |
| 304 | file->f_path.dentry->d_inode)->crypt_stat; | ||
| 305 | 296 | ||
| 306 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) | 297 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
| 307 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { | 298 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { |
| @@ -487,7 +478,7 @@ static int ecryptfs_write_end(struct file *file, | |||
| 487 | unsigned to = from + copied; | 478 | unsigned to = from + copied; |
| 488 | struct inode *ecryptfs_inode = mapping->host; | 479 | struct inode *ecryptfs_inode = mapping->host; |
| 489 | struct ecryptfs_crypt_stat *crypt_stat = | 480 | struct ecryptfs_crypt_stat *crypt_stat = |
| 490 | &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat; | 481 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
| 491 | int rc; | 482 | int rc; |
| 492 | 483 | ||
| 493 | if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { | 484 | if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 0cc4fafd655..db184ef15d3 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
| @@ -93,7 +93,7 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | |||
| 93 | 93 | ||
| 94 | /** | 94 | /** |
| 95 | * ecryptfs_write | 95 | * ecryptfs_write |
| 96 | * @ecryptfs_file: The eCryptfs file into which to write | 96 | * @ecryptfs_inode: The eCryptfs file into which to write |
| 97 | * @data: Virtual address where data to write is located | 97 | * @data: Virtual address where data to write is located |
| 98 | * @offset: Offset in the eCryptfs file at which to begin writing the | 98 | * @offset: Offset in the eCryptfs file at which to begin writing the |
| 99 | * data from @data | 99 | * data from @data |
| @@ -109,12 +109,11 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | |||
| 109 | * | 109 | * |
| 110 | * Returns zero on success; non-zero otherwise | 110 | * Returns zero on success; non-zero otherwise |
| 111 | */ | 111 | */ |
| 112 | int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | 112 | int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, |
| 113 | size_t size) | 113 | size_t size) |
| 114 | { | 114 | { |
| 115 | struct page *ecryptfs_page; | 115 | struct page *ecryptfs_page; |
| 116 | struct ecryptfs_crypt_stat *crypt_stat; | 116 | struct ecryptfs_crypt_stat *crypt_stat; |
| 117 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; | ||
| 118 | char *ecryptfs_page_virt; | 117 | char *ecryptfs_page_virt; |
| 119 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); | 118 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); |
| 120 | loff_t data_offset = 0; | 119 | loff_t data_offset = 0; |
| @@ -145,7 +144,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
| 145 | if (num_bytes > total_remaining_zeros) | 144 | if (num_bytes > total_remaining_zeros) |
| 146 | num_bytes = total_remaining_zeros; | 145 | num_bytes = total_remaining_zeros; |
| 147 | } | 146 | } |
| 148 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file, | 147 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, |
| 149 | ecryptfs_page_idx); | 148 | ecryptfs_page_idx); |
| 150 | if (IS_ERR(ecryptfs_page)) { | 149 | if (IS_ERR(ecryptfs_page)) { |
| 151 | rc = PTR_ERR(ecryptfs_page); | 150 | rc = PTR_ERR(ecryptfs_page); |
| @@ -302,10 +301,10 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
| 302 | int ecryptfs_read(char *data, loff_t offset, size_t size, | 301 | int ecryptfs_read(char *data, loff_t offset, size_t size, |
| 303 | struct file *ecryptfs_file) | 302 | struct file *ecryptfs_file) |
| 304 | { | 303 | { |
| 304 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; | ||
| 305 | struct page *ecryptfs_page; | 305 | struct page *ecryptfs_page; |
| 306 | char *ecryptfs_page_virt; | 306 | char *ecryptfs_page_virt; |
| 307 | loff_t ecryptfs_file_size = | 307 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); |
| 308 | i_size_read(ecryptfs_file->f_dentry->d_inode); | ||
| 309 | loff_t data_offset = 0; | 308 | loff_t data_offset = 0; |
| 310 | loff_t pos; | 309 | loff_t pos; |
| 311 | int rc = 0; | 310 | int rc = 0; |
| @@ -327,7 +326,7 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
| 327 | 326 | ||
| 328 | if (num_bytes > total_remaining_bytes) | 327 | if (num_bytes > total_remaining_bytes) |
| 329 | num_bytes = total_remaining_bytes; | 328 | num_bytes = total_remaining_bytes; |
| 330 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file, | 329 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, |
| 331 | ecryptfs_page_idx); | 330 | ecryptfs_page_idx); |
| 332 | if (IS_ERR(ecryptfs_page)) { | 331 | if (IS_ERR(ecryptfs_page)) { |
| 333 | rc = PTR_ERR(ecryptfs_page); | 332 | rc = PTR_ERR(ecryptfs_page); |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 0c0ae491d23..0435886e4a9 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
| @@ -109,27 +109,6 @@ void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode) | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | /** | 111 | /** |
| 112 | * ecryptfs_put_super | ||
| 113 | * @sb: Pointer to the ecryptfs super block | ||
| 114 | * | ||
| 115 | * Final actions when unmounting a file system. | ||
| 116 | * This will handle deallocation and release of our private data. | ||
| 117 | */ | ||
| 118 | static void ecryptfs_put_super(struct super_block *sb) | ||
| 119 | { | ||
| 120 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); | ||
| 121 | |||
| 122 | lock_kernel(); | ||
| 123 | |||
| 124 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | ||
| 125 | bdi_destroy(&sb_info->bdi); | ||
| 126 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | ||
| 127 | ecryptfs_set_superblock_private(sb, NULL); | ||
| 128 | |||
| 129 | unlock_kernel(); | ||
| 130 | } | ||
| 131 | |||
| 132 | /** | ||
| 133 | * ecryptfs_statfs | 112 | * ecryptfs_statfs |
| 134 | * @sb: The ecryptfs super block | 113 | * @sb: The ecryptfs super block |
| 135 | * @buf: The struct kstatfs to fill in with stats | 114 | * @buf: The struct kstatfs to fill in with stats |
| @@ -203,7 +182,6 @@ const struct super_operations ecryptfs_sops = { | |||
| 203 | .alloc_inode = ecryptfs_alloc_inode, | 182 | .alloc_inode = ecryptfs_alloc_inode, |
| 204 | .destroy_inode = ecryptfs_destroy_inode, | 183 | .destroy_inode = ecryptfs_destroy_inode, |
| 205 | .drop_inode = generic_delete_inode, | 184 | .drop_inode = generic_delete_inode, |
| 206 | .put_super = ecryptfs_put_super, | ||
| 207 | .statfs = ecryptfs_statfs, | 185 | .statfs = ecryptfs_statfs, |
| 208 | .remount_fs = NULL, | 186 | .remount_fs = NULL, |
| 209 | .clear_inode = ecryptfs_clear_inode, | 187 | .clear_inode = ecryptfs_clear_inode, |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 76d2a79ef93..d7c6afa7975 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
| @@ -1123,16 +1123,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
| 1123 | sbi = sb->s_fs_info; | 1123 | sbi = sb->s_fs_info; |
| 1124 | 1124 | ||
| 1125 | sb->s_dirt = 1; | 1125 | sb->s_dirt = 1; |
| 1126 | inode->i_uid = current->cred->fsuid; | 1126 | inode_init_owner(inode, dir, mode); |
| 1127 | if (dir->i_mode & S_ISGID) { | ||
| 1128 | inode->i_gid = dir->i_gid; | ||
| 1129 | if (S_ISDIR(mode)) | ||
| 1130 | mode |= S_ISGID; | ||
| 1131 | } else { | ||
| 1132 | inode->i_gid = current->cred->fsgid; | ||
| 1133 | } | ||
| 1134 | inode->i_mode = mode; | ||
| 1135 | |||
| 1136 | inode->i_ino = sbi->s_nextid++; | 1127 | inode->i_ino = sbi->s_nextid++; |
| 1137 | inode->i_blkbits = EXOFS_BLKSHIFT; | 1128 | inode->i_blkbits = EXOFS_BLKSHIFT; |
| 1138 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 1129 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index a99e54318c3..ca7e2a0ed98 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
| @@ -420,7 +420,7 @@ release_and_out: | |||
| 420 | return error; | 420 | return error; |
| 421 | } | 421 | } |
| 422 | 422 | ||
| 423 | struct xattr_handler ext2_xattr_acl_access_handler = { | 423 | const struct xattr_handler ext2_xattr_acl_access_handler = { |
| 424 | .prefix = POSIX_ACL_XATTR_ACCESS, | 424 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 425 | .flags = ACL_TYPE_ACCESS, | 425 | .flags = ACL_TYPE_ACCESS, |
| 426 | .list = ext2_xattr_list_acl_access, | 426 | .list = ext2_xattr_list_acl_access, |
| @@ -428,7 +428,7 @@ struct xattr_handler ext2_xattr_acl_access_handler = { | |||
| 428 | .set = ext2_xattr_set_acl, | 428 | .set = ext2_xattr_set_acl, |
| 429 | }; | 429 | }; |
| 430 | 430 | ||
| 431 | struct xattr_handler ext2_xattr_acl_default_handler = { | 431 | const struct xattr_handler ext2_xattr_acl_default_handler = { |
| 432 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 432 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 433 | .flags = ACL_TYPE_DEFAULT, | 433 | .flags = ACL_TYPE_DEFAULT, |
| 434 | .list = ext2_xattr_list_acl_default, | 434 | .list = ext2_xattr_list_acl_default, |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index f0c5286f934..938dbc739d0 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
| @@ -549,16 +549,12 @@ got: | |||
| 549 | 549 | ||
| 550 | sb->s_dirt = 1; | 550 | sb->s_dirt = 1; |
| 551 | mark_buffer_dirty(bh2); | 551 | mark_buffer_dirty(bh2); |
| 552 | inode->i_uid = current_fsuid(); | 552 | if (test_opt(sb, GRPID)) { |
| 553 | if (test_opt (sb, GRPID)) | 553 | inode->i_mode = mode; |
| 554 | inode->i_uid = current_fsuid(); | ||
| 554 | inode->i_gid = dir->i_gid; | 555 | inode->i_gid = dir->i_gid; |
| 555 | else if (dir->i_mode & S_ISGID) { | ||
| 556 | inode->i_gid = dir->i_gid; | ||
| 557 | if (S_ISDIR(mode)) | ||
| 558 | mode |= S_ISGID; | ||
| 559 | } else | 556 | } else |
| 560 | inode->i_gid = current_fsgid(); | 557 | inode_init_owner(inode, dir, mode); |
| 561 | inode->i_mode = mode; | ||
| 562 | 558 | ||
| 563 | inode->i_ino = ino; | 559 | inode->i_ino = ino; |
| 564 | inode->i_blocks = 0; | 560 | inode->i_blocks = 0; |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 3b96045a00c..7c3915780b1 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
| @@ -101,7 +101,7 @@ static void ext2_xattr_rehash(struct ext2_xattr_header *, | |||
| 101 | 101 | ||
| 102 | static struct mb_cache *ext2_xattr_cache; | 102 | static struct mb_cache *ext2_xattr_cache; |
| 103 | 103 | ||
| 104 | static struct xattr_handler *ext2_xattr_handler_map[] = { | 104 | static const struct xattr_handler *ext2_xattr_handler_map[] = { |
| 105 | [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, | 105 | [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, |
| 106 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 106 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
| 107 | [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, | 107 | [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, |
| @@ -113,7 +113,7 @@ static struct xattr_handler *ext2_xattr_handler_map[] = { | |||
| 113 | #endif | 113 | #endif |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | struct xattr_handler *ext2_xattr_handlers[] = { | 116 | const struct xattr_handler *ext2_xattr_handlers[] = { |
| 117 | &ext2_xattr_user_handler, | 117 | &ext2_xattr_user_handler, |
| 118 | &ext2_xattr_trusted_handler, | 118 | &ext2_xattr_trusted_handler, |
| 119 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 119 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
| @@ -126,10 +126,10 @@ struct xattr_handler *ext2_xattr_handlers[] = { | |||
| 126 | NULL | 126 | NULL |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | static inline struct xattr_handler * | 129 | static inline const struct xattr_handler * |
| 130 | ext2_xattr_handler(int name_index) | 130 | ext2_xattr_handler(int name_index) |
| 131 | { | 131 | { |
| 132 | struct xattr_handler *handler = NULL; | 132 | const struct xattr_handler *handler = NULL; |
| 133 | 133 | ||
| 134 | if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map)) | 134 | if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map)) |
| 135 | handler = ext2_xattr_handler_map[name_index]; | 135 | handler = ext2_xattr_handler_map[name_index]; |
| @@ -298,7 +298,7 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", | |||
| 298 | /* list the attribute names */ | 298 | /* list the attribute names */ |
| 299 | for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); | 299 | for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); |
| 300 | entry = EXT2_XATTR_NEXT(entry)) { | 300 | entry = EXT2_XATTR_NEXT(entry)) { |
| 301 | struct xattr_handler *handler = | 301 | const struct xattr_handler *handler = |
| 302 | ext2_xattr_handler(entry->e_name_index); | 302 | ext2_xattr_handler(entry->e_name_index); |
| 303 | 303 | ||
| 304 | if (handler) { | 304 | if (handler) { |
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h index bf8175b2ced..a1a1c218461 100644 --- a/fs/ext2/xattr.h +++ b/fs/ext2/xattr.h | |||
| @@ -55,11 +55,11 @@ struct ext2_xattr_entry { | |||
| 55 | 55 | ||
| 56 | # ifdef CONFIG_EXT2_FS_XATTR | 56 | # ifdef CONFIG_EXT2_FS_XATTR |
| 57 | 57 | ||
| 58 | extern struct xattr_handler ext2_xattr_user_handler; | 58 | extern const struct xattr_handler ext2_xattr_user_handler; |
| 59 | extern struct xattr_handler ext2_xattr_trusted_handler; | 59 | extern const struct xattr_handler ext2_xattr_trusted_handler; |
| 60 | extern struct xattr_handler ext2_xattr_acl_access_handler; | 60 | extern const struct xattr_handler ext2_xattr_acl_access_handler; |
| 61 | extern struct xattr_handler ext2_xattr_acl_default_handler; | 61 | extern const struct xattr_handler ext2_xattr_acl_default_handler; |
| 62 | extern struct xattr_handler ext2_xattr_security_handler; | 62 | extern const struct xattr_handler ext2_xattr_security_handler; |
| 63 | 63 | ||
| 64 | extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); | 64 | extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); |
| 65 | 65 | ||
| @@ -72,7 +72,7 @@ extern void ext2_xattr_put_super(struct super_block *); | |||
| 72 | extern int init_ext2_xattr(void); | 72 | extern int init_ext2_xattr(void); |
| 73 | extern void exit_ext2_xattr(void); | 73 | extern void exit_ext2_xattr(void); |
| 74 | 74 | ||
| 75 | extern struct xattr_handler *ext2_xattr_handlers[]; | 75 | extern const struct xattr_handler *ext2_xattr_handlers[]; |
| 76 | 76 | ||
| 77 | # else /* CONFIG_EXT2_FS_XATTR */ | 77 | # else /* CONFIG_EXT2_FS_XATTR */ |
| 78 | 78 | ||
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index b118c6383c6..3004e15d5da 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
| @@ -67,7 +67,7 @@ ext2_init_security(struct inode *inode, struct inode *dir) | |||
| 67 | return err; | 67 | return err; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | struct xattr_handler ext2_xattr_security_handler = { | 70 | const struct xattr_handler ext2_xattr_security_handler = { |
| 71 | .prefix = XATTR_SECURITY_PREFIX, | 71 | .prefix = XATTR_SECURITY_PREFIX, |
| 72 | .list = ext2_xattr_security_list, | 72 | .list = ext2_xattr_security_list, |
| 73 | .get = ext2_xattr_security_get, | 73 | .get = ext2_xattr_security_get, |
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 2a26d71f477..667e46a8d62 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c | |||
| @@ -50,7 +50,7 @@ ext2_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
| 50 | value, size, flags); | 50 | value, size, flags); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | struct xattr_handler ext2_xattr_trusted_handler = { | 53 | const struct xattr_handler ext2_xattr_trusted_handler = { |
| 54 | .prefix = XATTR_TRUSTED_PREFIX, | 54 | .prefix = XATTR_TRUSTED_PREFIX, |
| 55 | .list = ext2_xattr_trusted_list, | 55 | .list = ext2_xattr_trusted_list, |
| 56 | .get = ext2_xattr_trusted_get, | 56 | .get = ext2_xattr_trusted_get, |
diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 3f6caf3684b..099d20f4716 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c | |||
| @@ -54,7 +54,7 @@ ext2_xattr_user_set(struct dentry *dentry, const char *name, | |||
| 54 | name, value, size, flags); | 54 | name, value, size, flags); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | struct xattr_handler ext2_xattr_user_handler = { | 57 | const struct xattr_handler ext2_xattr_user_handler = { |
| 58 | .prefix = XATTR_USER_PREFIX, | 58 | .prefix = XATTR_USER_PREFIX, |
| 59 | .list = ext2_xattr_user_list, | 59 | .list = ext2_xattr_user_list, |
| 60 | .get = ext2_xattr_user_get, | 60 | .get = ext2_xattr_user_get, |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 82ba3415866..01552abbca3 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
| @@ -456,7 +456,7 @@ release_and_out: | |||
| 456 | return error; | 456 | return error; |
| 457 | } | 457 | } |
| 458 | 458 | ||
| 459 | struct xattr_handler ext3_xattr_acl_access_handler = { | 459 | const struct xattr_handler ext3_xattr_acl_access_handler = { |
| 460 | .prefix = POSIX_ACL_XATTR_ACCESS, | 460 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 461 | .flags = ACL_TYPE_ACCESS, | 461 | .flags = ACL_TYPE_ACCESS, |
| 462 | .list = ext3_xattr_list_acl_access, | 462 | .list = ext3_xattr_list_acl_access, |
| @@ -464,7 +464,7 @@ struct xattr_handler ext3_xattr_acl_access_handler = { | |||
| 464 | .set = ext3_xattr_set_acl, | 464 | .set = ext3_xattr_set_acl, |
| 465 | }; | 465 | }; |
| 466 | 466 | ||
| 467 | struct xattr_handler ext3_xattr_acl_default_handler = { | 467 | const struct xattr_handler ext3_xattr_acl_default_handler = { |
| 468 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 468 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 469 | .flags = ACL_TYPE_DEFAULT, | 469 | .flags = ACL_TYPE_DEFAULT, |
| 470 | .list = ext3_xattr_list_acl_default, | 470 | .list = ext3_xattr_list_acl_default, |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 0d0e97ed3ff..498021eb88f 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
| @@ -538,16 +538,13 @@ got: | |||
| 538 | if (S_ISDIR(mode)) | 538 | if (S_ISDIR(mode)) |
| 539 | percpu_counter_inc(&sbi->s_dirs_counter); | 539 | percpu_counter_inc(&sbi->s_dirs_counter); |
| 540 | 540 | ||
| 541 | inode->i_uid = current_fsuid(); | 541 | |
| 542 | if (test_opt (sb, GRPID)) | 542 | if (test_opt(sb, GRPID)) { |
| 543 | inode->i_gid = dir->i_gid; | 543 | inode->i_mode = mode; |
| 544 | else if (dir->i_mode & S_ISGID) { | 544 | inode->i_uid = current_fsuid(); |
| 545 | inode->i_gid = dir->i_gid; | 545 | inode->i_gid = dir->i_gid; |
| 546 | if (S_ISDIR(mode)) | ||
| 547 | mode |= S_ISGID; | ||
| 548 | } else | 546 | } else |
| 549 | inode->i_gid = current_fsgid(); | 547 | inode_init_owner(inode, dir, mode); |
| 550 | inode->i_mode = mode; | ||
| 551 | 548 | ||
| 552 | inode->i_ino = ino; | 549 | inode->i_ino = ino; |
| 553 | /* This is the optimal IO size (for stat), not the fs block size */ | 550 | /* This is the optimal IO size (for stat), not the fs block size */ |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 534a94c3a93..71fb8d65e54 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
| @@ -104,7 +104,7 @@ static int ext3_xattr_list(struct dentry *dentry, char *buffer, | |||
| 104 | 104 | ||
| 105 | static struct mb_cache *ext3_xattr_cache; | 105 | static struct mb_cache *ext3_xattr_cache; |
| 106 | 106 | ||
| 107 | static struct xattr_handler *ext3_xattr_handler_map[] = { | 107 | static const struct xattr_handler *ext3_xattr_handler_map[] = { |
| 108 | [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler, | 108 | [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler, |
| 109 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 109 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
| 110 | [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext3_xattr_acl_access_handler, | 110 | [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext3_xattr_acl_access_handler, |
| @@ -116,7 +116,7 @@ static struct xattr_handler *ext3_xattr_handler_map[] = { | |||
| 116 | #endif | 116 | #endif |
| 117 | }; | 117 | }; |
| 118 | 118 | ||
| 119 | struct xattr_handler *ext3_xattr_handlers[] = { | 119 | const struct xattr_handler *ext3_xattr_handlers[] = { |
| 120 | &ext3_xattr_user_handler, | 120 | &ext3_xattr_user_handler, |
| 121 | &ext3_xattr_trusted_handler, | 121 | &ext3_xattr_trusted_handler, |
| 122 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 122 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
| @@ -129,10 +129,10 @@ struct xattr_handler *ext3_xattr_handlers[] = { | |||
| 129 | NULL | 129 | NULL |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| 132 | static inline struct xattr_handler * | 132 | static inline const struct xattr_handler * |
| 133 | ext3_xattr_handler(int name_index) | 133 | ext3_xattr_handler(int name_index) |
| 134 | { | 134 | { |
| 135 | struct xattr_handler *handler = NULL; | 135 | const struct xattr_handler *handler = NULL; |
| 136 | 136 | ||
| 137 | if (name_index > 0 && name_index < ARRAY_SIZE(ext3_xattr_handler_map)) | 137 | if (name_index > 0 && name_index < ARRAY_SIZE(ext3_xattr_handler_map)) |
| 138 | handler = ext3_xattr_handler_map[name_index]; | 138 | handler = ext3_xattr_handler_map[name_index]; |
| @@ -338,7 +338,7 @@ ext3_xattr_list_entries(struct dentry *dentry, struct ext3_xattr_entry *entry, | |||
| 338 | size_t rest = buffer_size; | 338 | size_t rest = buffer_size; |
| 339 | 339 | ||
| 340 | for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) { | 340 | for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) { |
| 341 | struct xattr_handler *handler = | 341 | const struct xattr_handler *handler = |
| 342 | ext3_xattr_handler(entry->e_name_index); | 342 | ext3_xattr_handler(entry->e_name_index); |
| 343 | 343 | ||
| 344 | if (handler) { | 344 | if (handler) { |
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h index 148a4dfc82a..377fe720116 100644 --- a/fs/ext3/xattr.h +++ b/fs/ext3/xattr.h | |||
| @@ -58,11 +58,11 @@ struct ext3_xattr_entry { | |||
| 58 | 58 | ||
| 59 | # ifdef CONFIG_EXT3_FS_XATTR | 59 | # ifdef CONFIG_EXT3_FS_XATTR |
| 60 | 60 | ||
| 61 | extern struct xattr_handler ext3_xattr_user_handler; | 61 | extern const struct xattr_handler ext3_xattr_user_handler; |
| 62 | extern struct xattr_handler ext3_xattr_trusted_handler; | 62 | extern const struct xattr_handler ext3_xattr_trusted_handler; |
| 63 | extern struct xattr_handler ext3_xattr_acl_access_handler; | 63 | extern const struct xattr_handler ext3_xattr_acl_access_handler; |
| 64 | extern struct xattr_handler ext3_xattr_acl_default_handler; | 64 | extern const struct xattr_handler ext3_xattr_acl_default_handler; |
| 65 | extern struct xattr_handler ext3_xattr_security_handler; | 65 | extern const struct xattr_handler ext3_xattr_security_handler; |
| 66 | 66 | ||
| 67 | extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); | 67 | extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); |
| 68 | 68 | ||
| @@ -76,7 +76,7 @@ extern void ext3_xattr_put_super(struct super_block *); | |||
| 76 | extern int init_ext3_xattr(void); | 76 | extern int init_ext3_xattr(void); |
| 77 | extern void exit_ext3_xattr(void); | 77 | extern void exit_ext3_xattr(void); |
| 78 | 78 | ||
| 79 | extern struct xattr_handler *ext3_xattr_handlers[]; | 79 | extern const struct xattr_handler *ext3_xattr_handlers[]; |
| 80 | 80 | ||
| 81 | # else /* CONFIG_EXT3_FS_XATTR */ | 81 | # else /* CONFIG_EXT3_FS_XATTR */ |
| 82 | 82 | ||
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c index 3af91f476df..03a99bfc59f 100644 --- a/fs/ext3/xattr_security.c +++ b/fs/ext3/xattr_security.c | |||
| @@ -69,7 +69,7 @@ ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir) | |||
| 69 | return err; | 69 | return err; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | struct xattr_handler ext3_xattr_security_handler = { | 72 | const struct xattr_handler ext3_xattr_security_handler = { |
| 73 | .prefix = XATTR_SECURITY_PREFIX, | 73 | .prefix = XATTR_SECURITY_PREFIX, |
| 74 | .list = ext3_xattr_security_list, | 74 | .list = ext3_xattr_security_list, |
| 75 | .get = ext3_xattr_security_get, | 75 | .get = ext3_xattr_security_get, |
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c index e5562845ed9..dc8edda9ffe 100644 --- a/fs/ext3/xattr_trusted.c +++ b/fs/ext3/xattr_trusted.c | |||
| @@ -51,7 +51,7 @@ ext3_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
| 51 | value, size, flags); | 51 | value, size, flags); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | struct xattr_handler ext3_xattr_trusted_handler = { | 54 | const struct xattr_handler ext3_xattr_trusted_handler = { |
| 55 | .prefix = XATTR_TRUSTED_PREFIX, | 55 | .prefix = XATTR_TRUSTED_PREFIX, |
| 56 | .list = ext3_xattr_trusted_list, | 56 | .list = ext3_xattr_trusted_list, |
| 57 | .get = ext3_xattr_trusted_get, | 57 | .get = ext3_xattr_trusted_get, |
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c index 3bcfe9ee0a6..7a321974d58 100644 --- a/fs/ext3/xattr_user.c +++ b/fs/ext3/xattr_user.c | |||
| @@ -54,7 +54,7 @@ ext3_xattr_user_set(struct dentry *dentry, const char *name, | |||
| 54 | name, value, size, flags); | 54 | name, value, size, flags); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | struct xattr_handler ext3_xattr_user_handler = { | 57 | const struct xattr_handler ext3_xattr_user_handler = { |
| 58 | .prefix = XATTR_USER_PREFIX, | 58 | .prefix = XATTR_USER_PREFIX, |
| 59 | .list = ext3_xattr_user_list, | 59 | .list = ext3_xattr_user_list, |
| 60 | .get = ext3_xattr_user_get, | 60 | .get = ext3_xattr_user_get, |
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 8a2a29d35a6..feaf498feaa 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
| @@ -454,7 +454,7 @@ release_and_out: | |||
| 454 | return error; | 454 | return error; |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | struct xattr_handler ext4_xattr_acl_access_handler = { | 457 | const struct xattr_handler ext4_xattr_acl_access_handler = { |
| 458 | .prefix = POSIX_ACL_XATTR_ACCESS, | 458 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 459 | .flags = ACL_TYPE_ACCESS, | 459 | .flags = ACL_TYPE_ACCESS, |
| 460 | .list = ext4_xattr_list_acl_access, | 460 | .list = ext4_xattr_list_acl_access, |
| @@ -462,7 +462,7 @@ struct xattr_handler ext4_xattr_acl_access_handler = { | |||
| 462 | .set = ext4_xattr_set_acl, | 462 | .set = ext4_xattr_set_acl, |
| 463 | }; | 463 | }; |
| 464 | 464 | ||
| 465 | struct xattr_handler ext4_xattr_acl_default_handler = { | 465 | const struct xattr_handler ext4_xattr_acl_default_handler = { |
| 466 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 466 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 467 | .flags = ACL_TYPE_DEFAULT, | 467 | .flags = ACL_TYPE_DEFAULT, |
| 468 | .list = ext4_xattr_list_acl_default, | 468 | .list = ext4_xattr_list_acl_default, |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 57f6eef6ccd..1a0e183a2f0 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -979,16 +979,12 @@ got: | |||
| 979 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); | 979 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); |
| 980 | } | 980 | } |
| 981 | 981 | ||
| 982 | inode->i_uid = current_fsuid(); | 982 | if (test_opt(sb, GRPID)) { |
| 983 | if (test_opt(sb, GRPID)) | 983 | inode->i_mode = mode; |
| 984 | inode->i_uid = current_fsuid(); | ||
| 984 | inode->i_gid = dir->i_gid; | 985 | inode->i_gid = dir->i_gid; |
| 985 | else if (dir->i_mode & S_ISGID) { | ||
| 986 | inode->i_gid = dir->i_gid; | ||
| 987 | if (S_ISDIR(mode)) | ||
| 988 | mode |= S_ISGID; | ||
| 989 | } else | 986 | } else |
| 990 | inode->i_gid = current_fsgid(); | 987 | inode_init_owner(inode, dir, mode); |
| 991 | inode->i_mode = mode; | ||
| 992 | 988 | ||
| 993 | inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); | 989 | inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); |
| 994 | /* This is the optimal IO size (for stat), not the fs block size */ | 990 | /* This is the optimal IO size (for stat), not the fs block size */ |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index b4c5aa8489d..2de0e951508 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
| @@ -97,7 +97,7 @@ static int ext4_xattr_list(struct dentry *dentry, char *buffer, | |||
| 97 | 97 | ||
| 98 | static struct mb_cache *ext4_xattr_cache; | 98 | static struct mb_cache *ext4_xattr_cache; |
| 99 | 99 | ||
| 100 | static struct xattr_handler *ext4_xattr_handler_map[] = { | 100 | static const struct xattr_handler *ext4_xattr_handler_map[] = { |
| 101 | [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, | 101 | [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, |
| 102 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 102 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
| 103 | [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext4_xattr_acl_access_handler, | 103 | [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext4_xattr_acl_access_handler, |
| @@ -109,7 +109,7 @@ static struct xattr_handler *ext4_xattr_handler_map[] = { | |||
| 109 | #endif | 109 | #endif |
| 110 | }; | 110 | }; |
| 111 | 111 | ||
| 112 | struct xattr_handler *ext4_xattr_handlers[] = { | 112 | const struct xattr_handler *ext4_xattr_handlers[] = { |
| 113 | &ext4_xattr_user_handler, | 113 | &ext4_xattr_user_handler, |
| 114 | &ext4_xattr_trusted_handler, | 114 | &ext4_xattr_trusted_handler, |
| 115 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 115 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
| @@ -122,10 +122,10 @@ struct xattr_handler *ext4_xattr_handlers[] = { | |||
| 122 | NULL | 122 | NULL |
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | static inline struct xattr_handler * | 125 | static inline const struct xattr_handler * |
| 126 | ext4_xattr_handler(int name_index) | 126 | ext4_xattr_handler(int name_index) |
| 127 | { | 127 | { |
| 128 | struct xattr_handler *handler = NULL; | 128 | const struct xattr_handler *handler = NULL; |
| 129 | 129 | ||
| 130 | if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map)) | 130 | if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map)) |
| 131 | handler = ext4_xattr_handler_map[name_index]; | 131 | handler = ext4_xattr_handler_map[name_index]; |
| @@ -332,7 +332,7 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, | |||
| 332 | size_t rest = buffer_size; | 332 | size_t rest = buffer_size; |
| 333 | 333 | ||
| 334 | for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { | 334 | for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { |
| 335 | struct xattr_handler *handler = | 335 | const struct xattr_handler *handler = |
| 336 | ext4_xattr_handler(entry->e_name_index); | 336 | ext4_xattr_handler(entry->e_name_index); |
| 337 | 337 | ||
| 338 | if (handler) { | 338 | if (handler) { |
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 8ede88b18c2..518e96e4390 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
| @@ -65,11 +65,11 @@ struct ext4_xattr_entry { | |||
| 65 | 65 | ||
| 66 | # ifdef CONFIG_EXT4_FS_XATTR | 66 | # ifdef CONFIG_EXT4_FS_XATTR |
| 67 | 67 | ||
| 68 | extern struct xattr_handler ext4_xattr_user_handler; | 68 | extern const struct xattr_handler ext4_xattr_user_handler; |
| 69 | extern struct xattr_handler ext4_xattr_trusted_handler; | 69 | extern const struct xattr_handler ext4_xattr_trusted_handler; |
| 70 | extern struct xattr_handler ext4_xattr_acl_access_handler; | 70 | extern const struct xattr_handler ext4_xattr_acl_access_handler; |
| 71 | extern struct xattr_handler ext4_xattr_acl_default_handler; | 71 | extern const struct xattr_handler ext4_xattr_acl_default_handler; |
| 72 | extern struct xattr_handler ext4_xattr_security_handler; | 72 | extern const struct xattr_handler ext4_xattr_security_handler; |
| 73 | 73 | ||
| 74 | extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); | 74 | extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); |
| 75 | 75 | ||
| @@ -86,7 +86,7 @@ extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | |||
| 86 | extern int init_ext4_xattr(void); | 86 | extern int init_ext4_xattr(void); |
| 87 | extern void exit_ext4_xattr(void); | 87 | extern void exit_ext4_xattr(void); |
| 88 | 88 | ||
| 89 | extern struct xattr_handler *ext4_xattr_handlers[]; | 89 | extern const struct xattr_handler *ext4_xattr_handlers[]; |
| 90 | 90 | ||
| 91 | # else /* CONFIG_EXT4_FS_XATTR */ | 91 | # else /* CONFIG_EXT4_FS_XATTR */ |
| 92 | 92 | ||
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index 8b145e98df0..9b21268e121 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c | |||
| @@ -69,7 +69,7 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir) | |||
| 69 | return err; | 69 | return err; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | struct xattr_handler ext4_xattr_security_handler = { | 72 | const struct xattr_handler ext4_xattr_security_handler = { |
| 73 | .prefix = XATTR_SECURITY_PREFIX, | 73 | .prefix = XATTR_SECURITY_PREFIX, |
| 74 | .list = ext4_xattr_security_list, | 74 | .list = ext4_xattr_security_list, |
| 75 | .get = ext4_xattr_security_get, | 75 | .get = ext4_xattr_security_get, |
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index 15b50edc658..37e6ebca2cc 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c | |||
| @@ -51,7 +51,7 @@ ext4_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
| 51 | name, value, size, flags); | 51 | name, value, size, flags); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | struct xattr_handler ext4_xattr_trusted_handler = { | 54 | const struct xattr_handler ext4_xattr_trusted_handler = { |
| 55 | .prefix = XATTR_TRUSTED_PREFIX, | 55 | .prefix = XATTR_TRUSTED_PREFIX, |
| 56 | .list = ext4_xattr_trusted_list, | 56 | .list = ext4_xattr_trusted_list, |
| 57 | .get = ext4_xattr_trusted_get, | 57 | .get = ext4_xattr_trusted_get, |
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index c4ce05746ce..98c375352d0 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c | |||
| @@ -54,7 +54,7 @@ ext4_xattr_user_set(struct dentry *dentry, const char *name, | |||
| 54 | name, value, size, flags); | 54 | name, value, size, flags); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | struct xattr_handler ext4_xattr_user_handler = { | 57 | const struct xattr_handler ext4_xattr_user_handler = { |
| 58 | .prefix = XATTR_USER_PREFIX, | 58 | .prefix = XATTR_USER_PREFIX, |
| 59 | .list = ext4_xattr_user_list, | 59 | .list = ext4_xattr_user_list, |
| 60 | .get = ext4_xattr_user_get, | 60 | .get = ext4_xattr_user_get, |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 437a7431b4e..5c4161f1fd9 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -42,10 +42,10 @@ struct wb_writeback_args { | |||
| 42 | long nr_pages; | 42 | long nr_pages; |
| 43 | struct super_block *sb; | 43 | struct super_block *sb; |
| 44 | enum writeback_sync_modes sync_mode; | 44 | enum writeback_sync_modes sync_mode; |
| 45 | int for_kupdate:1; | 45 | unsigned int for_kupdate:1; |
| 46 | int range_cyclic:1; | 46 | unsigned int range_cyclic:1; |
| 47 | int for_background:1; | 47 | unsigned int for_background:1; |
| 48 | int sb_pinned:1; | 48 | unsigned int sb_pinned:1; |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | /* | 51 | /* |
diff --git a/fs/generic_acl.c b/fs/generic_acl.c index fe5df545765..99800e56415 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c | |||
| @@ -201,7 +201,7 @@ generic_check_acl(struct inode *inode, int mask) | |||
| 201 | return -EAGAIN; | 201 | return -EAGAIN; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | struct xattr_handler generic_acl_access_handler = { | 204 | const struct xattr_handler generic_acl_access_handler = { |
| 205 | .prefix = POSIX_ACL_XATTR_ACCESS, | 205 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 206 | .flags = ACL_TYPE_ACCESS, | 206 | .flags = ACL_TYPE_ACCESS, |
| 207 | .list = generic_acl_list, | 207 | .list = generic_acl_list, |
| @@ -209,7 +209,7 @@ struct xattr_handler generic_acl_access_handler = { | |||
| 209 | .set = generic_acl_set, | 209 | .set = generic_acl_set, |
| 210 | }; | 210 | }; |
| 211 | 211 | ||
| 212 | struct xattr_handler generic_acl_default_handler = { | 212 | const struct xattr_handler generic_acl_default_handler = { |
| 213 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 213 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 214 | .flags = ACL_TYPE_DEFAULT, | 214 | .flags = ACL_TYPE_DEFAULT, |
| 215 | .list = generic_acl_list, | 215 | .list = generic_acl_list, |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 87ee309d4c2..9fb76b0a048 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
| @@ -335,7 +335,7 @@ out: | |||
| 335 | return error; | 335 | return error; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | struct xattr_handler gfs2_xattr_system_handler = { | 338 | const struct xattr_handler gfs2_xattr_system_handler = { |
| 339 | .prefix = XATTR_SYSTEM_PREFIX, | 339 | .prefix = XATTR_SYSTEM_PREFIX, |
| 340 | .flags = GFS2_EATYPE_SYS, | 340 | .flags = GFS2_EATYPE_SYS, |
| 341 | .get = gfs2_xattr_system_get, | 341 | .get = gfs2_xattr_system_get, |
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index 9306a2e6620..b522b0cb39e 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h | |||
| @@ -19,6 +19,6 @@ | |||
| 19 | extern int gfs2_check_acl(struct inode *inode, int mask); | 19 | extern int gfs2_check_acl(struct inode *inode, int mask); |
| 20 | extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); | 20 | extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); |
| 21 | extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); | 21 | extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); |
| 22 | extern struct xattr_handler gfs2_xattr_system_handler; | 22 | extern const struct xattr_handler gfs2_xattr_system_handler; |
| 23 | 23 | ||
| 24 | #endif /* __ACL_DOT_H__ */ | 24 | #endif /* __ACL_DOT_H__ */ |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 3df60f2d84e..a0464680af0 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
| @@ -54,7 +54,7 @@ extern struct file_system_type gfs2meta_fs_type; | |||
| 54 | extern const struct export_operations gfs2_export_ops; | 54 | extern const struct export_operations gfs2_export_ops; |
| 55 | extern const struct super_operations gfs2_super_ops; | 55 | extern const struct super_operations gfs2_super_ops; |
| 56 | extern const struct dentry_operations gfs2_dops; | 56 | extern const struct dentry_operations gfs2_dops; |
| 57 | extern struct xattr_handler *gfs2_xattr_handlers[]; | 57 | extern const struct xattr_handler *gfs2_xattr_handlers[]; |
| 58 | 58 | ||
| 59 | #endif /* __SUPER_DOT_H__ */ | 59 | #endif /* __SUPER_DOT_H__ */ |
| 60 | 60 | ||
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index c2ebdf2c01d..82f93da00d1 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
| @@ -1535,21 +1535,21 @@ out_alloc: | |||
| 1535 | return error; | 1535 | return error; |
| 1536 | } | 1536 | } |
| 1537 | 1537 | ||
| 1538 | static struct xattr_handler gfs2_xattr_user_handler = { | 1538 | static const struct xattr_handler gfs2_xattr_user_handler = { |
| 1539 | .prefix = XATTR_USER_PREFIX, | 1539 | .prefix = XATTR_USER_PREFIX, |
| 1540 | .flags = GFS2_EATYPE_USR, | 1540 | .flags = GFS2_EATYPE_USR, |
| 1541 | .get = gfs2_xattr_get, | 1541 | .get = gfs2_xattr_get, |
| 1542 | .set = gfs2_xattr_set, | 1542 | .set = gfs2_xattr_set, |
| 1543 | }; | 1543 | }; |
| 1544 | 1544 | ||
| 1545 | static struct xattr_handler gfs2_xattr_security_handler = { | 1545 | static const struct xattr_handler gfs2_xattr_security_handler = { |
| 1546 | .prefix = XATTR_SECURITY_PREFIX, | 1546 | .prefix = XATTR_SECURITY_PREFIX, |
| 1547 | .flags = GFS2_EATYPE_SECURITY, | 1547 | .flags = GFS2_EATYPE_SECURITY, |
| 1548 | .get = gfs2_xattr_get, | 1548 | .get = gfs2_xattr_get, |
| 1549 | .set = gfs2_xattr_set, | 1549 | .set = gfs2_xattr_set, |
| 1550 | }; | 1550 | }; |
| 1551 | 1551 | ||
| 1552 | struct xattr_handler *gfs2_xattr_handlers[] = { | 1552 | const struct xattr_handler *gfs2_xattr_handlers[] = { |
| 1553 | &gfs2_xattr_user_handler, | 1553 | &gfs2_xattr_user_handler, |
| 1554 | &gfs2_xattr_security_handler, | 1554 | &gfs2_xattr_security_handler, |
| 1555 | &gfs2_xattr_system_handler, | 1555 | &gfs2_xattr_system_handler, |
diff --git a/fs/inode.c b/fs/inode.c index 258ec22bb29..2bee20ae3d6 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -286,11 +286,9 @@ static void init_once(void *foo) | |||
| 286 | */ | 286 | */ |
| 287 | void __iget(struct inode *inode) | 287 | void __iget(struct inode *inode) |
| 288 | { | 288 | { |
| 289 | if (atomic_read(&inode->i_count)) { | 289 | if (atomic_inc_return(&inode->i_count) != 1) |
| 290 | atomic_inc(&inode->i_count); | ||
| 291 | return; | 290 | return; |
| 292 | } | 291 | |
| 293 | atomic_inc(&inode->i_count); | ||
| 294 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | 292 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) |
| 295 | list_move(&inode->i_list, &inode_in_use); | 293 | list_move(&inode->i_list, &inode_in_use); |
| 296 | inodes_stat.nr_unused--; | 294 | inodes_stat.nr_unused--; |
| @@ -1608,3 +1606,23 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) | |||
| 1608 | inode->i_ino); | 1606 | inode->i_ino); |
| 1609 | } | 1607 | } |
| 1610 | EXPORT_SYMBOL(init_special_inode); | 1608 | EXPORT_SYMBOL(init_special_inode); |
| 1609 | |||
| 1610 | /** | ||
| 1611 | * Init uid,gid,mode for new inode according to posix standards | ||
| 1612 | * @inode: New inode | ||
| 1613 | * @dir: Directory inode | ||
| 1614 | * @mode: mode of the new inode | ||
| 1615 | */ | ||
| 1616 | void inode_init_owner(struct inode *inode, const struct inode *dir, | ||
| 1617 | mode_t mode) | ||
| 1618 | { | ||
| 1619 | inode->i_uid = current_fsuid(); | ||
| 1620 | if (dir && dir->i_mode & S_ISGID) { | ||
| 1621 | inode->i_gid = dir->i_gid; | ||
| 1622 | if (S_ISDIR(mode)) | ||
| 1623 | mode |= S_ISGID; | ||
| 1624 | } else | ||
| 1625 | inode->i_gid = current_fsgid(); | ||
| 1626 | inode->i_mode = mode; | ||
| 1627 | } | ||
| 1628 | EXPORT_SYMBOL(inode_init_owner); | ||
diff --git a/fs/internal.h b/fs/internal.h index 8a03a5447bd..6b706bc60a6 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
| @@ -87,6 +87,8 @@ extern struct file *get_empty_filp(void); | |||
| 87 | * super.c | 87 | * super.c |
| 88 | */ | 88 | */ |
| 89 | extern int do_remount_sb(struct super_block *, int, void *, int); | 89 | extern int do_remount_sb(struct super_block *, int, void *, int); |
| 90 | extern void __put_super(struct super_block *sb); | ||
| 91 | extern void put_super(struct super_block *sb); | ||
| 90 | 92 | ||
| 91 | /* | 93 | /* |
| 92 | * open.c | 94 | * open.c |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 7faefb4da93..2d140a71386 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
| @@ -525,15 +525,8 @@ static int ioctl_fsfreeze(struct file *filp) | |||
| 525 | if (sb->s_op->freeze_fs == NULL) | 525 | if (sb->s_op->freeze_fs == NULL) |
| 526 | return -EOPNOTSUPP; | 526 | return -EOPNOTSUPP; |
| 527 | 527 | ||
| 528 | /* If a blockdevice-backed filesystem isn't specified, return. */ | ||
| 529 | if (sb->s_bdev == NULL) | ||
| 530 | return -EINVAL; | ||
| 531 | |||
| 532 | /* Freeze */ | 528 | /* Freeze */ |
| 533 | sb = freeze_bdev(sb->s_bdev); | 529 | return freeze_super(sb); |
| 534 | if (IS_ERR(sb)) | ||
| 535 | return PTR_ERR(sb); | ||
| 536 | return 0; | ||
| 537 | } | 530 | } |
| 538 | 531 | ||
| 539 | static int ioctl_fsthaw(struct file *filp) | 532 | static int ioctl_fsthaw(struct file *filp) |
| @@ -543,12 +536,8 @@ static int ioctl_fsthaw(struct file *filp) | |||
| 543 | if (!capable(CAP_SYS_ADMIN)) | 536 | if (!capable(CAP_SYS_ADMIN)) |
| 544 | return -EPERM; | 537 | return -EPERM; |
| 545 | 538 | ||
| 546 | /* If a blockdevice-backed filesystem isn't specified, return EINVAL. */ | ||
| 547 | if (sb->s_bdev == NULL) | ||
| 548 | return -EINVAL; | ||
| 549 | |||
| 550 | /* Thaw */ | 539 | /* Thaw */ |
| 551 | return thaw_bdev(sb->s_bdev, sb); | 540 | return thaw_super(sb); |
| 552 | } | 541 | } |
| 553 | 542 | ||
| 554 | /* | 543 | /* |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 7cdc3196476..a33aab6b5e6 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
| @@ -419,7 +419,7 @@ static int jffs2_acl_setxattr(struct dentry *dentry, const char *name, | |||
| 419 | return rc; | 419 | return rc; |
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | struct xattr_handler jffs2_acl_access_xattr_handler = { | 422 | const struct xattr_handler jffs2_acl_access_xattr_handler = { |
| 423 | .prefix = POSIX_ACL_XATTR_ACCESS, | 423 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 424 | .flags = ACL_TYPE_DEFAULT, | 424 | .flags = ACL_TYPE_DEFAULT, |
| 425 | .list = jffs2_acl_access_listxattr, | 425 | .list = jffs2_acl_access_listxattr, |
| @@ -427,7 +427,7 @@ struct xattr_handler jffs2_acl_access_xattr_handler = { | |||
| 427 | .set = jffs2_acl_setxattr, | 427 | .set = jffs2_acl_setxattr, |
| 428 | }; | 428 | }; |
| 429 | 429 | ||
| 430 | struct xattr_handler jffs2_acl_default_xattr_handler = { | 430 | const struct xattr_handler jffs2_acl_default_xattr_handler = { |
| 431 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 431 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 432 | .flags = ACL_TYPE_DEFAULT, | 432 | .flags = ACL_TYPE_DEFAULT, |
| 433 | .list = jffs2_acl_default_listxattr, | 433 | .list = jffs2_acl_default_listxattr, |
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index f0ba63e3c36..5e42de8d954 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h | |||
| @@ -31,8 +31,8 @@ extern int jffs2_acl_chmod(struct inode *); | |||
| 31 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); | 31 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); |
| 32 | extern int jffs2_init_acl_post(struct inode *); | 32 | extern int jffs2_init_acl_post(struct inode *); |
| 33 | 33 | ||
| 34 | extern struct xattr_handler jffs2_acl_access_xattr_handler; | 34 | extern const struct xattr_handler jffs2_acl_access_xattr_handler; |
| 35 | extern struct xattr_handler jffs2_acl_default_xattr_handler; | 35 | extern const struct xattr_handler jffs2_acl_default_xattr_handler; |
| 36 | 36 | ||
| 37 | #else | 37 | #else |
| 38 | 38 | ||
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c index eaccee05858..239f51216a6 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c | |||
| @@ -77,7 +77,7 @@ static size_t jffs2_security_listxattr(struct dentry *dentry, char *list, | |||
| 77 | return retlen; | 77 | return retlen; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | struct xattr_handler jffs2_security_xattr_handler = { | 80 | const struct xattr_handler jffs2_security_xattr_handler = { |
| 81 | .prefix = XATTR_SECURITY_PREFIX, | 81 | .prefix = XATTR_SECURITY_PREFIX, |
| 82 | .list = jffs2_security_listxattr, | 82 | .list = jffs2_security_listxattr, |
| 83 | .set = jffs2_security_setxattr, | 83 | .set = jffs2_security_setxattr, |
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 9e75c62c85d..a2d58c96f1b 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
| @@ -904,7 +904,7 @@ struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, | |||
| 904 | * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags) | 904 | * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags) |
| 905 | * is an implementation of setxattr handler on jffs2. | 905 | * is an implementation of setxattr handler on jffs2. |
| 906 | * -------------------------------------------------- */ | 906 | * -------------------------------------------------- */ |
| 907 | struct xattr_handler *jffs2_xattr_handlers[] = { | 907 | const struct xattr_handler *jffs2_xattr_handlers[] = { |
| 908 | &jffs2_user_xattr_handler, | 908 | &jffs2_user_xattr_handler, |
| 909 | #ifdef CONFIG_JFFS2_FS_SECURITY | 909 | #ifdef CONFIG_JFFS2_FS_SECURITY |
| 910 | &jffs2_security_xattr_handler, | 910 | &jffs2_security_xattr_handler, |
| @@ -917,8 +917,8 @@ struct xattr_handler *jffs2_xattr_handlers[] = { | |||
| 917 | NULL | 917 | NULL |
| 918 | }; | 918 | }; |
| 919 | 919 | ||
| 920 | static struct xattr_handler *xprefix_to_handler(int xprefix) { | 920 | static const struct xattr_handler *xprefix_to_handler(int xprefix) { |
| 921 | struct xattr_handler *ret; | 921 | const struct xattr_handler *ret; |
| 922 | 922 | ||
| 923 | switch (xprefix) { | 923 | switch (xprefix) { |
| 924 | case JFFS2_XPREFIX_USER: | 924 | case JFFS2_XPREFIX_USER: |
| @@ -955,7 +955,7 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 955 | struct jffs2_inode_cache *ic = f->inocache; | 955 | struct jffs2_inode_cache *ic = f->inocache; |
| 956 | struct jffs2_xattr_ref *ref, **pref; | 956 | struct jffs2_xattr_ref *ref, **pref; |
| 957 | struct jffs2_xattr_datum *xd; | 957 | struct jffs2_xattr_datum *xd; |
| 958 | struct xattr_handler *xhandle; | 958 | const struct xattr_handler *xhandle; |
| 959 | ssize_t len, rc; | 959 | ssize_t len, rc; |
| 960 | int retry = 0; | 960 | int retry = 0; |
| 961 | 961 | ||
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index 6e3b5ddfb7a..cf4f5759b42 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h | |||
| @@ -93,9 +93,9 @@ extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname | |||
| 93 | extern int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | 93 | extern int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, |
| 94 | const char *buffer, size_t size, int flags); | 94 | const char *buffer, size_t size, int flags); |
| 95 | 95 | ||
| 96 | extern struct xattr_handler *jffs2_xattr_handlers[]; | 96 | extern const struct xattr_handler *jffs2_xattr_handlers[]; |
| 97 | extern struct xattr_handler jffs2_user_xattr_handler; | 97 | extern const struct xattr_handler jffs2_user_xattr_handler; |
| 98 | extern struct xattr_handler jffs2_trusted_xattr_handler; | 98 | extern const struct xattr_handler jffs2_trusted_xattr_handler; |
| 99 | 99 | ||
| 100 | extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | 100 | extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); |
| 101 | #define jffs2_getxattr generic_getxattr | 101 | #define jffs2_getxattr generic_getxattr |
| @@ -122,7 +122,7 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | |||
| 122 | 122 | ||
| 123 | #ifdef CONFIG_JFFS2_FS_SECURITY | 123 | #ifdef CONFIG_JFFS2_FS_SECURITY |
| 124 | extern int jffs2_init_security(struct inode *inode, struct inode *dir); | 124 | extern int jffs2_init_security(struct inode *inode, struct inode *dir); |
| 125 | extern struct xattr_handler jffs2_security_xattr_handler; | 125 | extern const struct xattr_handler jffs2_security_xattr_handler; |
| 126 | #else | 126 | #else |
| 127 | #define jffs2_init_security(inode,dir) (0) | 127 | #define jffs2_init_security(inode,dir) (0) |
| 128 | #endif /* CONFIG_JFFS2_FS_SECURITY */ | 128 | #endif /* CONFIG_JFFS2_FS_SECURITY */ |
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c index 3e5a5e356e0..1c868194c50 100644 --- a/fs/jffs2/xattr_trusted.c +++ b/fs/jffs2/xattr_trusted.c | |||
| @@ -47,7 +47,7 @@ static size_t jffs2_trusted_listxattr(struct dentry *dentry, char *list, | |||
| 47 | return retlen; | 47 | return retlen; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | struct xattr_handler jffs2_trusted_xattr_handler = { | 50 | const struct xattr_handler jffs2_trusted_xattr_handler = { |
| 51 | .prefix = XATTR_TRUSTED_PREFIX, | 51 | .prefix = XATTR_TRUSTED_PREFIX, |
| 52 | .list = jffs2_trusted_listxattr, | 52 | .list = jffs2_trusted_listxattr, |
| 53 | .set = jffs2_trusted_setxattr, | 53 | .set = jffs2_trusted_setxattr, |
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c index 8544af67dff..916b5c96603 100644 --- a/fs/jffs2/xattr_user.c +++ b/fs/jffs2/xattr_user.c | |||
| @@ -47,7 +47,7 @@ static size_t jffs2_user_listxattr(struct dentry *dentry, char *list, | |||
| 47 | return retlen; | 47 | return retlen; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | struct xattr_handler jffs2_user_xattr_handler = { | 50 | const struct xattr_handler jffs2_user_xattr_handler = { |
| 51 | .prefix = XATTR_USER_PREFIX, | 51 | .prefix = XATTR_USER_PREFIX, |
| 52 | .list = jffs2_user_listxattr, | 52 | .list = jffs2_user_listxattr, |
| 53 | .set = jffs2_user_setxattr, | 53 | .set = jffs2_user_setxattr, |
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 829921b6776..2686531e235 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c | |||
| @@ -98,14 +98,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
| 98 | goto fail_unlock; | 98 | goto fail_unlock; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | inode->i_uid = current_fsuid(); | 101 | inode_init_owner(inode, parent, mode); |
| 102 | if (parent->i_mode & S_ISGID) { | ||
| 103 | inode->i_gid = parent->i_gid; | ||
| 104 | if (S_ISDIR(mode)) | ||
| 105 | mode |= S_ISGID; | ||
| 106 | } else | ||
| 107 | inode->i_gid = current_fsgid(); | ||
| 108 | |||
| 109 | /* | 102 | /* |
| 110 | * New inodes need to save sane values on disk when | 103 | * New inodes need to save sane values on disk when |
| 111 | * uid & gid mount options are used | 104 | * uid & gid mount options are used |
| @@ -121,7 +114,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
| 121 | if (rc) | 114 | if (rc) |
| 122 | goto fail_drop; | 115 | goto fail_drop; |
| 123 | 116 | ||
| 124 | inode->i_mode = mode; | ||
| 125 | /* inherit flags from parent */ | 117 | /* inherit flags from parent */ |
| 126 | jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT; | 118 | jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT; |
| 127 | 119 | ||
| @@ -134,7 +126,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
| 134 | if (S_ISLNK(mode)) | 126 | if (S_ISLNK(mode)) |
| 135 | jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL); | 127 | jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL); |
| 136 | } | 128 | } |
| 137 | jfs_inode->mode2 |= mode; | 129 | jfs_inode->mode2 |= inode->i_mode; |
| 138 | 130 | ||
| 139 | inode->i_blocks = 0; | 131 | inode->i_blocks = 0; |
| 140 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 132 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index 755a92e8daa..f602e230e16 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c | |||
| @@ -358,14 +358,7 @@ struct inode *logfs_new_inode(struct inode *dir, int mode) | |||
| 358 | inode->i_mode = mode; | 358 | inode->i_mode = mode; |
| 359 | logfs_set_ino_generation(sb, inode); | 359 | logfs_set_ino_generation(sb, inode); |
| 360 | 360 | ||
| 361 | inode->i_uid = current_fsuid(); | 361 | inode_init_owner(inode, dir, mode); |
| 362 | inode->i_gid = current_fsgid(); | ||
| 363 | if (dir->i_mode & S_ISGID) { | ||
| 364 | inode->i_gid = dir->i_gid; | ||
| 365 | if (S_ISDIR(mode)) | ||
| 366 | inode->i_mode |= S_ISGID; | ||
| 367 | } | ||
| 368 | |||
| 369 | logfs_inode_setops(inode); | 362 | logfs_inode_setops(inode); |
| 370 | insert_inode_hash(inode); | 363 | insert_inode_hash(inode); |
| 371 | 364 | ||
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 6ac693faae4..482779fe4e7 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c | |||
| @@ -221,7 +221,7 @@ void minix_free_inode(struct inode * inode) | |||
| 221 | clear_inode(inode); /* clear in-memory copy */ | 221 | clear_inode(inode); /* clear in-memory copy */ |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | struct inode * minix_new_inode(const struct inode * dir, int * error) | 224 | struct inode *minix_new_inode(const struct inode *dir, int mode, int *error) |
| 225 | { | 225 | { |
| 226 | struct super_block *sb = dir->i_sb; | 226 | struct super_block *sb = dir->i_sb; |
| 227 | struct minix_sb_info *sbi = minix_sb(sb); | 227 | struct minix_sb_info *sbi = minix_sb(sb); |
| @@ -263,8 +263,7 @@ struct inode * minix_new_inode(const struct inode * dir, int * error) | |||
| 263 | iput(inode); | 263 | iput(inode); |
| 264 | return NULL; | 264 | return NULL; |
| 265 | } | 265 | } |
| 266 | inode->i_uid = current_fsuid(); | 266 | inode_init_owner(inode, dir, mode); |
| 267 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid(); | ||
| 268 | inode->i_ino = j; | 267 | inode->i_ino = j; |
| 269 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 268 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
| 270 | inode->i_blocks = 0; | 269 | inode->i_blocks = 0; |
diff --git a/fs/minix/minix.h b/fs/minix/minix.h index 9dcf95b4211..111f34ee9e3 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h | |||
| @@ -46,7 +46,7 @@ struct minix_sb_info { | |||
| 46 | extern struct inode *minix_iget(struct super_block *, unsigned long); | 46 | extern struct inode *minix_iget(struct super_block *, unsigned long); |
| 47 | extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **); | 47 | extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **); |
| 48 | extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **); | 48 | extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **); |
| 49 | extern struct inode * minix_new_inode(const struct inode * dir, int * error); | 49 | extern struct inode * minix_new_inode(const struct inode *, int, int *); |
| 50 | extern void minix_free_inode(struct inode * inode); | 50 | extern void minix_free_inode(struct inode * inode); |
| 51 | extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi); | 51 | extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi); |
| 52 | extern int minix_new_block(struct inode * inode); | 52 | extern int minix_new_block(struct inode * inode); |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 32b131cd612..e20ee85955d 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
| @@ -46,10 +46,9 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_ | |||
| 46 | if (!old_valid_dev(rdev)) | 46 | if (!old_valid_dev(rdev)) |
| 47 | return -EINVAL; | 47 | return -EINVAL; |
| 48 | 48 | ||
| 49 | inode = minix_new_inode(dir, &error); | 49 | inode = minix_new_inode(dir, mode, &error); |
| 50 | 50 | ||
| 51 | if (inode) { | 51 | if (inode) { |
| 52 | inode->i_mode = mode; | ||
| 53 | minix_set_inode(inode, rdev); | 52 | minix_set_inode(inode, rdev); |
| 54 | mark_inode_dirty(inode); | 53 | mark_inode_dirty(inode); |
| 55 | error = add_nondir(dentry, inode); | 54 | error = add_nondir(dentry, inode); |
| @@ -73,11 +72,10 @@ static int minix_symlink(struct inode * dir, struct dentry *dentry, | |||
| 73 | if (i > dir->i_sb->s_blocksize) | 72 | if (i > dir->i_sb->s_blocksize) |
| 74 | goto out; | 73 | goto out; |
| 75 | 74 | ||
| 76 | inode = minix_new_inode(dir, &err); | 75 | inode = minix_new_inode(dir, S_IFLNK | 0777, &err); |
| 77 | if (!inode) | 76 | if (!inode) |
| 78 | goto out; | 77 | goto out; |
| 79 | 78 | ||
| 80 | inode->i_mode = S_IFLNK | 0777; | ||
| 81 | minix_set_inode(inode, 0); | 79 | minix_set_inode(inode, 0); |
| 82 | err = page_symlink(inode, symname, i); | 80 | err = page_symlink(inode, symname, i); |
| 83 | if (err) | 81 | if (err) |
| @@ -117,13 +115,10 @@ static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) | |||
| 117 | 115 | ||
| 118 | inode_inc_link_count(dir); | 116 | inode_inc_link_count(dir); |
| 119 | 117 | ||
| 120 | inode = minix_new_inode(dir, &err); | 118 | inode = minix_new_inode(dir, mode, &err); |
| 121 | if (!inode) | 119 | if (!inode) |
| 122 | goto out_dir; | 120 | goto out_dir; |
| 123 | 121 | ||
| 124 | inode->i_mode = S_IFDIR | mode; | ||
| 125 | if (dir->i_mode & S_ISGID) | ||
| 126 | inode->i_mode |= S_ISGID; | ||
| 127 | minix_set_inode(inode, 0); | 122 | minix_set_inode(inode, 0); |
| 128 | 123 | ||
| 129 | inode_inc_link_count(inode); | 124 | inode_inc_link_count(inode); |
diff --git a/fs/namei.c b/fs/namei.c index b86b96fe1dc..48e1f60520e 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -523,9 +523,10 @@ static void path_put_conditional(struct path *path, struct nameidata *nd) | |||
| 523 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | 523 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) |
| 524 | { | 524 | { |
| 525 | dput(nd->path.dentry); | 525 | dput(nd->path.dentry); |
| 526 | if (nd->path.mnt != path->mnt) | 526 | if (nd->path.mnt != path->mnt) { |
| 527 | mntput(nd->path.mnt); | 527 | mntput(nd->path.mnt); |
| 528 | nd->path.mnt = path->mnt; | 528 | nd->path.mnt = path->mnt; |
| 529 | } | ||
| 529 | nd->path.dentry = path->dentry; | 530 | nd->path.dentry = path->dentry; |
| 530 | } | 531 | } |
| 531 | 532 | ||
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 7a9ae3254a4..7e26caab2a2 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
| @@ -44,8 +44,7 @@ | |||
| 44 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 44 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
| 45 | 45 | ||
| 46 | /* Globals */ | 46 | /* Globals */ |
| 47 | static struct path rec_dir; | 47 | static struct file *rec_file; |
| 48 | static int rec_dir_init = 0; | ||
| 49 | 48 | ||
| 50 | static int | 49 | static int |
| 51 | nfs4_save_creds(const struct cred **original_creds) | 50 | nfs4_save_creds(const struct cred **original_creds) |
| @@ -117,33 +116,28 @@ out_no_tfm: | |||
| 117 | return status; | 116 | return status; |
| 118 | } | 117 | } |
| 119 | 118 | ||
| 120 | static void | ||
| 121 | nfsd4_sync_rec_dir(void) | ||
| 122 | { | ||
| 123 | vfs_fsync(NULL, rec_dir.dentry, 0); | ||
| 124 | } | ||
| 125 | |||
| 126 | int | 119 | int |
| 127 | nfsd4_create_clid_dir(struct nfs4_client *clp) | 120 | nfsd4_create_clid_dir(struct nfs4_client *clp) |
| 128 | { | 121 | { |
| 129 | const struct cred *original_cred; | 122 | const struct cred *original_cred; |
| 130 | char *dname = clp->cl_recdir; | 123 | char *dname = clp->cl_recdir; |
| 131 | struct dentry *dentry; | 124 | struct dentry *dir, *dentry; |
| 132 | int status; | 125 | int status; |
| 133 | 126 | ||
| 134 | dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); | 127 | dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); |
| 135 | 128 | ||
| 136 | if (!rec_dir_init || clp->cl_firststate) | 129 | if (!rec_file || clp->cl_firststate) |
| 137 | return 0; | 130 | return 0; |
| 138 | 131 | ||
| 139 | status = nfs4_save_creds(&original_cred); | 132 | status = nfs4_save_creds(&original_cred); |
| 140 | if (status < 0) | 133 | if (status < 0) |
| 141 | return status; | 134 | return status; |
| 142 | 135 | ||
| 136 | dir = rec_file->f_path.dentry; | ||
| 143 | /* lock the parent */ | 137 | /* lock the parent */ |
| 144 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); | 138 | mutex_lock(&dir->d_inode->i_mutex); |
| 145 | 139 | ||
| 146 | dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1); | 140 | dentry = lookup_one_len(dname, dir, HEXDIR_LEN-1); |
| 147 | if (IS_ERR(dentry)) { | 141 | if (IS_ERR(dentry)) { |
| 148 | status = PTR_ERR(dentry); | 142 | status = PTR_ERR(dentry); |
| 149 | goto out_unlock; | 143 | goto out_unlock; |
| @@ -153,18 +147,18 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
| 153 | dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); | 147 | dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); |
| 154 | goto out_put; | 148 | goto out_put; |
| 155 | } | 149 | } |
| 156 | status = mnt_want_write(rec_dir.mnt); | 150 | status = mnt_want_write(rec_file->f_path.mnt); |
| 157 | if (status) | 151 | if (status) |
| 158 | goto out_put; | 152 | goto out_put; |
| 159 | status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); | 153 | status = vfs_mkdir(dir->d_inode, dentry, S_IRWXU); |
| 160 | mnt_drop_write(rec_dir.mnt); | 154 | mnt_drop_write(rec_file->f_path.mnt); |
| 161 | out_put: | 155 | out_put: |
| 162 | dput(dentry); | 156 | dput(dentry); |
| 163 | out_unlock: | 157 | out_unlock: |
| 164 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); | 158 | mutex_unlock(&dir->d_inode->i_mutex); |
| 165 | if (status == 0) { | 159 | if (status == 0) { |
| 166 | clp->cl_firststate = 1; | 160 | clp->cl_firststate = 1; |
| 167 | nfsd4_sync_rec_dir(); | 161 | vfs_fsync(rec_file, 0); |
| 168 | } | 162 | } |
| 169 | nfs4_reset_creds(original_cred); | 163 | nfs4_reset_creds(original_cred); |
| 170 | dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); | 164 | dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); |
| @@ -206,14 +200,14 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) | |||
| 206 | struct dentry *dentry; | 200 | struct dentry *dentry; |
| 207 | int status; | 201 | int status; |
| 208 | 202 | ||
| 209 | if (!rec_dir_init) | 203 | if (!rec_file) |
| 210 | return 0; | 204 | return 0; |
| 211 | 205 | ||
| 212 | status = nfs4_save_creds(&original_cred); | 206 | status = nfs4_save_creds(&original_cred); |
| 213 | if (status < 0) | 207 | if (status < 0) |
| 214 | return status; | 208 | return status; |
| 215 | 209 | ||
| 216 | filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY, | 210 | filp = dentry_open(dget(dir), mntget(rec_file->f_path.mnt), O_RDONLY, |
| 217 | current_cred()); | 211 | current_cred()); |
| 218 | status = PTR_ERR(filp); | 212 | status = PTR_ERR(filp); |
| 219 | if (IS_ERR(filp)) | 213 | if (IS_ERR(filp)) |
| @@ -250,13 +244,14 @@ out: | |||
| 250 | static int | 244 | static int |
| 251 | nfsd4_unlink_clid_dir(char *name, int namlen) | 245 | nfsd4_unlink_clid_dir(char *name, int namlen) |
| 252 | { | 246 | { |
| 253 | struct dentry *dentry; | 247 | struct dentry *dir, *dentry; |
| 254 | int status; | 248 | int status; |
| 255 | 249 | ||
| 256 | dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); | 250 | dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); |
| 257 | 251 | ||
| 258 | mutex_lock_nested(&rec_dir.dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 252 | dir = rec_file->f_path.dentry; |
| 259 | dentry = lookup_one_len(name, rec_dir.dentry, namlen); | 253 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
| 254 | dentry = lookup_one_len(name, dir, namlen); | ||
| 260 | if (IS_ERR(dentry)) { | 255 | if (IS_ERR(dentry)) { |
| 261 | status = PTR_ERR(dentry); | 256 | status = PTR_ERR(dentry); |
| 262 | goto out_unlock; | 257 | goto out_unlock; |
| @@ -264,11 +259,11 @@ nfsd4_unlink_clid_dir(char *name, int namlen) | |||
| 264 | status = -ENOENT; | 259 | status = -ENOENT; |
| 265 | if (!dentry->d_inode) | 260 | if (!dentry->d_inode) |
| 266 | goto out; | 261 | goto out; |
| 267 | status = vfs_rmdir(rec_dir.dentry->d_inode, dentry); | 262 | status = vfs_rmdir(dir->d_inode, dentry); |
| 268 | out: | 263 | out: |
| 269 | dput(dentry); | 264 | dput(dentry); |
| 270 | out_unlock: | 265 | out_unlock: |
| 271 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); | 266 | mutex_unlock(&dir->d_inode->i_mutex); |
| 272 | return status; | 267 | return status; |
| 273 | } | 268 | } |
| 274 | 269 | ||
| @@ -278,10 +273,10 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp) | |||
| 278 | const struct cred *original_cred; | 273 | const struct cred *original_cred; |
| 279 | int status; | 274 | int status; |
| 280 | 275 | ||
| 281 | if (!rec_dir_init || !clp->cl_firststate) | 276 | if (!rec_file || !clp->cl_firststate) |
| 282 | return; | 277 | return; |
| 283 | 278 | ||
| 284 | status = mnt_want_write(rec_dir.mnt); | 279 | status = mnt_want_write(rec_file->f_path.mnt); |
| 285 | if (status) | 280 | if (status) |
| 286 | goto out; | 281 | goto out; |
| 287 | clp->cl_firststate = 0; | 282 | clp->cl_firststate = 0; |
| @@ -293,8 +288,8 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp) | |||
| 293 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); | 288 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); |
| 294 | nfs4_reset_creds(original_cred); | 289 | nfs4_reset_creds(original_cred); |
| 295 | if (status == 0) | 290 | if (status == 0) |
| 296 | nfsd4_sync_rec_dir(); | 291 | vfs_fsync(rec_file, 0); |
| 297 | mnt_drop_write(rec_dir.mnt); | 292 | mnt_drop_write(rec_file->f_path.mnt); |
| 298 | out: | 293 | out: |
| 299 | if (status) | 294 | if (status) |
| 300 | printk("NFSD: Failed to remove expired client state directory" | 295 | printk("NFSD: Failed to remove expired client state directory" |
| @@ -323,19 +318,19 @@ void | |||
| 323 | nfsd4_recdir_purge_old(void) { | 318 | nfsd4_recdir_purge_old(void) { |
| 324 | int status; | 319 | int status; |
| 325 | 320 | ||
| 326 | if (!rec_dir_init) | 321 | if (!rec_file) |
| 327 | return; | 322 | return; |
| 328 | status = mnt_want_write(rec_dir.mnt); | 323 | status = mnt_want_write(rec_file->f_path.mnt); |
| 329 | if (status) | 324 | if (status) |
| 330 | goto out; | 325 | goto out; |
| 331 | status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old); | 326 | status = nfsd4_list_rec_dir(rec_file->f_path.dentry, purge_old); |
| 332 | if (status == 0) | 327 | if (status == 0) |
| 333 | nfsd4_sync_rec_dir(); | 328 | vfs_fsync(rec_file, 0); |
| 334 | mnt_drop_write(rec_dir.mnt); | 329 | mnt_drop_write(rec_file->f_path.mnt); |
| 335 | out: | 330 | out: |
| 336 | if (status) | 331 | if (status) |
| 337 | printk("nfsd4: failed to purge old clients from recovery" | 332 | printk("nfsd4: failed to purge old clients from recovery" |
| 338 | " directory %s\n", rec_dir.dentry->d_name.name); | 333 | " directory %s\n", rec_file->f_path.dentry->d_name.name); |
| 339 | } | 334 | } |
| 340 | 335 | ||
| 341 | static int | 336 | static int |
| @@ -355,10 +350,13 @@ int | |||
| 355 | nfsd4_recdir_load(void) { | 350 | nfsd4_recdir_load(void) { |
| 356 | int status; | 351 | int status; |
| 357 | 352 | ||
| 358 | status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir); | 353 | if (!rec_file) |
| 354 | return 0; | ||
| 355 | |||
| 356 | status = nfsd4_list_rec_dir(rec_file->f_path.dentry, load_recdir); | ||
| 359 | if (status) | 357 | if (status) |
| 360 | printk("nfsd4: failed loading clients from recovery" | 358 | printk("nfsd4: failed loading clients from recovery" |
| 361 | " directory %s\n", rec_dir.dentry->d_name.name); | 359 | " directory %s\n", rec_file->f_path.dentry->d_name.name); |
| 362 | return status; | 360 | return status; |
| 363 | } | 361 | } |
| 364 | 362 | ||
| @@ -375,7 +373,7 @@ nfsd4_init_recdir(char *rec_dirname) | |||
| 375 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", | 373 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", |
| 376 | rec_dirname); | 374 | rec_dirname); |
| 377 | 375 | ||
| 378 | BUG_ON(rec_dir_init); | 376 | BUG_ON(rec_file); |
| 379 | 377 | ||
| 380 | status = nfs4_save_creds(&original_cred); | 378 | status = nfs4_save_creds(&original_cred); |
| 381 | if (status < 0) { | 379 | if (status < 0) { |
| @@ -385,22 +383,21 @@ nfsd4_init_recdir(char *rec_dirname) | |||
| 385 | return; | 383 | return; |
| 386 | } | 384 | } |
| 387 | 385 | ||
| 388 | status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, | 386 | rec_file = filp_open(rec_dirname, O_RDONLY | O_DIRECTORY, 0); |
| 389 | &rec_dir); | 387 | if (IS_ERR(rec_file)) { |
| 390 | if (status) | ||
| 391 | printk("NFSD: unable to find recovery directory %s\n", | 388 | printk("NFSD: unable to find recovery directory %s\n", |
| 392 | rec_dirname); | 389 | rec_dirname); |
| 390 | rec_file = NULL; | ||
| 391 | } | ||
| 393 | 392 | ||
| 394 | if (!status) | ||
| 395 | rec_dir_init = 1; | ||
| 396 | nfs4_reset_creds(original_cred); | 393 | nfs4_reset_creds(original_cred); |
| 397 | } | 394 | } |
| 398 | 395 | ||
| 399 | void | 396 | void |
| 400 | nfsd4_shutdown_recdir(void) | 397 | nfsd4_shutdown_recdir(void) |
| 401 | { | 398 | { |
| 402 | if (!rec_dir_init) | 399 | if (!rec_file) |
| 403 | return; | 400 | return; |
| 404 | rec_dir_init = 0; | 401 | fput(rec_file); |
| 405 | path_put(&rec_dir); | 402 | rec_file = NULL; |
| 406 | } | 403 | } |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 23c06f77f4c..ebbf3b6b245 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -999,7 +999,7 @@ static int wait_for_concurrent_writes(struct file *file) | |||
| 999 | 999 | ||
| 1000 | if (inode->i_state & I_DIRTY) { | 1000 | if (inode->i_state & I_DIRTY) { |
| 1001 | dprintk("nfsd: write sync %d\n", task_pid_nr(current)); | 1001 | dprintk("nfsd: write sync %d\n", task_pid_nr(current)); |
| 1002 | err = vfs_fsync(file, file->f_path.dentry, 0); | 1002 | err = vfs_fsync(file, 0); |
| 1003 | } | 1003 | } |
| 1004 | last_ino = inode->i_ino; | 1004 | last_ino = inode->i_ino; |
| 1005 | last_dev = inode->i_sb->s_dev; | 1005 | last_dev = inode->i_sb->s_dev; |
| @@ -1175,8 +1175,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
| 1175 | if (err) | 1175 | if (err) |
| 1176 | goto out; | 1176 | goto out; |
| 1177 | if (EX_ISSYNC(fhp->fh_export)) { | 1177 | if (EX_ISSYNC(fhp->fh_export)) { |
| 1178 | int err2 = vfs_fsync_range(file, file->f_path.dentry, | 1178 | int err2 = vfs_fsync_range(file, offset, end, 0); |
| 1179 | offset, end, 0); | ||
| 1180 | 1179 | ||
| 1181 | if (err2 != -EINVAL) | 1180 | if (err2 != -EINVAL) |
| 1182 | err = nfserrno(err2); | 1181 | err = nfserrno(err2); |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 5e226d4b41d..39e038ac8fc 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
| @@ -280,16 +280,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
| 280 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ | 280 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ |
| 281 | 281 | ||
| 282 | atomic_inc(&sbi->s_inodes_count); | 282 | atomic_inc(&sbi->s_inodes_count); |
| 283 | 283 | inode_init_owner(inode, dir, mode); | |
| 284 | inode->i_uid = current_fsuid(); | ||
| 285 | if (dir->i_mode & S_ISGID) { | ||
| 286 | inode->i_gid = dir->i_gid; | ||
| 287 | if (S_ISDIR(mode)) | ||
| 288 | mode |= S_ISGID; | ||
| 289 | } else | ||
| 290 | inode->i_gid = current_fsgid(); | ||
| 291 | |||
| 292 | inode->i_mode = mode; | ||
| 293 | inode->i_ino = ino; | 284 | inode->i_ino = ino; |
| 294 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 285 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
| 295 | 286 | ||
diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c index 40b1cf914cc..27b75ebc746 100644 --- a/fs/notify/inotify/inotify.c +++ b/fs/notify/inotify/inotify.c | |||
| @@ -110,14 +110,10 @@ EXPORT_SYMBOL_GPL(get_inotify_watch); | |||
| 110 | int pin_inotify_watch(struct inotify_watch *watch) | 110 | int pin_inotify_watch(struct inotify_watch *watch) |
| 111 | { | 111 | { |
| 112 | struct super_block *sb = watch->inode->i_sb; | 112 | struct super_block *sb = watch->inode->i_sb; |
| 113 | spin_lock(&sb_lock); | 113 | if (atomic_inc_not_zero(&sb->s_active)) { |
| 114 | if (sb->s_count >= S_BIAS) { | ||
| 115 | atomic_inc(&sb->s_active); | ||
| 116 | spin_unlock(&sb_lock); | ||
| 117 | atomic_inc(&watch->count); | 114 | atomic_inc(&watch->count); |
| 118 | return 1; | 115 | return 1; |
| 119 | } | 116 | } |
| 120 | spin_unlock(&sb_lock); | ||
| 121 | return 0; | 117 | return 0; |
| 122 | } | 118 | } |
| 123 | 119 | ||
| @@ -515,34 +511,8 @@ EXPORT_SYMBOL_GPL(inotify_init_watch); | |||
| 515 | * done. Cleanup is just deactivate_super(). However, that leaves a messy | 511 | * done. Cleanup is just deactivate_super(). However, that leaves a messy |
| 516 | * case - what if we *are* racing with umount() and active references to | 512 | * case - what if we *are* racing with umount() and active references to |
| 517 | * superblock can't be acquired anymore? We can bump ->s_count, grab | 513 | * superblock can't be acquired anymore? We can bump ->s_count, grab |
| 518 | * ->s_umount, which will almost certainly wait until the superblock is shut | 514 | * ->s_umount, which will wait until the superblock is shut down and the |
| 519 | * down and the watch in question is pining for fjords. That's fine, but | 515 | * watch in question is pining for fjords. |
| 520 | * there is a problem - we might have hit the window between ->s_active | ||
| 521 | * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock | ||
| 522 | * is past the point of no return and is heading for shutdown) and the | ||
| 523 | * moment when deactivate_super() acquires ->s_umount. We could just do | ||
| 524 | * drop_super() yield() and retry, but that's rather antisocial and this | ||
| 525 | * stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having | ||
| 526 | * found that we'd got there first (i.e. that ->s_root is non-NULL) we know | ||
| 527 | * that we won't race with inotify_umount_inodes(). So we could grab a | ||
| 528 | * reference to watch and do the rest as above, just with drop_super() instead | ||
| 529 | * of deactivate_super(), right? Wrong. We had to drop ih->mutex before we | ||
| 530 | * could grab ->s_umount. So the watch could've been gone already. | ||
| 531 | * | ||
| 532 | * That still can be dealt with - we need to save watch->wd, do idr_find() | ||
| 533 | * and compare its result with our pointer. If they match, we either have | ||
| 534 | * the damn thing still alive or we'd lost not one but two races at once, | ||
| 535 | * the watch had been killed and a new one got created with the same ->wd | ||
| 536 | * at the same address. That couldn't have happened in inotify_destroy(), | ||
| 537 | * but inotify_rm_wd() could run into that. Still, "new one got created" | ||
| 538 | * is not a problem - we have every right to kill it or leave it alone, | ||
| 539 | * whatever's more convenient. | ||
| 540 | * | ||
| 541 | * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as | ||
| 542 | * "grab it and kill it" check. If it's been our original watch, we are | ||
| 543 | * fine, if it's a newcomer - nevermind, just pretend that we'd won the | ||
| 544 | * race and kill the fscker anyway; we are safe since we know that its | ||
| 545 | * superblock won't be going away. | ||
| 546 | * | 516 | * |
| 547 | * And yes, this is far beyond mere "not very pretty"; so's the entire | 517 | * And yes, this is far beyond mere "not very pretty"; so's the entire |
| 548 | * concept of inotify to start with. | 518 | * concept of inotify to start with. |
| @@ -556,57 +526,31 @@ EXPORT_SYMBOL_GPL(inotify_init_watch); | |||
| 556 | * Called with ih->mutex held, drops it. Possible return values: | 526 | * Called with ih->mutex held, drops it. Possible return values: |
| 557 | * 0 - nothing to do, it has died | 527 | * 0 - nothing to do, it has died |
| 558 | * 1 - remove it, drop the reference and deactivate_super() | 528 | * 1 - remove it, drop the reference and deactivate_super() |
| 559 | * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid | ||
| 560 | * that variant, since it involved a lot of PITA, but that's the best that | ||
| 561 | * could've been done. | ||
| 562 | */ | 529 | */ |
| 563 | static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) | 530 | static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) |
| 564 | { | 531 | { |
| 565 | struct super_block *sb = watch->inode->i_sb; | 532 | struct super_block *sb = watch->inode->i_sb; |
| 566 | s32 wd = watch->wd; | ||
| 567 | 533 | ||
| 568 | spin_lock(&sb_lock); | 534 | if (atomic_inc_not_zero(&sb->s_active)) { |
| 569 | if (sb->s_count >= S_BIAS) { | ||
| 570 | atomic_inc(&sb->s_active); | ||
| 571 | spin_unlock(&sb_lock); | ||
| 572 | get_inotify_watch(watch); | 535 | get_inotify_watch(watch); |
| 573 | mutex_unlock(&ih->mutex); | 536 | mutex_unlock(&ih->mutex); |
| 574 | return 1; /* the best outcome */ | 537 | return 1; /* the best outcome */ |
| 575 | } | 538 | } |
| 539 | spin_lock(&sb_lock); | ||
| 576 | sb->s_count++; | 540 | sb->s_count++; |
| 577 | spin_unlock(&sb_lock); | 541 | spin_unlock(&sb_lock); |
| 578 | mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ | 542 | mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ |
| 579 | down_read(&sb->s_umount); | 543 | down_read(&sb->s_umount); |
| 580 | if (likely(!sb->s_root)) { | 544 | /* fs is already shut down; the watch is dead */ |
| 581 | /* fs is already shut down; the watch is dead */ | 545 | drop_super(sb); |
| 582 | drop_super(sb); | 546 | return 0; |
| 583 | return 0; | ||
| 584 | } | ||
| 585 | /* raced with the final deactivate_super() */ | ||
| 586 | mutex_lock(&ih->mutex); | ||
| 587 | if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) { | ||
| 588 | /* the watch is dead */ | ||
| 589 | mutex_unlock(&ih->mutex); | ||
| 590 | drop_super(sb); | ||
| 591 | return 0; | ||
| 592 | } | ||
| 593 | /* still alive or freed and reused with the same sb and wd; kill */ | ||
| 594 | get_inotify_watch(watch); | ||
| 595 | mutex_unlock(&ih->mutex); | ||
| 596 | return 2; | ||
| 597 | } | 547 | } |
| 598 | 548 | ||
| 599 | static void unpin_and_kill(struct inotify_watch *watch, int how) | 549 | static void unpin_and_kill(struct inotify_watch *watch) |
| 600 | { | 550 | { |
| 601 | struct super_block *sb = watch->inode->i_sb; | 551 | struct super_block *sb = watch->inode->i_sb; |
| 602 | put_inotify_watch(watch); | 552 | put_inotify_watch(watch); |
| 603 | switch (how) { | 553 | deactivate_super(sb); |
| 604 | case 1: | ||
| 605 | deactivate_super(sb); | ||
| 606 | break; | ||
| 607 | case 2: | ||
| 608 | drop_super(sb); | ||
| 609 | } | ||
| 610 | } | 554 | } |
| 611 | 555 | ||
| 612 | /** | 556 | /** |
| @@ -628,7 +572,6 @@ void inotify_destroy(struct inotify_handle *ih) | |||
| 628 | struct list_head *watches; | 572 | struct list_head *watches; |
| 629 | struct super_block *sb; | 573 | struct super_block *sb; |
| 630 | struct inode *inode; | 574 | struct inode *inode; |
| 631 | int how; | ||
| 632 | 575 | ||
| 633 | mutex_lock(&ih->mutex); | 576 | mutex_lock(&ih->mutex); |
| 634 | watches = &ih->watches; | 577 | watches = &ih->watches; |
| @@ -638,8 +581,7 @@ void inotify_destroy(struct inotify_handle *ih) | |||
| 638 | } | 581 | } |
| 639 | watch = list_first_entry(watches, struct inotify_watch, h_list); | 582 | watch = list_first_entry(watches, struct inotify_watch, h_list); |
| 640 | sb = watch->inode->i_sb; | 583 | sb = watch->inode->i_sb; |
| 641 | how = pin_to_kill(ih, watch); | 584 | if (!pin_to_kill(ih, watch)) |
| 642 | if (!how) | ||
| 643 | continue; | 585 | continue; |
| 644 | 586 | ||
| 645 | inode = watch->inode; | 587 | inode = watch->inode; |
| @@ -654,7 +596,7 @@ void inotify_destroy(struct inotify_handle *ih) | |||
| 654 | 596 | ||
| 655 | mutex_unlock(&ih->mutex); | 597 | mutex_unlock(&ih->mutex); |
| 656 | mutex_unlock(&inode->inotify_mutex); | 598 | mutex_unlock(&inode->inotify_mutex); |
| 657 | unpin_and_kill(watch, how); | 599 | unpin_and_kill(watch); |
| 658 | } | 600 | } |
| 659 | 601 | ||
| 660 | /* free this handle: the put matching the get in inotify_init() */ | 602 | /* free this handle: the put matching the get in inotify_init() */ |
| @@ -857,7 +799,6 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
| 857 | struct inotify_watch *watch; | 799 | struct inotify_watch *watch; |
| 858 | struct super_block *sb; | 800 | struct super_block *sb; |
| 859 | struct inode *inode; | 801 | struct inode *inode; |
| 860 | int how; | ||
| 861 | 802 | ||
| 862 | mutex_lock(&ih->mutex); | 803 | mutex_lock(&ih->mutex); |
| 863 | watch = idr_find(&ih->idr, wd); | 804 | watch = idr_find(&ih->idr, wd); |
| @@ -866,8 +807,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
| 866 | return -EINVAL; | 807 | return -EINVAL; |
| 867 | } | 808 | } |
| 868 | sb = watch->inode->i_sb; | 809 | sb = watch->inode->i_sb; |
| 869 | how = pin_to_kill(ih, watch); | 810 | if (!pin_to_kill(ih, watch)) |
| 870 | if (!how) | ||
| 871 | return 0; | 811 | return 0; |
| 872 | 812 | ||
| 873 | inode = watch->inode; | 813 | inode = watch->inode; |
| @@ -881,7 +821,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
| 881 | 821 | ||
| 882 | mutex_unlock(&ih->mutex); | 822 | mutex_unlock(&ih->mutex); |
| 883 | mutex_unlock(&inode->inotify_mutex); | 823 | mutex_unlock(&inode->inotify_mutex); |
| 884 | unpin_and_kill(watch, how); | 824 | unpin_and_kill(watch); |
| 885 | 825 | ||
| 886 | return 0; | 826 | return 0; |
| 887 | } | 827 | } |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index e13fc9e8fcd..da702294d7e 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
| @@ -489,7 +489,7 @@ cleanup: | |||
| 489 | return ret; | 489 | return ret; |
| 490 | } | 490 | } |
| 491 | 491 | ||
| 492 | struct xattr_handler ocfs2_xattr_acl_access_handler = { | 492 | const struct xattr_handler ocfs2_xattr_acl_access_handler = { |
| 493 | .prefix = POSIX_ACL_XATTR_ACCESS, | 493 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 494 | .flags = ACL_TYPE_ACCESS, | 494 | .flags = ACL_TYPE_ACCESS, |
| 495 | .list = ocfs2_xattr_list_acl_access, | 495 | .list = ocfs2_xattr_list_acl_access, |
| @@ -497,7 +497,7 @@ struct xattr_handler ocfs2_xattr_acl_access_handler = { | |||
| 497 | .set = ocfs2_xattr_set_acl, | 497 | .set = ocfs2_xattr_set_acl, |
| 498 | }; | 498 | }; |
| 499 | 499 | ||
| 500 | struct xattr_handler ocfs2_xattr_acl_default_handler = { | 500 | const struct xattr_handler ocfs2_xattr_acl_default_handler = { |
| 501 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 501 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 502 | .flags = ACL_TYPE_DEFAULT, | 502 | .flags = ACL_TYPE_DEFAULT, |
| 503 | .list = ocfs2_xattr_list_acl_default, | 503 | .list = ocfs2_xattr_list_acl_default, |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index db5dd3ed4df..f171b51a74f 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -204,14 +204,7 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode) | |||
| 204 | inode->i_nlink = 2; | 204 | inode->i_nlink = 2; |
| 205 | else | 205 | else |
| 206 | inode->i_nlink = 1; | 206 | inode->i_nlink = 1; |
| 207 | inode->i_uid = current_fsuid(); | 207 | inode_init_owner(inode, dir, mode); |
| 208 | if (dir->i_mode & S_ISGID) { | ||
| 209 | inode->i_gid = dir->i_gid; | ||
| 210 | if (S_ISDIR(mode)) | ||
| 211 | mode |= S_ISGID; | ||
| 212 | } else | ||
| 213 | inode->i_gid = current_fsgid(); | ||
| 214 | inode->i_mode = mode; | ||
| 215 | dquot_initialize(inode); | 208 | dquot_initialize(inode); |
| 216 | return inode; | 209 | return inode; |
| 217 | } | 210 | } |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 98ee6c44102..e97b34842cf 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -97,7 +97,7 @@ static struct ocfs2_xattr_def_value_root def_xv = { | |||
| 97 | .xv.xr_list.l_count = cpu_to_le16(1), | 97 | .xv.xr_list.l_count = cpu_to_le16(1), |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | struct xattr_handler *ocfs2_xattr_handlers[] = { | 100 | const struct xattr_handler *ocfs2_xattr_handlers[] = { |
| 101 | &ocfs2_xattr_user_handler, | 101 | &ocfs2_xattr_user_handler, |
| 102 | &ocfs2_xattr_acl_access_handler, | 102 | &ocfs2_xattr_acl_access_handler, |
| 103 | &ocfs2_xattr_acl_default_handler, | 103 | &ocfs2_xattr_acl_default_handler, |
| @@ -106,7 +106,7 @@ struct xattr_handler *ocfs2_xattr_handlers[] = { | |||
| 106 | NULL | 106 | NULL |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | static struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { | 109 | static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { |
| 110 | [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler, | 110 | [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler, |
| 111 | [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] | 111 | [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] |
| 112 | = &ocfs2_xattr_acl_access_handler, | 112 | = &ocfs2_xattr_acl_access_handler, |
| @@ -540,7 +540,7 @@ static int ocfs2_read_xattr_block(struct inode *inode, u64 xb_blkno, | |||
| 540 | 540 | ||
| 541 | static inline const char *ocfs2_xattr_prefix(int name_index) | 541 | static inline const char *ocfs2_xattr_prefix(int name_index) |
| 542 | { | 542 | { |
| 543 | struct xattr_handler *handler = NULL; | 543 | const struct xattr_handler *handler = NULL; |
| 544 | 544 | ||
| 545 | if (name_index > 0 && name_index < OCFS2_XATTR_MAX) | 545 | if (name_index > 0 && name_index < OCFS2_XATTR_MAX) |
| 546 | handler = ocfs2_xattr_handler_map[name_index]; | 546 | handler = ocfs2_xattr_handler_map[name_index]; |
| @@ -7213,7 +7213,7 @@ int ocfs2_init_security_set(handle_t *handle, | |||
| 7213 | xattr_ac, data_ac); | 7213 | xattr_ac, data_ac); |
| 7214 | } | 7214 | } |
| 7215 | 7215 | ||
| 7216 | struct xattr_handler ocfs2_xattr_security_handler = { | 7216 | const struct xattr_handler ocfs2_xattr_security_handler = { |
| 7217 | .prefix = XATTR_SECURITY_PREFIX, | 7217 | .prefix = XATTR_SECURITY_PREFIX, |
| 7218 | .list = ocfs2_xattr_security_list, | 7218 | .list = ocfs2_xattr_security_list, |
| 7219 | .get = ocfs2_xattr_security_get, | 7219 | .get = ocfs2_xattr_security_get, |
| @@ -7257,7 +7257,7 @@ static int ocfs2_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
| 7257 | name, value, size, flags); | 7257 | name, value, size, flags); |
| 7258 | } | 7258 | } |
| 7259 | 7259 | ||
| 7260 | struct xattr_handler ocfs2_xattr_trusted_handler = { | 7260 | const struct xattr_handler ocfs2_xattr_trusted_handler = { |
| 7261 | .prefix = XATTR_TRUSTED_PREFIX, | 7261 | .prefix = XATTR_TRUSTED_PREFIX, |
| 7262 | .list = ocfs2_xattr_trusted_list, | 7262 | .list = ocfs2_xattr_trusted_list, |
| 7263 | .get = ocfs2_xattr_trusted_get, | 7263 | .get = ocfs2_xattr_trusted_get, |
| @@ -7313,7 +7313,7 @@ static int ocfs2_xattr_user_set(struct dentry *dentry, const char *name, | |||
| 7313 | name, value, size, flags); | 7313 | name, value, size, flags); |
| 7314 | } | 7314 | } |
| 7315 | 7315 | ||
| 7316 | struct xattr_handler ocfs2_xattr_user_handler = { | 7316 | const struct xattr_handler ocfs2_xattr_user_handler = { |
| 7317 | .prefix = XATTR_USER_PREFIX, | 7317 | .prefix = XATTR_USER_PREFIX, |
| 7318 | .list = ocfs2_xattr_user_list, | 7318 | .list = ocfs2_xattr_user_list, |
| 7319 | .get = ocfs2_xattr_user_get, | 7319 | .get = ocfs2_xattr_user_get, |
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h index abd72a47f52..aa64bb37a65 100644 --- a/fs/ocfs2/xattr.h +++ b/fs/ocfs2/xattr.h | |||
| @@ -37,12 +37,12 @@ struct ocfs2_security_xattr_info { | |||
| 37 | size_t value_len; | 37 | size_t value_len; |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | extern struct xattr_handler ocfs2_xattr_user_handler; | 40 | extern const struct xattr_handler ocfs2_xattr_user_handler; |
| 41 | extern struct xattr_handler ocfs2_xattr_trusted_handler; | 41 | extern const struct xattr_handler ocfs2_xattr_trusted_handler; |
| 42 | extern struct xattr_handler ocfs2_xattr_security_handler; | 42 | extern const struct xattr_handler ocfs2_xattr_security_handler; |
| 43 | extern struct xattr_handler ocfs2_xattr_acl_access_handler; | 43 | extern const struct xattr_handler ocfs2_xattr_acl_access_handler; |
| 44 | extern struct xattr_handler ocfs2_xattr_acl_default_handler; | 44 | extern const struct xattr_handler ocfs2_xattr_acl_default_handler; |
| 45 | extern struct xattr_handler *ocfs2_xattr_handlers[]; | 45 | extern const struct xattr_handler *ocfs2_xattr_handlers[]; |
| 46 | 46 | ||
| 47 | ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); | 47 | ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); |
| 48 | int ocfs2_xattr_get_nolock(struct inode *, struct buffer_head *, int, | 48 | int ocfs2_xattr_get_nolock(struct inode *, struct buffer_head *, int, |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index b44bb835e8e..089839a6cc6 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
| @@ -37,9 +37,7 @@ struct inode *omfs_new_inode(struct inode *dir, int mode) | |||
| 37 | goto fail; | 37 | goto fail; |
| 38 | 38 | ||
| 39 | inode->i_ino = new_block; | 39 | inode->i_ino = new_block; |
| 40 | inode->i_mode = mode; | 40 | inode_init_owner(inode, NULL, mode); |
| 41 | inode->i_uid = current_fsuid(); | ||
| 42 | inode->i_gid = current_fsgid(); | ||
| 43 | inode->i_mapping->a_ops = &omfs_aops; | 41 | inode->i_mapping->a_ops = &omfs_aops; |
| 44 | 42 | ||
| 45 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 43 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/securebits.h> | 17 | #include <linux/securebits.h> |
| 18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
| 19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
| 20 | #include <linux/vfs.h> | ||
| 21 | #include <linux/fcntl.h> | 20 | #include <linux/fcntl.h> |
| 22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 23 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
| @@ -33,171 +32,6 @@ | |||
| 33 | 32 | ||
| 34 | #include "internal.h" | 33 | #include "internal.h" |
| 35 | 34 | ||
| 36 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | ||
| 37 | { | ||
| 38 | int retval = -ENODEV; | ||
| 39 | |||
| 40 | if (dentry) { | ||
| 41 | retval = -ENOSYS; | ||
| 42 | if (dentry->d_sb->s_op->statfs) { | ||
| 43 | memset(buf, 0, sizeof(*buf)); | ||
| 44 | retval = security_sb_statfs(dentry); | ||
| 45 | if (retval) | ||
| 46 | return retval; | ||
| 47 | retval = dentry->d_sb->s_op->statfs(dentry, buf); | ||
| 48 | if (retval == 0 && buf->f_frsize == 0) | ||
| 49 | buf->f_frsize = buf->f_bsize; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | return retval; | ||
| 53 | } | ||
| 54 | |||
| 55 | EXPORT_SYMBOL(vfs_statfs); | ||
| 56 | |||
| 57 | static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) | ||
| 58 | { | ||
| 59 | struct kstatfs st; | ||
| 60 | int retval; | ||
| 61 | |||
| 62 | retval = vfs_statfs(dentry, &st); | ||
| 63 | if (retval) | ||
| 64 | return retval; | ||
| 65 | |||
| 66 | if (sizeof(*buf) == sizeof(st)) | ||
| 67 | memcpy(buf, &st, sizeof(st)); | ||
| 68 | else { | ||
| 69 | if (sizeof buf->f_blocks == 4) { | ||
| 70 | if ((st.f_blocks | st.f_bfree | st.f_bavail | | ||
| 71 | st.f_bsize | st.f_frsize) & | ||
| 72 | 0xffffffff00000000ULL) | ||
| 73 | return -EOVERFLOW; | ||
| 74 | /* | ||
| 75 | * f_files and f_ffree may be -1; it's okay to stuff | ||
| 76 | * that into 32 bits | ||
| 77 | */ | ||
| 78 | if (st.f_files != -1 && | ||
| 79 | (st.f_files & 0xffffffff00000000ULL)) | ||
| 80 | return -EOVERFLOW; | ||
| 81 | if (st.f_ffree != -1 && | ||
| 82 | (st.f_ffree & 0xffffffff00000000ULL)) | ||
| 83 | return -EOVERFLOW; | ||
| 84 | } | ||
| 85 | |||
| 86 | buf->f_type = st.f_type; | ||
| 87 | buf->f_bsize = st.f_bsize; | ||
| 88 | buf->f_blocks = st.f_blocks; | ||
| 89 | buf->f_bfree = st.f_bfree; | ||
| 90 | buf->f_bavail = st.f_bavail; | ||
| 91 | buf->f_files = st.f_files; | ||
| 92 | buf->f_ffree = st.f_ffree; | ||
| 93 | buf->f_fsid = st.f_fsid; | ||
| 94 | buf->f_namelen = st.f_namelen; | ||
| 95 | buf->f_frsize = st.f_frsize; | ||
| 96 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
| 97 | } | ||
| 98 | return 0; | ||
| 99 | } | ||
| 100 | |||
| 101 | static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) | ||
| 102 | { | ||
| 103 | struct kstatfs st; | ||
| 104 | int retval; | ||
| 105 | |||
| 106 | retval = vfs_statfs(dentry, &st); | ||
| 107 | if (retval) | ||
| 108 | return retval; | ||
| 109 | |||
| 110 | if (sizeof(*buf) == sizeof(st)) | ||
| 111 | memcpy(buf, &st, sizeof(st)); | ||
| 112 | else { | ||
| 113 | buf->f_type = st.f_type; | ||
| 114 | buf->f_bsize = st.f_bsize; | ||
| 115 | buf->f_blocks = st.f_blocks; | ||
| 116 | buf->f_bfree = st.f_bfree; | ||
| 117 | buf->f_bavail = st.f_bavail; | ||
| 118 | buf->f_files = st.f_files; | ||
| 119 | buf->f_ffree = st.f_ffree; | ||
| 120 | buf->f_fsid = st.f_fsid; | ||
| 121 | buf->f_namelen = st.f_namelen; | ||
| 122 | buf->f_frsize = st.f_frsize; | ||
| 123 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
| 124 | } | ||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) | ||
| 129 | { | ||
| 130 | struct path path; | ||
| 131 | int error; | ||
| 132 | |||
| 133 | error = user_path(pathname, &path); | ||
| 134 | if (!error) { | ||
| 135 | struct statfs tmp; | ||
| 136 | error = vfs_statfs_native(path.dentry, &tmp); | ||
| 137 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 138 | error = -EFAULT; | ||
| 139 | path_put(&path); | ||
| 140 | } | ||
| 141 | return error; | ||
| 142 | } | ||
| 143 | |||
| 144 | SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) | ||
| 145 | { | ||
| 146 | struct path path; | ||
| 147 | long error; | ||
| 148 | |||
| 149 | if (sz != sizeof(*buf)) | ||
| 150 | return -EINVAL; | ||
| 151 | error = user_path(pathname, &path); | ||
| 152 | if (!error) { | ||
| 153 | struct statfs64 tmp; | ||
| 154 | error = vfs_statfs64(path.dentry, &tmp); | ||
| 155 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 156 | error = -EFAULT; | ||
| 157 | path_put(&path); | ||
| 158 | } | ||
| 159 | return error; | ||
| 160 | } | ||
| 161 | |||
| 162 | SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) | ||
| 163 | { | ||
| 164 | struct file * file; | ||
| 165 | struct statfs tmp; | ||
| 166 | int error; | ||
| 167 | |||
| 168 | error = -EBADF; | ||
| 169 | file = fget(fd); | ||
| 170 | if (!file) | ||
| 171 | goto out; | ||
| 172 | error = vfs_statfs_native(file->f_path.dentry, &tmp); | ||
| 173 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 174 | error = -EFAULT; | ||
| 175 | fput(file); | ||
| 176 | out: | ||
| 177 | return error; | ||
| 178 | } | ||
| 179 | |||
| 180 | SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) | ||
| 181 | { | ||
| 182 | struct file * file; | ||
| 183 | struct statfs64 tmp; | ||
| 184 | int error; | ||
| 185 | |||
| 186 | if (sz != sizeof(*buf)) | ||
| 187 | return -EINVAL; | ||
| 188 | |||
| 189 | error = -EBADF; | ||
| 190 | file = fget(fd); | ||
| 191 | if (!file) | ||
| 192 | goto out; | ||
| 193 | error = vfs_statfs64(file->f_path.dentry, &tmp); | ||
| 194 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 195 | error = -EFAULT; | ||
| 196 | fput(file); | ||
| 197 | out: | ||
| 198 | return error; | ||
| 199 | } | ||
| 200 | |||
| 201 | int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, | 35 | int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, |
| 202 | struct file *filp) | 36 | struct file *filp) |
| 203 | { | 37 | { |
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c index 9e346c19bbb..9efb2cfe241 100644 --- a/fs/partitions/efi.c +++ b/fs/partitions/efi.c | |||
| @@ -626,7 +626,7 @@ int efi_partition(struct parsed_partitions *state) | |||
| 626 | /* If this is a RAID volume, tell md */ | 626 | /* If this is a RAID volume, tell md */ |
| 627 | if (!efi_guidcmp(ptes[i].partition_type_guid, | 627 | if (!efi_guidcmp(ptes[i].partition_type_guid, |
| 628 | PARTITION_LINUX_RAID_GUID)) | 628 | PARTITION_LINUX_RAID_GUID)) |
| 629 | state->parts[i+1].flags = 1; | 629 | state->parts[i + 1].flags = ADDPART_FLAG_RAID; |
| 630 | } | 630 | } |
| 631 | kfree(ptes); | 631 | kfree(ptes); |
| 632 | kfree(gpt); | 632 | kfree(gpt); |
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c index 13e27b0082f..74465ff7c26 100644 --- a/fs/partitions/mac.c +++ b/fs/partitions/mac.c | |||
| @@ -75,7 +75,7 @@ int mac_partition(struct parsed_partitions *state) | |||
| 75 | be32_to_cpu(part->block_count) * (secsize/512)); | 75 | be32_to_cpu(part->block_count) * (secsize/512)); |
| 76 | 76 | ||
| 77 | if (!strnicmp(part->type, "Linux_RAID", 10)) | 77 | if (!strnicmp(part->type, "Linux_RAID", 10)) |
| 78 | state->parts[slot].flags = 1; | 78 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
| 79 | #ifdef CONFIG_PPC_PMAC | 79 | #ifdef CONFIG_PPC_PMAC |
| 80 | /* | 80 | /* |
| 81 | * If this is the first bootable partition, tell the | 81 | * If this is the first bootable partition, tell the |
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 645a68d8c05..15bfb7b1e04 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c | |||
| @@ -498,7 +498,7 @@ int msdos_partition(struct parsed_partitions *state) | |||
| 498 | } | 498 | } |
| 499 | put_partition(state, slot, start, size); | 499 | put_partition(state, slot, start, size); |
| 500 | if (SYS_IND(p) == LINUX_RAID_PARTITION) | 500 | if (SYS_IND(p) == LINUX_RAID_PARTITION) |
| 501 | state->parts[slot].flags = 1; | 501 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
| 502 | if (SYS_IND(p) == DM6_PARTITION) | 502 | if (SYS_IND(p) == DM6_PARTITION) |
| 503 | printk("[DM]"); | 503 | printk("[DM]"); |
| 504 | if (SYS_IND(p) == EZD_PARTITION) | 504 | if (SYS_IND(p) == EZD_PARTITION) |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index cfc78826da9..ce3dfd066f5 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
| @@ -45,36 +45,22 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd, | |||
| 45 | return security_quotactl(cmd, type, id, sb); | 45 | return security_quotactl(cmd, type, id, sb); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static void quota_sync_one(struct super_block *sb, void *arg) | ||
| 49 | { | ||
| 50 | if (sb->s_qcop && sb->s_qcop->quota_sync) | ||
| 51 | sb->s_qcop->quota_sync(sb, *(int *)arg, 1); | ||
| 52 | } | ||
| 53 | |||
| 48 | static int quota_sync_all(int type) | 54 | static int quota_sync_all(int type) |
| 49 | { | 55 | { |
| 50 | struct super_block *sb; | ||
| 51 | int ret; | 56 | int ret; |
| 52 | 57 | ||
| 53 | if (type >= MAXQUOTAS) | 58 | if (type >= MAXQUOTAS) |
| 54 | return -EINVAL; | 59 | return -EINVAL; |
| 55 | ret = security_quotactl(Q_SYNC, type, 0, NULL); | 60 | ret = security_quotactl(Q_SYNC, type, 0, NULL); |
| 56 | if (ret) | 61 | if (!ret) |
| 57 | return ret; | 62 | iterate_supers(quota_sync_one, &type); |
| 58 | 63 | return ret; | |
| 59 | spin_lock(&sb_lock); | ||
| 60 | restart: | ||
| 61 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
| 62 | if (!sb->s_qcop || !sb->s_qcop->quota_sync) | ||
| 63 | continue; | ||
| 64 | |||
| 65 | sb->s_count++; | ||
| 66 | spin_unlock(&sb_lock); | ||
| 67 | down_read(&sb->s_umount); | ||
| 68 | if (sb->s_root) | ||
| 69 | sb->s_qcop->quota_sync(sb, type, 1); | ||
| 70 | up_read(&sb->s_umount); | ||
| 71 | spin_lock(&sb_lock); | ||
| 72 | if (__put_super_and_need_restart(sb)) | ||
| 73 | goto restart; | ||
| 74 | } | ||
| 75 | spin_unlock(&sb_lock); | ||
| 76 | |||
| 77 | return 0; | ||
| 78 | } | 64 | } |
| 79 | 65 | ||
| 80 | static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, | 66 | static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index f47cd212dee..a5ebae70dc6 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
| @@ -52,14 +52,13 @@ static struct backing_dev_info ramfs_backing_dev_info = { | |||
| 52 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, | 52 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | 55 | struct inode *ramfs_get_inode(struct super_block *sb, |
| 56 | const struct inode *dir, int mode, dev_t dev) | ||
| 56 | { | 57 | { |
| 57 | struct inode * inode = new_inode(sb); | 58 | struct inode * inode = new_inode(sb); |
| 58 | 59 | ||
| 59 | if (inode) { | 60 | if (inode) { |
| 60 | inode->i_mode = mode; | 61 | inode_init_owner(inode, dir, mode); |
| 61 | inode->i_uid = current_fsuid(); | ||
| 62 | inode->i_gid = current_fsgid(); | ||
| 63 | inode->i_mapping->a_ops = &ramfs_aops; | 62 | inode->i_mapping->a_ops = &ramfs_aops; |
| 64 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; | 63 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; |
| 65 | mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); | 64 | mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); |
| @@ -95,15 +94,10 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | |||
| 95 | static int | 94 | static int |
| 96 | ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | 95 | ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) |
| 97 | { | 96 | { |
| 98 | struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev); | 97 | struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev); |
| 99 | int error = -ENOSPC; | 98 | int error = -ENOSPC; |
| 100 | 99 | ||
| 101 | if (inode) { | 100 | if (inode) { |
| 102 | if (dir->i_mode & S_ISGID) { | ||
| 103 | inode->i_gid = dir->i_gid; | ||
| 104 | if (S_ISDIR(mode)) | ||
| 105 | inode->i_mode |= S_ISGID; | ||
| 106 | } | ||
| 107 | d_instantiate(dentry, inode); | 101 | d_instantiate(dentry, inode); |
| 108 | dget(dentry); /* Extra count - pin the dentry in core */ | 102 | dget(dentry); /* Extra count - pin the dentry in core */ |
| 109 | error = 0; | 103 | error = 0; |
| @@ -130,13 +124,11 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * | |||
| 130 | struct inode *inode; | 124 | struct inode *inode; |
| 131 | int error = -ENOSPC; | 125 | int error = -ENOSPC; |
| 132 | 126 | ||
| 133 | inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); | 127 | inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0); |
| 134 | if (inode) { | 128 | if (inode) { |
| 135 | int l = strlen(symname)+1; | 129 | int l = strlen(symname)+1; |
| 136 | error = page_symlink(inode, symname, l); | 130 | error = page_symlink(inode, symname, l); |
| 137 | if (!error) { | 131 | if (!error) { |
| 138 | if (dir->i_mode & S_ISGID) | ||
| 139 | inode->i_gid = dir->i_gid; | ||
| 140 | d_instantiate(dentry, inode); | 132 | d_instantiate(dentry, inode); |
| 141 | dget(dentry); | 133 | dget(dentry); |
| 142 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | 134 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
| @@ -241,7 +233,7 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 241 | sb->s_op = &ramfs_ops; | 233 | sb->s_op = &ramfs_ops; |
| 242 | sb->s_time_gran = 1; | 234 | sb->s_time_gran = 1; |
| 243 | 235 | ||
| 244 | inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0); | 236 | inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0); |
| 245 | if (!inode) { | 237 | if (!inode) { |
| 246 | err = -ENOMEM; | 238 | err = -ENOMEM; |
| 247 | goto fail; | 239 | goto fail; |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index d0c43cb99ff..ee78d4a0086 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
| @@ -561,23 +561,13 @@ static int drop_new_inode(struct inode *inode) | |||
| 561 | */ | 561 | */ |
| 562 | static int new_inode_init(struct inode *inode, struct inode *dir, int mode) | 562 | static int new_inode_init(struct inode *inode, struct inode *dir, int mode) |
| 563 | { | 563 | { |
| 564 | |||
| 565 | /* the quota init calls have to know who to charge the quota to, so | ||
| 566 | ** we have to set uid and gid here | ||
| 567 | */ | ||
| 568 | inode->i_uid = current_fsuid(); | ||
| 569 | inode->i_mode = mode; | ||
| 570 | /* Make inode invalid - just in case we are going to drop it before | 564 | /* Make inode invalid - just in case we are going to drop it before |
| 571 | * the initialization happens */ | 565 | * the initialization happens */ |
| 572 | INODE_PKEY(inode)->k_objectid = 0; | 566 | INODE_PKEY(inode)->k_objectid = 0; |
| 573 | 567 | /* the quota init calls have to know who to charge the quota to, so | |
| 574 | if (dir->i_mode & S_ISGID) { | 568 | ** we have to set uid and gid here |
| 575 | inode->i_gid = dir->i_gid; | 569 | */ |
| 576 | if (S_ISDIR(mode)) | 570 | inode_init_owner(inode, dir, mode); |
| 577 | inode->i_mode |= S_ISGID; | ||
| 578 | } else { | ||
| 579 | inode->i_gid = current_fsgid(); | ||
| 580 | } | ||
| 581 | dquot_initialize(inode); | 571 | dquot_initialize(inode); |
| 582 | return 0; | 572 | return 0; |
| 583 | } | 573 | } |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index e7cc00e636d..8c4cf273c67 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -723,11 +723,11 @@ out: | |||
| 723 | (handler) = *(handlers)++) | 723 | (handler) = *(handlers)++) |
| 724 | 724 | ||
| 725 | /* This is the implementation for the xattr plugin infrastructure */ | 725 | /* This is the implementation for the xattr plugin infrastructure */ |
| 726 | static inline struct xattr_handler * | 726 | static inline const struct xattr_handler * |
| 727 | find_xattr_handler_prefix(struct xattr_handler **handlers, | 727 | find_xattr_handler_prefix(const struct xattr_handler **handlers, |
| 728 | const char *name) | 728 | const char *name) |
| 729 | { | 729 | { |
| 730 | struct xattr_handler *xah; | 730 | const struct xattr_handler *xah; |
| 731 | 731 | ||
| 732 | if (!handlers) | 732 | if (!handlers) |
| 733 | return NULL; | 733 | return NULL; |
| @@ -748,7 +748,7 @@ ssize_t | |||
| 748 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, | 748 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, |
| 749 | size_t size) | 749 | size_t size) |
| 750 | { | 750 | { |
| 751 | struct xattr_handler *handler; | 751 | const struct xattr_handler *handler; |
| 752 | 752 | ||
| 753 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); | 753 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
| 754 | 754 | ||
| @@ -767,7 +767,7 @@ int | |||
| 767 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 767 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
| 768 | size_t size, int flags) | 768 | size_t size, int flags) |
| 769 | { | 769 | { |
| 770 | struct xattr_handler *handler; | 770 | const struct xattr_handler *handler; |
| 771 | 771 | ||
| 772 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); | 772 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
| 773 | 773 | ||
| @@ -784,7 +784,7 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
| 784 | */ | 784 | */ |
| 785 | int reiserfs_removexattr(struct dentry *dentry, const char *name) | 785 | int reiserfs_removexattr(struct dentry *dentry, const char *name) |
| 786 | { | 786 | { |
| 787 | struct xattr_handler *handler; | 787 | const struct xattr_handler *handler; |
| 788 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); | 788 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
| 789 | 789 | ||
| 790 | if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) | 790 | if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
| @@ -807,7 +807,7 @@ static int listxattr_filler(void *buf, const char *name, int namelen, | |||
| 807 | size_t size; | 807 | size_t size; |
| 808 | if (name[0] != '.' || | 808 | if (name[0] != '.' || |
| 809 | (namelen != 1 && (name[1] != '.' || namelen != 2))) { | 809 | (namelen != 1 && (name[1] != '.' || namelen != 2))) { |
| 810 | struct xattr_handler *handler; | 810 | const struct xattr_handler *handler; |
| 811 | handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, | 811 | handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, |
| 812 | name); | 812 | name); |
| 813 | if (!handler) /* Unsupported xattr name */ | 813 | if (!handler) /* Unsupported xattr name */ |
| @@ -920,7 +920,7 @@ static int create_privroot(struct dentry *dentry) { return 0; } | |||
| 920 | #endif | 920 | #endif |
| 921 | 921 | ||
| 922 | /* Actual operations that are exported to VFS-land */ | 922 | /* Actual operations that are exported to VFS-land */ |
| 923 | struct xattr_handler *reiserfs_xattr_handlers[] = { | 923 | const struct xattr_handler *reiserfs_xattr_handlers[] = { |
| 924 | #ifdef CONFIG_REISERFS_FS_XATTR | 924 | #ifdef CONFIG_REISERFS_FS_XATTR |
| 925 | &reiserfs_xattr_user_handler, | 925 | &reiserfs_xattr_user_handler, |
| 926 | &reiserfs_xattr_trusted_handler, | 926 | &reiserfs_xattr_trusted_handler, |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 9cdb759645a..536d697a8a2 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
| @@ -500,7 +500,7 @@ static size_t posix_acl_access_list(struct dentry *dentry, char *list, | |||
| 500 | return size; | 500 | return size; |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | struct xattr_handler reiserfs_posix_acl_access_handler = { | 503 | const struct xattr_handler reiserfs_posix_acl_access_handler = { |
| 504 | .prefix = POSIX_ACL_XATTR_ACCESS, | 504 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 505 | .flags = ACL_TYPE_ACCESS, | 505 | .flags = ACL_TYPE_ACCESS, |
| 506 | .get = posix_acl_get, | 506 | .get = posix_acl_get, |
| @@ -520,7 +520,7 @@ static size_t posix_acl_default_list(struct dentry *dentry, char *list, | |||
| 520 | return size; | 520 | return size; |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | struct xattr_handler reiserfs_posix_acl_default_handler = { | 523 | const struct xattr_handler reiserfs_posix_acl_default_handler = { |
| 524 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 524 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 525 | .flags = ACL_TYPE_DEFAULT, | 525 | .flags = ACL_TYPE_DEFAULT, |
| 526 | .get = posix_acl_get, | 526 | .get = posix_acl_get, |
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 7271a477c04..237c6928d3c 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c | |||
| @@ -111,7 +111,7 @@ void reiserfs_security_free(struct reiserfs_security_handle *sec) | |||
| 111 | sec->value = NULL; | 111 | sec->value = NULL; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | struct xattr_handler reiserfs_xattr_security_handler = { | 114 | const struct xattr_handler reiserfs_xattr_security_handler = { |
| 115 | .prefix = XATTR_SECURITY_PREFIX, | 115 | .prefix = XATTR_SECURITY_PREFIX, |
| 116 | .get = security_get, | 116 | .get = security_get, |
| 117 | .set = security_set, | 117 | .set = security_set, |
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index 5b08aaca3da..9883736ce3e 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c | |||
| @@ -48,7 +48,7 @@ static size_t trusted_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 48 | return len; | 48 | return len; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | struct xattr_handler reiserfs_xattr_trusted_handler = { | 51 | const struct xattr_handler reiserfs_xattr_trusted_handler = { |
| 52 | .prefix = XATTR_TRUSTED_PREFIX, | 52 | .prefix = XATTR_TRUSTED_PREFIX, |
| 53 | .get = trusted_get, | 53 | .get = trusted_get, |
| 54 | .set = trusted_set, | 54 | .set = trusted_set, |
diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index 75d59c49b91..45ae1a00013 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c | |||
| @@ -44,7 +44,7 @@ static size_t user_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 44 | return len; | 44 | return len; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | struct xattr_handler reiserfs_xattr_user_handler = { | 47 | const struct xattr_handler reiserfs_xattr_user_handler = { |
| 48 | .prefix = XATTR_USER_PREFIX, | 48 | .prefix = XATTR_USER_PREFIX, |
| 49 | .get = user_get, | 49 | .get = user_get, |
| 50 | .set = user_set, | 50 | .set = user_set, |
diff --git a/fs/statfs.c b/fs/statfs.c new file mode 100644 index 00000000000..4ef021f3b61 --- /dev/null +++ b/fs/statfs.c | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | #include <linux/syscalls.h> | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/fs.h> | ||
| 4 | #include <linux/file.h> | ||
| 5 | #include <linux/namei.h> | ||
| 6 | #include <linux/statfs.h> | ||
| 7 | #include <linux/security.h> | ||
| 8 | #include <linux/uaccess.h> | ||
| 9 | |||
| 10 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | ||
| 11 | { | ||
| 12 | int retval = -ENODEV; | ||
| 13 | |||
| 14 | if (dentry) { | ||
| 15 | retval = -ENOSYS; | ||
| 16 | if (dentry->d_sb->s_op->statfs) { | ||
| 17 | memset(buf, 0, sizeof(*buf)); | ||
| 18 | retval = security_sb_statfs(dentry); | ||
| 19 | if (retval) | ||
| 20 | return retval; | ||
| 21 | retval = dentry->d_sb->s_op->statfs(dentry, buf); | ||
| 22 | if (retval == 0 && buf->f_frsize == 0) | ||
| 23 | buf->f_frsize = buf->f_bsize; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | return retval; | ||
| 27 | } | ||
| 28 | |||
| 29 | EXPORT_SYMBOL(vfs_statfs); | ||
| 30 | |||
| 31 | static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) | ||
| 32 | { | ||
| 33 | struct kstatfs st; | ||
| 34 | int retval; | ||
| 35 | |||
| 36 | retval = vfs_statfs(dentry, &st); | ||
| 37 | if (retval) | ||
| 38 | return retval; | ||
| 39 | |||
| 40 | if (sizeof(*buf) == sizeof(st)) | ||
| 41 | memcpy(buf, &st, sizeof(st)); | ||
| 42 | else { | ||
| 43 | if (sizeof buf->f_blocks == 4) { | ||
| 44 | if ((st.f_blocks | st.f_bfree | st.f_bavail | | ||
| 45 | st.f_bsize | st.f_frsize) & | ||
| 46 | 0xffffffff00000000ULL) | ||
| 47 | return -EOVERFLOW; | ||
| 48 | /* | ||
| 49 | * f_files and f_ffree may be -1; it's okay to stuff | ||
| 50 | * that into 32 bits | ||
| 51 | */ | ||
| 52 | if (st.f_files != -1 && | ||
| 53 | (st.f_files & 0xffffffff00000000ULL)) | ||
| 54 | return -EOVERFLOW; | ||
| 55 | if (st.f_ffree != -1 && | ||
| 56 | (st.f_ffree & 0xffffffff00000000ULL)) | ||
| 57 | return -EOVERFLOW; | ||
| 58 | } | ||
| 59 | |||
| 60 | buf->f_type = st.f_type; | ||
| 61 | buf->f_bsize = st.f_bsize; | ||
| 62 | buf->f_blocks = st.f_blocks; | ||
| 63 | buf->f_bfree = st.f_bfree; | ||
| 64 | buf->f_bavail = st.f_bavail; | ||
| 65 | buf->f_files = st.f_files; | ||
| 66 | buf->f_ffree = st.f_ffree; | ||
| 67 | buf->f_fsid = st.f_fsid; | ||
| 68 | buf->f_namelen = st.f_namelen; | ||
| 69 | buf->f_frsize = st.f_frsize; | ||
| 70 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
| 71 | } | ||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) | ||
| 76 | { | ||
| 77 | struct kstatfs st; | ||
| 78 | int retval; | ||
| 79 | |||
| 80 | retval = vfs_statfs(dentry, &st); | ||
| 81 | if (retval) | ||
| 82 | return retval; | ||
| 83 | |||
| 84 | if (sizeof(*buf) == sizeof(st)) | ||
| 85 | memcpy(buf, &st, sizeof(st)); | ||
| 86 | else { | ||
| 87 | buf->f_type = st.f_type; | ||
| 88 | buf->f_bsize = st.f_bsize; | ||
| 89 | buf->f_blocks = st.f_blocks; | ||
| 90 | buf->f_bfree = st.f_bfree; | ||
| 91 | buf->f_bavail = st.f_bavail; | ||
| 92 | buf->f_files = st.f_files; | ||
| 93 | buf->f_ffree = st.f_ffree; | ||
| 94 | buf->f_fsid = st.f_fsid; | ||
| 95 | buf->f_namelen = st.f_namelen; | ||
| 96 | buf->f_frsize = st.f_frsize; | ||
| 97 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
| 98 | } | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) | ||
| 103 | { | ||
| 104 | struct path path; | ||
| 105 | int error; | ||
| 106 | |||
| 107 | error = user_path(pathname, &path); | ||
| 108 | if (!error) { | ||
| 109 | struct statfs tmp; | ||
| 110 | error = vfs_statfs_native(path.dentry, &tmp); | ||
| 111 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 112 | error = -EFAULT; | ||
| 113 | path_put(&path); | ||
| 114 | } | ||
| 115 | return error; | ||
| 116 | } | ||
| 117 | |||
| 118 | SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) | ||
| 119 | { | ||
| 120 | struct path path; | ||
| 121 | long error; | ||
| 122 | |||
| 123 | if (sz != sizeof(*buf)) | ||
| 124 | return -EINVAL; | ||
| 125 | error = user_path(pathname, &path); | ||
| 126 | if (!error) { | ||
| 127 | struct statfs64 tmp; | ||
| 128 | error = vfs_statfs64(path.dentry, &tmp); | ||
| 129 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 130 | error = -EFAULT; | ||
| 131 | path_put(&path); | ||
| 132 | } | ||
| 133 | return error; | ||
| 134 | } | ||
| 135 | |||
| 136 | SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) | ||
| 137 | { | ||
| 138 | struct file *file; | ||
| 139 | struct statfs tmp; | ||
| 140 | int error; | ||
| 141 | |||
| 142 | error = -EBADF; | ||
| 143 | file = fget(fd); | ||
| 144 | if (!file) | ||
| 145 | goto out; | ||
| 146 | error = vfs_statfs_native(file->f_path.dentry, &tmp); | ||
| 147 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 148 | error = -EFAULT; | ||
| 149 | fput(file); | ||
| 150 | out: | ||
| 151 | return error; | ||
| 152 | } | ||
| 153 | |||
| 154 | SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) | ||
| 155 | { | ||
| 156 | struct file *file; | ||
| 157 | struct statfs64 tmp; | ||
| 158 | int error; | ||
| 159 | |||
| 160 | if (sz != sizeof(*buf)) | ||
| 161 | return -EINVAL; | ||
| 162 | |||
| 163 | error = -EBADF; | ||
| 164 | file = fget(fd); | ||
| 165 | if (!file) | ||
| 166 | goto out; | ||
| 167 | error = vfs_statfs64(file->f_path.dentry, &tmp); | ||
| 168 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
| 169 | error = -EFAULT; | ||
| 170 | fput(file); | ||
| 171 | out: | ||
| 172 | return error; | ||
| 173 | } | ||
| 174 | |||
| 175 | SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) | ||
| 176 | { | ||
| 177 | struct super_block *s; | ||
| 178 | struct ustat tmp; | ||
| 179 | struct kstatfs sbuf; | ||
| 180 | int err; | ||
| 181 | |||
| 182 | s = user_get_super(new_decode_dev(dev)); | ||
| 183 | if (!s) | ||
| 184 | return -EINVAL; | ||
| 185 | |||
| 186 | err = vfs_statfs(s->s_root, &sbuf); | ||
| 187 | drop_super(s); | ||
| 188 | if (err) | ||
| 189 | return err; | ||
| 190 | |||
| 191 | memset(&tmp,0,sizeof(struct ustat)); | ||
| 192 | tmp.f_tfree = sbuf.f_bfree; | ||
| 193 | tmp.f_tinode = sbuf.f_ffree; | ||
| 194 | |||
| 195 | return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0; | ||
| 196 | } | ||
diff --git a/fs/super.c b/fs/super.c index 1527e6a0ee3..69688b15f1f 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -22,23 +22,15 @@ | |||
| 22 | 22 | ||
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/smp_lock.h> | ||
| 27 | #include <linux/acct.h> | 25 | #include <linux/acct.h> |
| 28 | #include <linux/blkdev.h> | 26 | #include <linux/blkdev.h> |
| 29 | #include <linux/quotaops.h> | 27 | #include <linux/quotaops.h> |
| 30 | #include <linux/namei.h> | ||
| 31 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
| 32 | #include <linux/security.h> | 29 | #include <linux/security.h> |
| 33 | #include <linux/syscalls.h> | ||
| 34 | #include <linux/vfs.h> | ||
| 35 | #include <linux/writeback.h> /* for the emergency remount stuff */ | 30 | #include <linux/writeback.h> /* for the emergency remount stuff */ |
| 36 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
| 37 | #include <linux/kobject.h> | ||
| 38 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
| 39 | #include <linux/file.h> | ||
| 40 | #include <linux/backing-dev.h> | 33 | #include <linux/backing-dev.h> |
| 41 | #include <asm/uaccess.h> | ||
| 42 | #include "internal.h" | 34 | #include "internal.h" |
| 43 | 35 | ||
| 44 | 36 | ||
| @@ -93,9 +85,10 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
| 93 | * subclass. | 85 | * subclass. |
| 94 | */ | 86 | */ |
| 95 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | 87 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); |
| 96 | s->s_count = S_BIAS; | 88 | s->s_count = 1; |
| 97 | atomic_set(&s->s_active, 1); | 89 | atomic_set(&s->s_active, 1); |
| 98 | mutex_init(&s->s_vfs_rename_mutex); | 90 | mutex_init(&s->s_vfs_rename_mutex); |
| 91 | lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); | ||
| 99 | mutex_init(&s->s_dquot.dqio_mutex); | 92 | mutex_init(&s->s_dquot.dqio_mutex); |
| 100 | mutex_init(&s->s_dquot.dqonoff_mutex); | 93 | mutex_init(&s->s_dquot.dqonoff_mutex); |
| 101 | init_rwsem(&s->s_dquot.dqptr_sem); | 94 | init_rwsem(&s->s_dquot.dqptr_sem); |
| @@ -127,39 +120,14 @@ static inline void destroy_super(struct super_block *s) | |||
| 127 | /* Superblock refcounting */ | 120 | /* Superblock refcounting */ |
| 128 | 121 | ||
| 129 | /* | 122 | /* |
| 130 | * Drop a superblock's refcount. Returns non-zero if the superblock was | 123 | * Drop a superblock's refcount. The caller must hold sb_lock. |
| 131 | * destroyed. The caller must hold sb_lock. | ||
| 132 | */ | 124 | */ |
| 133 | static int __put_super(struct super_block *sb) | 125 | void __put_super(struct super_block *sb) |
| 134 | { | 126 | { |
| 135 | int ret = 0; | ||
| 136 | |||
| 137 | if (!--sb->s_count) { | 127 | if (!--sb->s_count) { |
| 128 | list_del_init(&sb->s_list); | ||
| 138 | destroy_super(sb); | 129 | destroy_super(sb); |
| 139 | ret = 1; | ||
| 140 | } | 130 | } |
| 141 | return ret; | ||
| 142 | } | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Drop a superblock's refcount. | ||
| 146 | * Returns non-zero if the superblock is about to be destroyed and | ||
| 147 | * at least is already removed from super_blocks list, so if we are | ||
| 148 | * making a loop through super blocks then we need to restart. | ||
| 149 | * The caller must hold sb_lock. | ||
| 150 | */ | ||
| 151 | int __put_super_and_need_restart(struct super_block *sb) | ||
| 152 | { | ||
| 153 | /* check for race with generic_shutdown_super() */ | ||
| 154 | if (list_empty(&sb->s_list)) { | ||
| 155 | /* super block is removed, need to restart... */ | ||
| 156 | __put_super(sb); | ||
| 157 | return 1; | ||
| 158 | } | ||
| 159 | /* can't be the last, since s_list is still in use */ | ||
| 160 | sb->s_count--; | ||
| 161 | BUG_ON(sb->s_count == 0); | ||
| 162 | return 0; | ||
| 163 | } | 131 | } |
| 164 | 132 | ||
| 165 | /** | 133 | /** |
| @@ -178,57 +146,48 @@ void put_super(struct super_block *sb) | |||
| 178 | 146 | ||
| 179 | 147 | ||
| 180 | /** | 148 | /** |
| 181 | * deactivate_super - drop an active reference to superblock | 149 | * deactivate_locked_super - drop an active reference to superblock |
| 182 | * @s: superblock to deactivate | 150 | * @s: superblock to deactivate |
| 183 | * | 151 | * |
| 184 | * Drops an active reference to superblock, acquiring a temprory one if | 152 | * Drops an active reference to superblock, converting it into a temprory |
| 185 | * there is no active references left. In that case we lock superblock, | 153 | * one if there is no other active references left. In that case we |
| 186 | * tell fs driver to shut it down and drop the temporary reference we | 154 | * tell fs driver to shut it down and drop the temporary reference we |
| 187 | * had just acquired. | 155 | * had just acquired. |
| 156 | * | ||
| 157 | * Caller holds exclusive lock on superblock; that lock is released. | ||
| 188 | */ | 158 | */ |
| 189 | void deactivate_super(struct super_block *s) | 159 | void deactivate_locked_super(struct super_block *s) |
| 190 | { | 160 | { |
| 191 | struct file_system_type *fs = s->s_type; | 161 | struct file_system_type *fs = s->s_type; |
| 192 | if (atomic_dec_and_lock(&s->s_active, &sb_lock)) { | 162 | if (atomic_dec_and_test(&s->s_active)) { |
| 193 | s->s_count -= S_BIAS-1; | ||
| 194 | spin_unlock(&sb_lock); | ||
| 195 | vfs_dq_off(s, 0); | 163 | vfs_dq_off(s, 0); |
| 196 | down_write(&s->s_umount); | ||
| 197 | fs->kill_sb(s); | 164 | fs->kill_sb(s); |
| 198 | put_filesystem(fs); | 165 | put_filesystem(fs); |
| 199 | put_super(s); | 166 | put_super(s); |
| 167 | } else { | ||
| 168 | up_write(&s->s_umount); | ||
| 200 | } | 169 | } |
| 201 | } | 170 | } |
| 202 | 171 | ||
| 203 | EXPORT_SYMBOL(deactivate_super); | 172 | EXPORT_SYMBOL(deactivate_locked_super); |
| 204 | 173 | ||
| 205 | /** | 174 | /** |
| 206 | * deactivate_locked_super - drop an active reference to superblock | 175 | * deactivate_super - drop an active reference to superblock |
| 207 | * @s: superblock to deactivate | 176 | * @s: superblock to deactivate |
| 208 | * | 177 | * |
| 209 | * Equivalent of up_write(&s->s_umount); deactivate_super(s);, except that | 178 | * Variant of deactivate_locked_super(), except that superblock is *not* |
| 210 | * it does not unlock it until it's all over. As the result, it's safe to | 179 | * locked by caller. If we are going to drop the final active reference, |
| 211 | * use to dispose of new superblock on ->get_sb() failure exits - nobody | 180 | * lock will be acquired prior to that. |
| 212 | * will see the sucker until it's all over. Equivalent using up_write + | ||
| 213 | * deactivate_super is safe for that purpose only if superblock is either | ||
| 214 | * safe to use or has NULL ->s_root when we unlock. | ||
| 215 | */ | 181 | */ |
| 216 | void deactivate_locked_super(struct super_block *s) | 182 | void deactivate_super(struct super_block *s) |
| 217 | { | 183 | { |
| 218 | struct file_system_type *fs = s->s_type; | 184 | if (!atomic_add_unless(&s->s_active, -1, 1)) { |
| 219 | if (atomic_dec_and_lock(&s->s_active, &sb_lock)) { | 185 | down_write(&s->s_umount); |
| 220 | s->s_count -= S_BIAS-1; | 186 | deactivate_locked_super(s); |
| 221 | spin_unlock(&sb_lock); | ||
| 222 | vfs_dq_off(s, 0); | ||
| 223 | fs->kill_sb(s); | ||
| 224 | put_filesystem(fs); | ||
| 225 | put_super(s); | ||
| 226 | } else { | ||
| 227 | up_write(&s->s_umount); | ||
| 228 | } | 187 | } |
| 229 | } | 188 | } |
| 230 | 189 | ||
| 231 | EXPORT_SYMBOL(deactivate_locked_super); | 190 | EXPORT_SYMBOL(deactivate_super); |
| 232 | 191 | ||
| 233 | /** | 192 | /** |
| 234 | * grab_super - acquire an active reference | 193 | * grab_super - acquire an active reference |
| @@ -243,22 +202,17 @@ EXPORT_SYMBOL(deactivate_locked_super); | |||
| 243 | */ | 202 | */ |
| 244 | static int grab_super(struct super_block *s) __releases(sb_lock) | 203 | static int grab_super(struct super_block *s) __releases(sb_lock) |
| 245 | { | 204 | { |
| 205 | if (atomic_inc_not_zero(&s->s_active)) { | ||
| 206 | spin_unlock(&sb_lock); | ||
| 207 | return 1; | ||
| 208 | } | ||
| 209 | /* it's going away */ | ||
| 246 | s->s_count++; | 210 | s->s_count++; |
| 247 | spin_unlock(&sb_lock); | 211 | spin_unlock(&sb_lock); |
| 212 | /* wait for it to die */ | ||
| 248 | down_write(&s->s_umount); | 213 | down_write(&s->s_umount); |
| 249 | if (s->s_root) { | ||
| 250 | spin_lock(&sb_lock); | ||
| 251 | if (s->s_count > S_BIAS) { | ||
| 252 | atomic_inc(&s->s_active); | ||
| 253 | s->s_count--; | ||
| 254 | spin_unlock(&sb_lock); | ||
| 255 | return 1; | ||
| 256 | } | ||
| 257 | spin_unlock(&sb_lock); | ||
| 258 | } | ||
| 259 | up_write(&s->s_umount); | 214 | up_write(&s->s_umount); |
| 260 | put_super(s); | 215 | put_super(s); |
| 261 | yield(); | ||
| 262 | return 0; | 216 | return 0; |
| 263 | } | 217 | } |
| 264 | 218 | ||
| @@ -321,8 +275,7 @@ void generic_shutdown_super(struct super_block *sb) | |||
| 321 | } | 275 | } |
| 322 | spin_lock(&sb_lock); | 276 | spin_lock(&sb_lock); |
| 323 | /* should be initialized for __put_super_and_need_restart() */ | 277 | /* should be initialized for __put_super_and_need_restart() */ |
| 324 | list_del_init(&sb->s_list); | 278 | list_del_init(&sb->s_instances); |
| 325 | list_del(&sb->s_instances); | ||
| 326 | spin_unlock(&sb_lock); | 279 | spin_unlock(&sb_lock); |
| 327 | up_write(&sb->s_umount); | 280 | up_write(&sb->s_umount); |
| 328 | } | 281 | } |
| @@ -357,6 +310,7 @@ retry: | |||
| 357 | up_write(&s->s_umount); | 310 | up_write(&s->s_umount); |
| 358 | destroy_super(s); | 311 | destroy_super(s); |
| 359 | } | 312 | } |
| 313 | down_write(&old->s_umount); | ||
| 360 | return old; | 314 | return old; |
| 361 | } | 315 | } |
| 362 | } | 316 | } |
| @@ -408,11 +362,12 @@ EXPORT_SYMBOL(drop_super); | |||
| 408 | */ | 362 | */ |
| 409 | void sync_supers(void) | 363 | void sync_supers(void) |
| 410 | { | 364 | { |
| 411 | struct super_block *sb; | 365 | struct super_block *sb, *n; |
| 412 | 366 | ||
| 413 | spin_lock(&sb_lock); | 367 | spin_lock(&sb_lock); |
| 414 | restart: | 368 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { |
| 415 | list_for_each_entry(sb, &super_blocks, s_list) { | 369 | if (list_empty(&sb->s_instances)) |
| 370 | continue; | ||
| 416 | if (sb->s_op->write_super && sb->s_dirt) { | 371 | if (sb->s_op->write_super && sb->s_dirt) { |
| 417 | sb->s_count++; | 372 | sb->s_count++; |
| 418 | spin_unlock(&sb_lock); | 373 | spin_unlock(&sb_lock); |
| @@ -423,14 +378,43 @@ restart: | |||
| 423 | up_read(&sb->s_umount); | 378 | up_read(&sb->s_umount); |
| 424 | 379 | ||
| 425 | spin_lock(&sb_lock); | 380 | spin_lock(&sb_lock); |
| 426 | if (__put_super_and_need_restart(sb)) | 381 | __put_super(sb); |
| 427 | goto restart; | ||
| 428 | } | 382 | } |
| 429 | } | 383 | } |
| 430 | spin_unlock(&sb_lock); | 384 | spin_unlock(&sb_lock); |
| 431 | } | 385 | } |
| 432 | 386 | ||
| 433 | /** | 387 | /** |
| 388 | * iterate_supers - call function for all active superblocks | ||
| 389 | * @f: function to call | ||
| 390 | * @arg: argument to pass to it | ||
| 391 | * | ||
| 392 | * Scans the superblock list and calls given function, passing it | ||
| 393 | * locked superblock and given argument. | ||
| 394 | */ | ||
| 395 | void iterate_supers(void (*f)(struct super_block *, void *), void *arg) | ||
| 396 | { | ||
| 397 | struct super_block *sb, *n; | ||
| 398 | |||
| 399 | spin_lock(&sb_lock); | ||
| 400 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { | ||
| 401 | if (list_empty(&sb->s_instances)) | ||
| 402 | continue; | ||
| 403 | sb->s_count++; | ||
| 404 | spin_unlock(&sb_lock); | ||
| 405 | |||
| 406 | down_read(&sb->s_umount); | ||
| 407 | if (sb->s_root) | ||
| 408 | f(sb, arg); | ||
| 409 | up_read(&sb->s_umount); | ||
| 410 | |||
| 411 | spin_lock(&sb_lock); | ||
| 412 | __put_super(sb); | ||
| 413 | } | ||
| 414 | spin_unlock(&sb_lock); | ||
| 415 | } | ||
| 416 | |||
| 417 | /** | ||
| 434 | * get_super - get the superblock of a device | 418 | * get_super - get the superblock of a device |
| 435 | * @bdev: device to get the superblock for | 419 | * @bdev: device to get the superblock for |
| 436 | * | 420 | * |
| @@ -438,7 +422,7 @@ restart: | |||
| 438 | * mounted on the device given. %NULL is returned if no match is found. | 422 | * mounted on the device given. %NULL is returned if no match is found. |
| 439 | */ | 423 | */ |
| 440 | 424 | ||
| 441 | struct super_block * get_super(struct block_device *bdev) | 425 | struct super_block *get_super(struct block_device *bdev) |
| 442 | { | 426 | { |
| 443 | struct super_block *sb; | 427 | struct super_block *sb; |
| 444 | 428 | ||
| @@ -448,17 +432,20 @@ struct super_block * get_super(struct block_device *bdev) | |||
| 448 | spin_lock(&sb_lock); | 432 | spin_lock(&sb_lock); |
| 449 | rescan: | 433 | rescan: |
| 450 | list_for_each_entry(sb, &super_blocks, s_list) { | 434 | list_for_each_entry(sb, &super_blocks, s_list) { |
| 435 | if (list_empty(&sb->s_instances)) | ||
| 436 | continue; | ||
| 451 | if (sb->s_bdev == bdev) { | 437 | if (sb->s_bdev == bdev) { |
| 452 | sb->s_count++; | 438 | sb->s_count++; |
| 453 | spin_unlock(&sb_lock); | 439 | spin_unlock(&sb_lock); |
| 454 | down_read(&sb->s_umount); | 440 | down_read(&sb->s_umount); |
| 441 | /* still alive? */ | ||
| 455 | if (sb->s_root) | 442 | if (sb->s_root) |
| 456 | return sb; | 443 | return sb; |
| 457 | up_read(&sb->s_umount); | 444 | up_read(&sb->s_umount); |
| 458 | /* restart only when sb is no longer on the list */ | 445 | /* nope, got unmounted */ |
| 459 | spin_lock(&sb_lock); | 446 | spin_lock(&sb_lock); |
| 460 | if (__put_super_and_need_restart(sb)) | 447 | __put_super(sb); |
| 461 | goto rescan; | 448 | goto rescan; |
| 462 | } | 449 | } |
| 463 | } | 450 | } |
| 464 | spin_unlock(&sb_lock); | 451 | spin_unlock(&sb_lock); |
| @@ -473,7 +460,7 @@ EXPORT_SYMBOL(get_super); | |||
| 473 | * | 460 | * |
| 474 | * Scans the superblock list and finds the superblock of the file system | 461 | * Scans the superblock list and finds the superblock of the file system |
| 475 | * mounted on the device given. Returns the superblock with an active | 462 | * mounted on the device given. Returns the superblock with an active |
| 476 | * reference and s_umount held exclusively or %NULL if none was found. | 463 | * reference or %NULL if none was found. |
| 477 | */ | 464 | */ |
| 478 | struct super_block *get_active_super(struct block_device *bdev) | 465 | struct super_block *get_active_super(struct block_device *bdev) |
| 479 | { | 466 | { |
| @@ -482,81 +469,49 @@ struct super_block *get_active_super(struct block_device *bdev) | |||
| 482 | if (!bdev) | 469 | if (!bdev) |
| 483 | return NULL; | 470 | return NULL; |
| 484 | 471 | ||
| 472 | restart: | ||
| 485 | spin_lock(&sb_lock); | 473 | spin_lock(&sb_lock); |
| 486 | list_for_each_entry(sb, &super_blocks, s_list) { | 474 | list_for_each_entry(sb, &super_blocks, s_list) { |
| 487 | if (sb->s_bdev != bdev) | 475 | if (list_empty(&sb->s_instances)) |
| 488 | continue; | 476 | continue; |
| 489 | 477 | if (sb->s_bdev == bdev) { | |
| 490 | sb->s_count++; | 478 | if (grab_super(sb)) /* drops sb_lock */ |
| 491 | spin_unlock(&sb_lock); | ||
| 492 | down_write(&sb->s_umount); | ||
| 493 | if (sb->s_root) { | ||
| 494 | spin_lock(&sb_lock); | ||
| 495 | if (sb->s_count > S_BIAS) { | ||
| 496 | atomic_inc(&sb->s_active); | ||
| 497 | sb->s_count--; | ||
| 498 | spin_unlock(&sb_lock); | ||
| 499 | return sb; | 479 | return sb; |
| 500 | } | 480 | else |
| 501 | spin_unlock(&sb_lock); | 481 | goto restart; |
| 502 | } | 482 | } |
| 503 | up_write(&sb->s_umount); | ||
| 504 | put_super(sb); | ||
| 505 | yield(); | ||
| 506 | spin_lock(&sb_lock); | ||
| 507 | } | 483 | } |
| 508 | spin_unlock(&sb_lock); | 484 | spin_unlock(&sb_lock); |
| 509 | return NULL; | 485 | return NULL; |
| 510 | } | 486 | } |
| 511 | 487 | ||
| 512 | struct super_block * user_get_super(dev_t dev) | 488 | struct super_block *user_get_super(dev_t dev) |
| 513 | { | 489 | { |
| 514 | struct super_block *sb; | 490 | struct super_block *sb; |
| 515 | 491 | ||
| 516 | spin_lock(&sb_lock); | 492 | spin_lock(&sb_lock); |
| 517 | rescan: | 493 | rescan: |
| 518 | list_for_each_entry(sb, &super_blocks, s_list) { | 494 | list_for_each_entry(sb, &super_blocks, s_list) { |
| 495 | if (list_empty(&sb->s_instances)) | ||
| 496 | continue; | ||
| 519 | if (sb->s_dev == dev) { | 497 | if (sb->s_dev == dev) { |
| 520 | sb->s_count++; | 498 | sb->s_count++; |
| 521 | spin_unlock(&sb_lock); | 499 | spin_unlock(&sb_lock); |
| 522 | down_read(&sb->s_umount); | 500 | down_read(&sb->s_umount); |
| 501 | /* still alive? */ | ||
| 523 | if (sb->s_root) | 502 | if (sb->s_root) |
| 524 | return sb; | 503 | return sb; |
| 525 | up_read(&sb->s_umount); | 504 | up_read(&sb->s_umount); |
| 526 | /* restart only when sb is no longer on the list */ | 505 | /* nope, got unmounted */ |
| 527 | spin_lock(&sb_lock); | 506 | spin_lock(&sb_lock); |
| 528 | if (__put_super_and_need_restart(sb)) | 507 | __put_super(sb); |
| 529 | goto rescan; | 508 | goto rescan; |
| 530 | } | 509 | } |
| 531 | } | 510 | } |
| 532 | spin_unlock(&sb_lock); | 511 | spin_unlock(&sb_lock); |
| 533 | return NULL; | 512 | return NULL; |
| 534 | } | 513 | } |
| 535 | 514 | ||
| 536 | SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) | ||
| 537 | { | ||
| 538 | struct super_block *s; | ||
| 539 | struct ustat tmp; | ||
| 540 | struct kstatfs sbuf; | ||
| 541 | int err = -EINVAL; | ||
| 542 | |||
| 543 | s = user_get_super(new_decode_dev(dev)); | ||
| 544 | if (s == NULL) | ||
| 545 | goto out; | ||
| 546 | err = vfs_statfs(s->s_root, &sbuf); | ||
| 547 | drop_super(s); | ||
| 548 | if (err) | ||
| 549 | goto out; | ||
| 550 | |||
| 551 | memset(&tmp,0,sizeof(struct ustat)); | ||
| 552 | tmp.f_tfree = sbuf.f_bfree; | ||
| 553 | tmp.f_tinode = sbuf.f_ffree; | ||
| 554 | |||
| 555 | err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0; | ||
| 556 | out: | ||
| 557 | return err; | ||
| 558 | } | ||
| 559 | |||
| 560 | /** | 515 | /** |
| 561 | * do_remount_sb - asks filesystem to change mount options. | 516 | * do_remount_sb - asks filesystem to change mount options. |
| 562 | * @sb: superblock in question | 517 | * @sb: superblock in question |
| @@ -622,24 +577,24 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
| 622 | 577 | ||
| 623 | static void do_emergency_remount(struct work_struct *work) | 578 | static void do_emergency_remount(struct work_struct *work) |
| 624 | { | 579 | { |
| 625 | struct super_block *sb; | 580 | struct super_block *sb, *n; |
| 626 | 581 | ||
| 627 | spin_lock(&sb_lock); | 582 | spin_lock(&sb_lock); |
| 628 | list_for_each_entry(sb, &super_blocks, s_list) { | 583 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { |
| 584 | if (list_empty(&sb->s_instances)) | ||
| 585 | continue; | ||
| 629 | sb->s_count++; | 586 | sb->s_count++; |
| 630 | spin_unlock(&sb_lock); | 587 | spin_unlock(&sb_lock); |
| 631 | down_write(&sb->s_umount); | 588 | down_write(&sb->s_umount); |
| 632 | if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) { | 589 | if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) { |
| 633 | /* | 590 | /* |
| 634 | * ->remount_fs needs lock_kernel(). | ||
| 635 | * | ||
| 636 | * What lock protects sb->s_flags?? | 591 | * What lock protects sb->s_flags?? |
| 637 | */ | 592 | */ |
| 638 | do_remount_sb(sb, MS_RDONLY, NULL, 1); | 593 | do_remount_sb(sb, MS_RDONLY, NULL, 1); |
| 639 | } | 594 | } |
| 640 | up_write(&sb->s_umount); | 595 | up_write(&sb->s_umount); |
| 641 | put_super(sb); | ||
| 642 | spin_lock(&sb_lock); | 596 | spin_lock(&sb_lock); |
| 597 | __put_super(sb); | ||
| 643 | } | 598 | } |
| 644 | spin_unlock(&sb_lock); | 599 | spin_unlock(&sb_lock); |
| 645 | kfree(work); | 600 | kfree(work); |
| @@ -990,6 +945,96 @@ out: | |||
| 990 | 945 | ||
| 991 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | 946 | EXPORT_SYMBOL_GPL(vfs_kern_mount); |
| 992 | 947 | ||
| 948 | /** | ||
| 949 | * freeze_super -- lock the filesystem and force it into a consistent state | ||
| 950 | * @super: the super to lock | ||
| 951 | * | ||
| 952 | * Syncs the super to make sure the filesystem is consistent and calls the fs's | ||
| 953 | * freeze_fs. Subsequent calls to this without first thawing the fs will return | ||
| 954 | * -EBUSY. | ||
| 955 | */ | ||
| 956 | int freeze_super(struct super_block *sb) | ||
| 957 | { | ||
| 958 | int ret; | ||
| 959 | |||
| 960 | atomic_inc(&sb->s_active); | ||
| 961 | down_write(&sb->s_umount); | ||
| 962 | if (sb->s_frozen) { | ||
| 963 | deactivate_locked_super(sb); | ||
| 964 | return -EBUSY; | ||
| 965 | } | ||
| 966 | |||
| 967 | if (sb->s_flags & MS_RDONLY) { | ||
| 968 | sb->s_frozen = SB_FREEZE_TRANS; | ||
| 969 | smp_wmb(); | ||
| 970 | up_write(&sb->s_umount); | ||
| 971 | return 0; | ||
| 972 | } | ||
| 973 | |||
| 974 | sb->s_frozen = SB_FREEZE_WRITE; | ||
| 975 | smp_wmb(); | ||
| 976 | |||
| 977 | sync_filesystem(sb); | ||
| 978 | |||
| 979 | sb->s_frozen = SB_FREEZE_TRANS; | ||
| 980 | smp_wmb(); | ||
| 981 | |||
| 982 | sync_blockdev(sb->s_bdev); | ||
| 983 | if (sb->s_op->freeze_fs) { | ||
| 984 | ret = sb->s_op->freeze_fs(sb); | ||
| 985 | if (ret) { | ||
| 986 | printk(KERN_ERR | ||
| 987 | "VFS:Filesystem freeze failed\n"); | ||
| 988 | sb->s_frozen = SB_UNFROZEN; | ||
| 989 | deactivate_locked_super(sb); | ||
| 990 | return ret; | ||
| 991 | } | ||
| 992 | } | ||
| 993 | up_write(&sb->s_umount); | ||
| 994 | return 0; | ||
| 995 | } | ||
| 996 | EXPORT_SYMBOL(freeze_super); | ||
| 997 | |||
| 998 | /** | ||
| 999 | * thaw_super -- unlock filesystem | ||
| 1000 | * @sb: the super to thaw | ||
| 1001 | * | ||
| 1002 | * Unlocks the filesystem and marks it writeable again after freeze_super(). | ||
| 1003 | */ | ||
| 1004 | int thaw_super(struct super_block *sb) | ||
| 1005 | { | ||
| 1006 | int error; | ||
| 1007 | |||
| 1008 | down_write(&sb->s_umount); | ||
| 1009 | if (sb->s_frozen == SB_UNFROZEN) { | ||
| 1010 | up_write(&sb->s_umount); | ||
| 1011 | return -EINVAL; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | if (sb->s_flags & MS_RDONLY) | ||
| 1015 | goto out; | ||
| 1016 | |||
| 1017 | if (sb->s_op->unfreeze_fs) { | ||
| 1018 | error = sb->s_op->unfreeze_fs(sb); | ||
| 1019 | if (error) { | ||
| 1020 | printk(KERN_ERR | ||
| 1021 | "VFS:Filesystem thaw failed\n"); | ||
| 1022 | sb->s_frozen = SB_FREEZE_TRANS; | ||
| 1023 | up_write(&sb->s_umount); | ||
| 1024 | return error; | ||
| 1025 | } | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | out: | ||
| 1029 | sb->s_frozen = SB_UNFROZEN; | ||
| 1030 | smp_wmb(); | ||
| 1031 | wake_up(&sb->s_wait_unfrozen); | ||
| 1032 | deactivate_locked_super(sb); | ||
| 1033 | |||
| 1034 | return 0; | ||
| 1035 | } | ||
| 1036 | EXPORT_SYMBOL(thaw_super); | ||
| 1037 | |||
| 993 | static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) | 1038 | static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) |
| 994 | { | 1039 | { |
| 995 | int err; | 1040 | int err; |
| @@ -77,50 +77,18 @@ int sync_filesystem(struct super_block *sb) | |||
| 77 | } | 77 | } |
| 78 | EXPORT_SYMBOL_GPL(sync_filesystem); | 78 | EXPORT_SYMBOL_GPL(sync_filesystem); |
| 79 | 79 | ||
| 80 | static void sync_one_sb(struct super_block *sb, void *arg) | ||
| 81 | { | ||
| 82 | if (!(sb->s_flags & MS_RDONLY) && sb->s_bdi) | ||
| 83 | __sync_filesystem(sb, *(int *)arg); | ||
| 84 | } | ||
| 80 | /* | 85 | /* |
| 81 | * Sync all the data for all the filesystems (called by sys_sync() and | 86 | * Sync all the data for all the filesystems (called by sys_sync() and |
| 82 | * emergency sync) | 87 | * emergency sync) |
| 83 | * | ||
| 84 | * This operation is careful to avoid the livelock which could easily happen | ||
| 85 | * if two or more filesystems are being continuously dirtied. s_need_sync | ||
| 86 | * is used only here. We set it against all filesystems and then clear it as | ||
| 87 | * we sync them. So redirtied filesystems are skipped. | ||
| 88 | * | ||
| 89 | * But if process A is currently running sync_filesystems and then process B | ||
| 90 | * calls sync_filesystems as well, process B will set all the s_need_sync | ||
| 91 | * flags again, which will cause process A to resync everything. Fix that with | ||
| 92 | * a local mutex. | ||
| 93 | */ | 88 | */ |
| 94 | static void sync_filesystems(int wait) | 89 | static void sync_filesystems(int wait) |
| 95 | { | 90 | { |
| 96 | struct super_block *sb; | 91 | iterate_supers(sync_one_sb, &wait); |
| 97 | static DEFINE_MUTEX(mutex); | ||
| 98 | |||
| 99 | mutex_lock(&mutex); /* Could be down_interruptible */ | ||
| 100 | spin_lock(&sb_lock); | ||
| 101 | list_for_each_entry(sb, &super_blocks, s_list) | ||
| 102 | sb->s_need_sync = 1; | ||
| 103 | |||
| 104 | restart: | ||
| 105 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
| 106 | if (!sb->s_need_sync) | ||
| 107 | continue; | ||
| 108 | sb->s_need_sync = 0; | ||
| 109 | sb->s_count++; | ||
| 110 | spin_unlock(&sb_lock); | ||
| 111 | |||
| 112 | down_read(&sb->s_umount); | ||
| 113 | if (!(sb->s_flags & MS_RDONLY) && sb->s_root && sb->s_bdi) | ||
| 114 | __sync_filesystem(sb, wait); | ||
| 115 | up_read(&sb->s_umount); | ||
| 116 | |||
| 117 | /* restart only when sb is no longer on the list */ | ||
| 118 | spin_lock(&sb_lock); | ||
| 119 | if (__put_super_and_need_restart(sb)) | ||
| 120 | goto restart; | ||
| 121 | } | ||
| 122 | spin_unlock(&sb_lock); | ||
| 123 | mutex_unlock(&mutex); | ||
| 124 | } | 92 | } |
| 125 | 93 | ||
| 126 | /* | 94 | /* |
| @@ -190,7 +158,6 @@ EXPORT_SYMBOL(file_fsync); | |||
| 190 | /** | 158 | /** |
| 191 | * vfs_fsync_range - helper to sync a range of data & metadata to disk | 159 | * vfs_fsync_range - helper to sync a range of data & metadata to disk |
| 192 | * @file: file to sync | 160 | * @file: file to sync |
| 193 | * @dentry: dentry of @file | ||
| 194 | * @start: offset in bytes of the beginning of data range to sync | 161 | * @start: offset in bytes of the beginning of data range to sync |
| 195 | * @end: offset in bytes of the end of data range (inclusive) | 162 | * @end: offset in bytes of the end of data range (inclusive) |
| 196 | * @datasync: perform only datasync | 163 | * @datasync: perform only datasync |
| @@ -198,32 +165,13 @@ EXPORT_SYMBOL(file_fsync); | |||
| 198 | * Write back data in range @start..@end and metadata for @file to disk. If | 165 | * Write back data in range @start..@end and metadata for @file to disk. If |
| 199 | * @datasync is set only metadata needed to access modified file data is | 166 | * @datasync is set only metadata needed to access modified file data is |
| 200 | * written. | 167 | * written. |
| 201 | * | ||
| 202 | * In case this function is called from nfsd @file may be %NULL and | ||
| 203 | * only @dentry is set. This can only happen when the filesystem | ||
| 204 | * implements the export_operations API. | ||
| 205 | */ | 168 | */ |
| 206 | int vfs_fsync_range(struct file *file, struct dentry *dentry, loff_t start, | 169 | int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) |
| 207 | loff_t end, int datasync) | ||
| 208 | { | 170 | { |
| 209 | const struct file_operations *fop; | 171 | struct address_space *mapping = file->f_mapping; |
| 210 | struct address_space *mapping; | ||
| 211 | int err, ret; | 172 | int err, ret; |
| 212 | 173 | ||
| 213 | /* | 174 | if (!file->f_op || !file->f_op->fsync) { |
| 214 | * Get mapping and operations from the file in case we have | ||
| 215 | * as file, or get the default values for them in case we | ||
| 216 | * don't have a struct file available. Damn nfsd.. | ||
| 217 | */ | ||
| 218 | if (file) { | ||
| 219 | mapping = file->f_mapping; | ||
| 220 | fop = file->f_op; | ||
| 221 | } else { | ||
| 222 | mapping = dentry->d_inode->i_mapping; | ||
| 223 | fop = dentry->d_inode->i_fop; | ||
| 224 | } | ||
| 225 | |||
| 226 | if (!fop || !fop->fsync) { | ||
| 227 | ret = -EINVAL; | 175 | ret = -EINVAL; |
| 228 | goto out; | 176 | goto out; |
| 229 | } | 177 | } |
| @@ -235,7 +183,7 @@ int vfs_fsync_range(struct file *file, struct dentry *dentry, loff_t start, | |||
| 235 | * livelocks in fsync_buffers_list(). | 183 | * livelocks in fsync_buffers_list(). |
| 236 | */ | 184 | */ |
| 237 | mutex_lock(&mapping->host->i_mutex); | 185 | mutex_lock(&mapping->host->i_mutex); |
| 238 | err = fop->fsync(file, dentry, datasync); | 186 | err = file->f_op->fsync(file, file->f_path.dentry, datasync); |
| 239 | if (!ret) | 187 | if (!ret) |
| 240 | ret = err; | 188 | ret = err; |
| 241 | mutex_unlock(&mapping->host->i_mutex); | 189 | mutex_unlock(&mapping->host->i_mutex); |
| @@ -248,19 +196,14 @@ EXPORT_SYMBOL(vfs_fsync_range); | |||
| 248 | /** | 196 | /** |
| 249 | * vfs_fsync - perform a fsync or fdatasync on a file | 197 | * vfs_fsync - perform a fsync or fdatasync on a file |
| 250 | * @file: file to sync | 198 | * @file: file to sync |
| 251 | * @dentry: dentry of @file | ||
| 252 | * @datasync: only perform a fdatasync operation | 199 | * @datasync: only perform a fdatasync operation |
| 253 | * | 200 | * |
| 254 | * Write back data and metadata for @file to disk. If @datasync is | 201 | * Write back data and metadata for @file to disk. If @datasync is |
| 255 | * set only metadata needed to access modified file data is written. | 202 | * set only metadata needed to access modified file data is written. |
| 256 | * | ||
| 257 | * In case this function is called from nfsd @file may be %NULL and | ||
| 258 | * only @dentry is set. This can only happen when the filesystem | ||
| 259 | * implements the export_operations API. | ||
| 260 | */ | 203 | */ |
| 261 | int vfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 204 | int vfs_fsync(struct file *file, int datasync) |
| 262 | { | 205 | { |
| 263 | return vfs_fsync_range(file, dentry, 0, LLONG_MAX, datasync); | 206 | return vfs_fsync_range(file, 0, LLONG_MAX, datasync); |
| 264 | } | 207 | } |
| 265 | EXPORT_SYMBOL(vfs_fsync); | 208 | EXPORT_SYMBOL(vfs_fsync); |
| 266 | 209 | ||
| @@ -271,7 +214,7 @@ static int do_fsync(unsigned int fd, int datasync) | |||
| 271 | 214 | ||
| 272 | file = fget(fd); | 215 | file = fget(fd); |
| 273 | if (file) { | 216 | if (file) { |
| 274 | ret = vfs_fsync(file, file->f_path.dentry, datasync); | 217 | ret = vfs_fsync(file, datasync); |
| 275 | fput(file); | 218 | fput(file); |
| 276 | } | 219 | } |
| 277 | return ret; | 220 | return ret; |
| @@ -299,8 +242,7 @@ int generic_write_sync(struct file *file, loff_t pos, loff_t count) | |||
| 299 | { | 242 | { |
| 300 | if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host)) | 243 | if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host)) |
| 301 | return 0; | 244 | return 0; |
| 302 | return vfs_fsync_range(file, file->f_path.dentry, pos, | 245 | return vfs_fsync_range(file, pos, pos + count - 1, |
| 303 | pos + count - 1, | ||
| 304 | (file->f_flags & __O_SYNC) ? 0 : 1); | 246 | (file->f_flags & __O_SYNC) ? 0 : 1); |
| 305 | } | 247 | } |
| 306 | EXPORT_SYMBOL(generic_write_sync); | 248 | EXPORT_SYMBOL(generic_write_sync); |
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index 241e9765cfa..bbd69bdb0fa 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c | |||
| @@ -159,15 +159,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) | |||
| 159 | *sbi->s_sb_fic_count = cpu_to_fs16(sbi, count); | 159 | *sbi->s_sb_fic_count = cpu_to_fs16(sbi, count); |
| 160 | fs16_add(sbi, sbi->s_sb_total_free_inodes, -1); | 160 | fs16_add(sbi, sbi->s_sb_total_free_inodes, -1); |
| 161 | dirty_sb(sb); | 161 | dirty_sb(sb); |
| 162 | 162 | inode_init_owner(inode, dir, mode); | |
| 163 | if (dir->i_mode & S_ISGID) { | ||
| 164 | inode->i_gid = dir->i_gid; | ||
| 165 | if (S_ISDIR(mode)) | ||
| 166 | mode |= S_ISGID; | ||
| 167 | } else | ||
| 168 | inode->i_gid = current_fsgid(); | ||
| 169 | |||
| 170 | inode->i_uid = current_fsuid(); | ||
| 171 | inode->i_ino = fs16_to_cpu(sbi, ino); | 163 | inode->i_ino = fs16_to_cpu(sbi, ino); |
| 172 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 164 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
| 173 | inode->i_blocks = 0; | 165 | inode->i_blocks = 0; |
| @@ -176,7 +168,6 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) | |||
| 176 | insert_inode_hash(inode); | 168 | insert_inode_hash(inode); |
| 177 | mark_inode_dirty(inode); | 169 | mark_inode_dirty(inode); |
| 178 | 170 | ||
| 179 | inode->i_mode = mode; /* for sysv_write_inode() */ | ||
| 180 | sysv_write_inode(inode, 0); /* ensure inode not allocated again */ | 171 | sysv_write_inode(inode, 0); /* ensure inode not allocated again */ |
| 181 | mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ | 172 | mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ |
| 182 | /* That's it. */ | 173 | /* That's it. */ |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 401e503d44a..87ebcce7221 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
| @@ -104,14 +104,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, | |||
| 104 | */ | 104 | */ |
| 105 | inode->i_flags |= (S_NOCMTIME); | 105 | inode->i_flags |= (S_NOCMTIME); |
| 106 | 106 | ||
| 107 | inode->i_uid = current_fsuid(); | 107 | inode_init_owner(inode, dir, mode); |
| 108 | if (dir->i_mode & S_ISGID) { | ||
| 109 | inode->i_gid = dir->i_gid; | ||
| 110 | if (S_ISDIR(mode)) | ||
| 111 | mode |= S_ISGID; | ||
| 112 | } else | ||
| 113 | inode->i_gid = current_fsgid(); | ||
| 114 | inode->i_mode = mode; | ||
| 115 | inode->i_mtime = inode->i_atime = inode->i_ctime = | 108 | inode->i_mtime = inode->i_atime = inode->i_ctime = |
| 116 | ubifs_current_time(inode); | 109 | ubifs_current_time(inode); |
| 117 | inode->i_mapping->nrpages = 0; | 110 | inode->i_mapping->nrpages = 0; |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index fb68c9cd0c3..2b5586c7f02 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
| @@ -124,15 +124,8 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
| 124 | udf_updated_lvid(sb); | 124 | udf_updated_lvid(sb); |
| 125 | } | 125 | } |
| 126 | mutex_unlock(&sbi->s_alloc_mutex); | 126 | mutex_unlock(&sbi->s_alloc_mutex); |
| 127 | inode->i_mode = mode; | 127 | |
| 128 | inode->i_uid = current_fsuid(); | 128 | inode_init_owner(inode, dir, mode); |
| 129 | if (dir->i_mode & S_ISGID) { | ||
| 130 | inode->i_gid = dir->i_gid; | ||
| 131 | if (S_ISDIR(mode)) | ||
| 132 | mode |= S_ISGID; | ||
| 133 | } else { | ||
| 134 | inode->i_gid = current_fsgid(); | ||
| 135 | } | ||
| 136 | 129 | ||
| 137 | iinfo->i_location.logicalBlockNum = block; | 130 | iinfo->i_location.logicalBlockNum = block; |
| 138 | iinfo->i_location.partitionReferenceNum = | 131 | iinfo->i_location.partitionReferenceNum = |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 75816025f95..585f733615d 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
| @@ -579,7 +579,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
| 579 | inode->i_data.a_ops = &udf_aops; | 579 | inode->i_data.a_ops = &udf_aops; |
| 580 | inode->i_op = &udf_file_inode_operations; | 580 | inode->i_op = &udf_file_inode_operations; |
| 581 | inode->i_fop = &udf_file_operations; | 581 | inode->i_fop = &udf_file_operations; |
| 582 | inode->i_mode = mode; | ||
| 583 | mark_inode_dirty(inode); | 582 | mark_inode_dirty(inode); |
| 584 | 583 | ||
| 585 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 584 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
| @@ -627,7 +626,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
| 627 | goto out; | 626 | goto out; |
| 628 | 627 | ||
| 629 | iinfo = UDF_I(inode); | 628 | iinfo = UDF_I(inode); |
| 630 | inode->i_uid = current_fsuid(); | ||
| 631 | init_special_inode(inode, mode, rdev); | 629 | init_special_inode(inode, mode, rdev); |
| 632 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 630 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
| 633 | if (!fi) { | 631 | if (!fi) { |
| @@ -674,7 +672,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 674 | goto out; | 672 | goto out; |
| 675 | 673 | ||
| 676 | err = -EIO; | 674 | err = -EIO; |
| 677 | inode = udf_new_inode(dir, S_IFDIR, &err); | 675 | inode = udf_new_inode(dir, S_IFDIR | mode, &err); |
| 678 | if (!inode) | 676 | if (!inode) |
| 679 | goto out; | 677 | goto out; |
| 680 | 678 | ||
| @@ -697,9 +695,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 697 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; | 695 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; |
| 698 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); | 696 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); |
| 699 | brelse(fibh.sbh); | 697 | brelse(fibh.sbh); |
| 700 | inode->i_mode = S_IFDIR | mode; | ||
| 701 | if (dir->i_mode & S_ISGID) | ||
| 702 | inode->i_mode |= S_ISGID; | ||
| 703 | mark_inode_dirty(inode); | 698 | mark_inode_dirty(inode); |
| 704 | 699 | ||
| 705 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 700 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
| @@ -912,7 +907,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 912 | dquot_initialize(dir); | 907 | dquot_initialize(dir); |
| 913 | 908 | ||
| 914 | lock_kernel(); | 909 | lock_kernel(); |
| 915 | inode = udf_new_inode(dir, S_IFLNK, &err); | 910 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
| 916 | if (!inode) | 911 | if (!inode) |
| 917 | goto out; | 912 | goto out; |
| 918 | 913 | ||
| @@ -923,7 +918,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 923 | } | 918 | } |
| 924 | 919 | ||
| 925 | iinfo = UDF_I(inode); | 920 | iinfo = UDF_I(inode); |
| 926 | inode->i_mode = S_IFLNK | S_IRWXUGO; | ||
| 927 | inode->i_data.a_ops = &udf_symlink_aops; | 921 | inode->i_data.a_ops = &udf_symlink_aops; |
| 928 | inode->i_op = &udf_symlink_inode_operations; | 922 | inode->i_op = &udf_symlink_inode_operations; |
| 929 | 923 | ||
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 230ecf60802..3a959d55084 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
| @@ -303,15 +303,7 @@ cg_found: | |||
| 303 | sb->s_dirt = 1; | 303 | sb->s_dirt = 1; |
| 304 | 304 | ||
| 305 | inode->i_ino = cg * uspi->s_ipg + bit; | 305 | inode->i_ino = cg * uspi->s_ipg + bit; |
| 306 | inode->i_mode = mode; | 306 | inode_init_owner(inode, dir, mode); |
| 307 | inode->i_uid = current_fsuid(); | ||
| 308 | if (dir->i_mode & S_ISGID) { | ||
| 309 | inode->i_gid = dir->i_gid; | ||
| 310 | if (S_ISDIR(mode)) | ||
| 311 | inode->i_mode |= S_ISGID; | ||
| 312 | } else | ||
| 313 | inode->i_gid = current_fsgid(); | ||
| 314 | |||
| 315 | inode->i_blocks = 0; | 307 | inode->i_blocks = 0; |
| 316 | inode->i_generation = 0; | 308 | inode->i_generation = 0; |
| 317 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 309 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
diff --git a/fs/xattr.c b/fs/xattr.c index 46f87e828b4..01bb8135e14 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
| @@ -590,10 +590,10 @@ strcmp_prefix(const char *a, const char *a_prefix) | |||
| 590 | /* | 590 | /* |
| 591 | * Find the xattr_handler with the matching prefix. | 591 | * Find the xattr_handler with the matching prefix. |
| 592 | */ | 592 | */ |
| 593 | static struct xattr_handler * | 593 | static const struct xattr_handler * |
| 594 | xattr_resolve_name(struct xattr_handler **handlers, const char **name) | 594 | xattr_resolve_name(const struct xattr_handler **handlers, const char **name) |
| 595 | { | 595 | { |
| 596 | struct xattr_handler *handler; | 596 | const struct xattr_handler *handler; |
| 597 | 597 | ||
| 598 | if (!*name) | 598 | if (!*name) |
| 599 | return NULL; | 599 | return NULL; |
| @@ -614,7 +614,7 @@ xattr_resolve_name(struct xattr_handler **handlers, const char **name) | |||
| 614 | ssize_t | 614 | ssize_t |
| 615 | generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) | 615 | generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) |
| 616 | { | 616 | { |
| 617 | struct xattr_handler *handler; | 617 | const struct xattr_handler *handler; |
| 618 | 618 | ||
| 619 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 619 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
| 620 | if (!handler) | 620 | if (!handler) |
| @@ -629,7 +629,7 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s | |||
| 629 | ssize_t | 629 | ssize_t |
| 630 | generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | 630 | generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) |
| 631 | { | 631 | { |
| 632 | struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr; | 632 | const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr; |
| 633 | unsigned int size = 0; | 633 | unsigned int size = 0; |
| 634 | 634 | ||
| 635 | if (!buffer) { | 635 | if (!buffer) { |
| @@ -659,7 +659,7 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
| 659 | int | 659 | int |
| 660 | generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) | 660 | generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) |
| 661 | { | 661 | { |
| 662 | struct xattr_handler *handler; | 662 | const struct xattr_handler *handler; |
| 663 | 663 | ||
| 664 | if (size == 0) | 664 | if (size == 0) |
| 665 | value = ""; /* empty EA, do not remove */ | 665 | value = ""; /* empty EA, do not remove */ |
| @@ -676,7 +676,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz | |||
| 676 | int | 676 | int |
| 677 | generic_removexattr(struct dentry *dentry, const char *name) | 677 | generic_removexattr(struct dentry *dentry, const char *name) |
| 678 | { | 678 | { |
| 679 | struct xattr_handler *handler; | 679 | const struct xattr_handler *handler; |
| 680 | 680 | ||
| 681 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 681 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
| 682 | if (!handler) | 682 | if (!handler) |
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index a7bc925c4d6..9f769b5b38f 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c | |||
| @@ -440,14 +440,14 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name, | |||
| 440 | return error; | 440 | return error; |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | struct xattr_handler xfs_xattr_acl_access_handler = { | 443 | const struct xattr_handler xfs_xattr_acl_access_handler = { |
| 444 | .prefix = POSIX_ACL_XATTR_ACCESS, | 444 | .prefix = POSIX_ACL_XATTR_ACCESS, |
| 445 | .flags = ACL_TYPE_ACCESS, | 445 | .flags = ACL_TYPE_ACCESS, |
| 446 | .get = xfs_xattr_acl_get, | 446 | .get = xfs_xattr_acl_get, |
| 447 | .set = xfs_xattr_acl_set, | 447 | .set = xfs_xattr_acl_set, |
| 448 | }; | 448 | }; |
| 449 | 449 | ||
| 450 | struct xattr_handler xfs_xattr_acl_default_handler = { | 450 | const struct xattr_handler xfs_xattr_acl_default_handler = { |
| 451 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 451 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
| 452 | .flags = ACL_TYPE_DEFAULT, | 452 | .flags = ACL_TYPE_DEFAULT, |
| 453 | .get = xfs_xattr_acl_get, | 453 | .get = xfs_xattr_acl_get, |
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index 233d4b9881b..519618e9279 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h | |||
| @@ -85,7 +85,7 @@ extern __uint64_t xfs_max_file_offset(unsigned int); | |||
| 85 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); | 85 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); |
| 86 | 86 | ||
| 87 | extern const struct export_operations xfs_export_operations; | 87 | extern const struct export_operations xfs_export_operations; |
| 88 | extern struct xattr_handler *xfs_xattr_handlers[]; | 88 | extern const struct xattr_handler *xfs_xattr_handlers[]; |
| 89 | extern const struct quotactl_ops xfs_quotactl_operations; | 89 | extern const struct quotactl_ops xfs_quotactl_operations; |
| 90 | 90 | ||
| 91 | #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) | 91 | #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) |
diff --git a/fs/xfs/linux-2.6/xfs_xattr.c b/fs/xfs/linux-2.6/xfs_xattr.c index fa01b9daba6..87d3e03878c 100644 --- a/fs/xfs/linux-2.6/xfs_xattr.c +++ b/fs/xfs/linux-2.6/xfs_xattr.c | |||
| @@ -72,28 +72,28 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, | |||
| 72 | (void *)value, size, xflags); | 72 | (void *)value, size, xflags); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static struct xattr_handler xfs_xattr_user_handler = { | 75 | static const struct xattr_handler xfs_xattr_user_handler = { |
| 76 | .prefix = XATTR_USER_PREFIX, | 76 | .prefix = XATTR_USER_PREFIX, |
| 77 | .flags = 0, /* no flags implies user namespace */ | 77 | .flags = 0, /* no flags implies user namespace */ |
| 78 | .get = xfs_xattr_get, | 78 | .get = xfs_xattr_get, |
| 79 | .set = xfs_xattr_set, | 79 | .set = xfs_xattr_set, |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | static struct xattr_handler xfs_xattr_trusted_handler = { | 82 | static const struct xattr_handler xfs_xattr_trusted_handler = { |
| 83 | .prefix = XATTR_TRUSTED_PREFIX, | 83 | .prefix = XATTR_TRUSTED_PREFIX, |
| 84 | .flags = ATTR_ROOT, | 84 | .flags = ATTR_ROOT, |
| 85 | .get = xfs_xattr_get, | 85 | .get = xfs_xattr_get, |
| 86 | .set = xfs_xattr_set, | 86 | .set = xfs_xattr_set, |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | static struct xattr_handler xfs_xattr_security_handler = { | 89 | static const struct xattr_handler xfs_xattr_security_handler = { |
| 90 | .prefix = XATTR_SECURITY_PREFIX, | 90 | .prefix = XATTR_SECURITY_PREFIX, |
| 91 | .flags = ATTR_SECURE, | 91 | .flags = ATTR_SECURE, |
| 92 | .get = xfs_xattr_get, | 92 | .get = xfs_xattr_get, |
| 93 | .set = xfs_xattr_set, | 93 | .set = xfs_xattr_set, |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | struct xattr_handler *xfs_xattr_handlers[] = { | 96 | const struct xattr_handler *xfs_xattr_handlers[] = { |
| 97 | &xfs_xattr_user_handler, | 97 | &xfs_xattr_user_handler, |
| 98 | &xfs_xattr_trusted_handler, | 98 | &xfs_xattr_trusted_handler, |
| 99 | &xfs_xattr_security_handler, | 99 | &xfs_xattr_security_handler, |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index d13eeba2c8f..0135e2a669d 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
| @@ -49,8 +49,8 @@ extern int xfs_acl_chmod(struct inode *inode); | |||
| 49 | extern int posix_acl_access_exists(struct inode *inode); | 49 | extern int posix_acl_access_exists(struct inode *inode); |
| 50 | extern int posix_acl_default_exists(struct inode *inode); | 50 | extern int posix_acl_default_exists(struct inode *inode); |
| 51 | 51 | ||
| 52 | extern struct xattr_handler xfs_xattr_acl_access_handler; | 52 | extern const struct xattr_handler xfs_xattr_acl_access_handler; |
| 53 | extern struct xattr_handler xfs_xattr_acl_default_handler; | 53 | extern const struct xattr_handler xfs_xattr_acl_default_handler; |
| 54 | #else | 54 | #else |
| 55 | # define xfs_check_acl NULL | 55 | # define xfs_check_acl NULL |
| 56 | # define xfs_get_acl(inode, type) NULL | 56 | # define xfs_get_acl(inode, type) NULL |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 1775d362732..b336cb9ca9a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1315,8 +1315,6 @@ extern int send_sigurg(struct fown_struct *fown); | |||
| 1315 | extern struct list_head super_blocks; | 1315 | extern struct list_head super_blocks; |
| 1316 | extern spinlock_t sb_lock; | 1316 | extern spinlock_t sb_lock; |
| 1317 | 1317 | ||
| 1318 | #define sb_entry(list) list_entry((list), struct super_block, s_list) | ||
| 1319 | #define S_BIAS (1<<30) | ||
| 1320 | struct super_block { | 1318 | struct super_block { |
| 1321 | struct list_head s_list; /* Keep this first */ | 1319 | struct list_head s_list; /* Keep this first */ |
| 1322 | dev_t s_dev; /* search index; _not_ kdev_t */ | 1320 | dev_t s_dev; /* search index; _not_ kdev_t */ |
| @@ -1335,12 +1333,11 @@ struct super_block { | |||
| 1335 | struct rw_semaphore s_umount; | 1333 | struct rw_semaphore s_umount; |
| 1336 | struct mutex s_lock; | 1334 | struct mutex s_lock; |
| 1337 | int s_count; | 1335 | int s_count; |
| 1338 | int s_need_sync; | ||
| 1339 | atomic_t s_active; | 1336 | atomic_t s_active; |
| 1340 | #ifdef CONFIG_SECURITY | 1337 | #ifdef CONFIG_SECURITY |
| 1341 | void *s_security; | 1338 | void *s_security; |
| 1342 | #endif | 1339 | #endif |
| 1343 | struct xattr_handler **s_xattr; | 1340 | const struct xattr_handler **s_xattr; |
| 1344 | 1341 | ||
| 1345 | struct list_head s_inodes; /* all inodes */ | 1342 | struct list_head s_inodes; /* all inodes */ |
| 1346 | struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ | 1343 | struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ |
| @@ -1432,7 +1429,8 @@ extern void dentry_unhash(struct dentry *dentry); | |||
| 1432 | * VFS file helper functions. | 1429 | * VFS file helper functions. |
| 1433 | */ | 1430 | */ |
| 1434 | extern int file_permission(struct file *, int); | 1431 | extern int file_permission(struct file *, int); |
| 1435 | 1432 | extern void inode_init_owner(struct inode *inode, const struct inode *dir, | |
| 1433 | mode_t mode); | ||
| 1436 | /* | 1434 | /* |
| 1437 | * VFS FS_IOC_FIEMAP helper definitions. | 1435 | * VFS FS_IOC_FIEMAP helper definitions. |
| 1438 | */ | 1436 | */ |
| @@ -1745,6 +1743,7 @@ struct file_system_type { | |||
| 1745 | 1743 | ||
| 1746 | struct lock_class_key s_lock_key; | 1744 | struct lock_class_key s_lock_key; |
| 1747 | struct lock_class_key s_umount_key; | 1745 | struct lock_class_key s_umount_key; |
| 1746 | struct lock_class_key s_vfs_rename_key; | ||
| 1748 | 1747 | ||
| 1749 | struct lock_class_key i_lock_key; | 1748 | struct lock_class_key i_lock_key; |
| 1750 | struct lock_class_key i_mutex_key; | 1749 | struct lock_class_key i_mutex_key; |
| @@ -1782,8 +1781,6 @@ extern int get_sb_pseudo(struct file_system_type *, char *, | |||
| 1782 | const struct super_operations *ops, unsigned long, | 1781 | const struct super_operations *ops, unsigned long, |
| 1783 | struct vfsmount *mnt); | 1782 | struct vfsmount *mnt); |
| 1784 | extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); | 1783 | extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); |
| 1785 | int __put_super_and_need_restart(struct super_block *sb); | ||
| 1786 | void put_super(struct super_block *sb); | ||
| 1787 | 1784 | ||
| 1788 | /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ | 1785 | /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ |
| 1789 | #define fops_get(fops) \ | 1786 | #define fops_get(fops) \ |
| @@ -1803,6 +1800,8 @@ extern void drop_collected_mounts(struct vfsmount *); | |||
| 1803 | extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, | 1800 | extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, |
| 1804 | struct vfsmount *); | 1801 | struct vfsmount *); |
| 1805 | extern int vfs_statfs(struct dentry *, struct kstatfs *); | 1802 | extern int vfs_statfs(struct dentry *, struct kstatfs *); |
| 1803 | extern int freeze_super(struct super_block *super); | ||
| 1804 | extern int thaw_super(struct super_block *super); | ||
| 1806 | 1805 | ||
| 1807 | extern int current_umask(void); | 1806 | extern int current_umask(void); |
| 1808 | 1807 | ||
| @@ -2088,9 +2087,9 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping, | |||
| 2088 | extern int filemap_fdatawrite_range(struct address_space *mapping, | 2087 | extern int filemap_fdatawrite_range(struct address_space *mapping, |
| 2089 | loff_t start, loff_t end); | 2088 | loff_t start, loff_t end); |
| 2090 | 2089 | ||
| 2091 | extern int vfs_fsync_range(struct file *file, struct dentry *dentry, | 2090 | extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end, |
| 2092 | loff_t start, loff_t end, int datasync); | 2091 | int datasync); |
| 2093 | extern int vfs_fsync(struct file *file, struct dentry *dentry, int datasync); | 2092 | extern int vfs_fsync(struct file *file, int datasync); |
| 2094 | extern int generic_write_sync(struct file *file, loff_t pos, loff_t count); | 2093 | extern int generic_write_sync(struct file *file, loff_t pos, loff_t count); |
| 2095 | extern void sync_supers(void); | 2094 | extern void sync_supers(void); |
| 2096 | extern void emergency_sync(void); | 2095 | extern void emergency_sync(void); |
| @@ -2330,6 +2329,7 @@ extern struct super_block *get_super(struct block_device *); | |||
| 2330 | extern struct super_block *get_active_super(struct block_device *bdev); | 2329 | extern struct super_block *get_active_super(struct block_device *bdev); |
| 2331 | extern struct super_block *user_get_super(dev_t); | 2330 | extern struct super_block *user_get_super(dev_t); |
| 2332 | extern void drop_super(struct super_block *sb); | 2331 | extern void drop_super(struct super_block *sb); |
| 2332 | extern void iterate_supers(void (*)(struct super_block *, void *), void *); | ||
| 2333 | 2333 | ||
| 2334 | extern int dcache_dir_open(struct inode *, struct file *); | 2334 | extern int dcache_dir_open(struct inode *, struct file *); |
| 2335 | extern int dcache_dir_close(struct inode *, struct file *); | 2335 | extern int dcache_dir_close(struct inode *, struct file *); |
diff --git a/include/linux/generic_acl.h b/include/linux/generic_acl.h index ca666d18ed6..574bea4013b 100644 --- a/include/linux/generic_acl.h +++ b/include/linux/generic_acl.h | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | 5 | ||
| 6 | struct inode; | 6 | struct inode; |
| 7 | 7 | ||
| 8 | extern struct xattr_handler generic_acl_access_handler; | 8 | extern const struct xattr_handler generic_acl_access_handler; |
| 9 | extern struct xattr_handler generic_acl_default_handler; | 9 | extern const struct xattr_handler generic_acl_default_handler; |
| 10 | 10 | ||
| 11 | int generic_acl_init(struct inode *, struct inode *); | 11 | int generic_acl_init(struct inode *, struct inode *); |
| 12 | int generic_acl_chmod(struct inode *); | 12 | int generic_acl_chmod(struct inode *); |
diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index 8600508c77a..e7320b5e82f 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | #ifndef _LINUX_RAMFS_H | 1 | #ifndef _LINUX_RAMFS_H |
| 2 | #define _LINUX_RAMFS_H | 2 | #define _LINUX_RAMFS_H |
| 3 | 3 | ||
| 4 | struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev); | 4 | struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, |
| 5 | int mode, dev_t dev); | ||
| 5 | extern int ramfs_get_sb(struct file_system_type *fs_type, | 6 | extern int ramfs_get_sb(struct file_system_type *fs_type, |
| 6 | int flags, const char *dev_name, void *data, struct vfsmount *mnt); | 7 | int flags, const char *dev_name, void *data, struct vfsmount *mnt); |
| 7 | 8 | ||
diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index b4448853900..3fd8c4506bb 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h | |||
| @@ -53,8 +53,8 @@ int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, | |||
| 53 | struct inode *dir, struct dentry *dentry, | 53 | struct inode *dir, struct dentry *dentry, |
| 54 | struct inode *inode); | 54 | struct inode *inode); |
| 55 | int reiserfs_cache_default_acl(struct inode *dir); | 55 | int reiserfs_cache_default_acl(struct inode *dir); |
| 56 | extern struct xattr_handler reiserfs_posix_acl_default_handler; | 56 | extern const struct xattr_handler reiserfs_posix_acl_default_handler; |
| 57 | extern struct xattr_handler reiserfs_posix_acl_access_handler; | 57 | extern const struct xattr_handler reiserfs_posix_acl_access_handler; |
| 58 | 58 | ||
| 59 | #else | 59 | #else |
| 60 | 60 | ||
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 7fa02b4af83..b2cf2089769 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h | |||
| @@ -58,9 +58,9 @@ int reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *, | |||
| 58 | struct inode *, const char *, const void *, | 58 | struct inode *, const char *, const void *, |
| 59 | size_t, int); | 59 | size_t, int); |
| 60 | 60 | ||
| 61 | extern struct xattr_handler reiserfs_xattr_user_handler; | 61 | extern const struct xattr_handler reiserfs_xattr_user_handler; |
| 62 | extern struct xattr_handler reiserfs_xattr_trusted_handler; | 62 | extern const struct xattr_handler reiserfs_xattr_trusted_handler; |
| 63 | extern struct xattr_handler reiserfs_xattr_security_handler; | 63 | extern const struct xattr_handler reiserfs_xattr_security_handler; |
| 64 | #ifdef CONFIG_REISERFS_FS_SECURITY | 64 | #ifdef CONFIG_REISERFS_FS_SECURITY |
| 65 | int reiserfs_security_init(struct inode *dir, struct inode *inode, | 65 | int reiserfs_security_init(struct inode *dir, struct inode *inode, |
| 66 | struct reiserfs_security_handle *sec); | 66 | struct reiserfs_security_handle *sec); |
diff --git a/include/linux/xattr.h b/include/linux/xattr.h index fb9b7e6e1e2..0cfa1e9c4cc 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h | |||
| @@ -37,7 +37,7 @@ struct inode; | |||
| 37 | struct dentry; | 37 | struct dentry; |
| 38 | 38 | ||
| 39 | struct xattr_handler { | 39 | struct xattr_handler { |
| 40 | char *prefix; | 40 | const char *prefix; |
| 41 | int flags; /* fs private flags passed back to the handlers */ | 41 | int flags; /* fs private flags passed back to the handlers */ |
| 42 | size_t (*list)(struct dentry *dentry, char *list, size_t list_size, | 42 | size_t (*list)(struct dentry *dentry, char *list, size_t list_size, |
| 43 | const char *name, size_t name_len, int handler_flags); | 43 | const char *name, size_t name_len, int handler_flags); |
diff --git a/mm/msync.c b/mm/msync.c index 4083209b7f0..632df4527c0 100644 --- a/mm/msync.c +++ b/mm/msync.c | |||
| @@ -82,7 +82,7 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) | |||
| 82 | (vma->vm_flags & VM_SHARED)) { | 82 | (vma->vm_flags & VM_SHARED)) { |
| 83 | get_file(file); | 83 | get_file(file); |
| 84 | up_read(&mm->mmap_sem); | 84 | up_read(&mm->mmap_sem); |
| 85 | error = vfs_fsync(file, file->f_path.dentry, 0); | 85 | error = vfs_fsync(file, 0); |
| 86 | fput(file); | 86 | fput(file); |
| 87 | if (error || start >= end) | 87 | if (error || start >= end) |
| 88 | goto out; | 88 | goto out; |
diff --git a/mm/shmem.c b/mm/shmem.c index eef4ebea515..0cd7f66f1c6 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -1545,8 +1545,8 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1545 | return 0; | 1545 | return 0; |
| 1546 | } | 1546 | } |
| 1547 | 1547 | ||
| 1548 | static struct inode *shmem_get_inode(struct super_block *sb, int mode, | 1548 | static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir, |
| 1549 | dev_t dev, unsigned long flags) | 1549 | int mode, dev_t dev, unsigned long flags) |
| 1550 | { | 1550 | { |
| 1551 | struct inode *inode; | 1551 | struct inode *inode; |
| 1552 | struct shmem_inode_info *info; | 1552 | struct shmem_inode_info *info; |
| @@ -1557,9 +1557,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, int mode, | |||
| 1557 | 1557 | ||
| 1558 | inode = new_inode(sb); | 1558 | inode = new_inode(sb); |
| 1559 | if (inode) { | 1559 | if (inode) { |
| 1560 | inode->i_mode = mode; | 1560 | inode_init_owner(inode, dir, mode); |
| 1561 | inode->i_uid = current_fsuid(); | ||
| 1562 | inode->i_gid = current_fsgid(); | ||
| 1563 | inode->i_blocks = 0; | 1561 | inode->i_blocks = 0; |
| 1564 | inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; | 1562 | inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; |
| 1565 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 1563 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| @@ -1814,7 +1812,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
| 1814 | struct inode *inode; | 1812 | struct inode *inode; |
| 1815 | int error = -ENOSPC; | 1813 | int error = -ENOSPC; |
| 1816 | 1814 | ||
| 1817 | inode = shmem_get_inode(dir->i_sb, mode, dev, VM_NORESERVE); | 1815 | inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); |
| 1818 | if (inode) { | 1816 | if (inode) { |
| 1819 | error = security_inode_init_security(inode, dir, NULL, NULL, | 1817 | error = security_inode_init_security(inode, dir, NULL, NULL, |
| 1820 | NULL); | 1818 | NULL); |
| @@ -1833,11 +1831,6 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
| 1833 | #else | 1831 | #else |
| 1834 | error = 0; | 1832 | error = 0; |
| 1835 | #endif | 1833 | #endif |
| 1836 | if (dir->i_mode & S_ISGID) { | ||
| 1837 | inode->i_gid = dir->i_gid; | ||
| 1838 | if (S_ISDIR(mode)) | ||
| 1839 | inode->i_mode |= S_ISGID; | ||
| 1840 | } | ||
| 1841 | dir->i_size += BOGO_DIRENT_SIZE; | 1834 | dir->i_size += BOGO_DIRENT_SIZE; |
| 1842 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 1835 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
| 1843 | d_instantiate(dentry, inode); | 1836 | d_instantiate(dentry, inode); |
| @@ -1957,7 +1950,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
| 1957 | if (len > PAGE_CACHE_SIZE) | 1950 | if (len > PAGE_CACHE_SIZE) |
| 1958 | return -ENAMETOOLONG; | 1951 | return -ENAMETOOLONG; |
| 1959 | 1952 | ||
| 1960 | inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); | 1953 | inode = shmem_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); |
| 1961 | if (!inode) | 1954 | if (!inode) |
| 1962 | return -ENOSPC; | 1955 | return -ENOSPC; |
| 1963 | 1956 | ||
| @@ -1992,8 +1985,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
| 1992 | unlock_page(page); | 1985 | unlock_page(page); |
| 1993 | page_cache_release(page); | 1986 | page_cache_release(page); |
| 1994 | } | 1987 | } |
| 1995 | if (dir->i_mode & S_ISGID) | ||
| 1996 | inode->i_gid = dir->i_gid; | ||
| 1997 | dir->i_size += BOGO_DIRENT_SIZE; | 1988 | dir->i_size += BOGO_DIRENT_SIZE; |
| 1998 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 1989 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
| 1999 | d_instantiate(dentry, inode); | 1990 | d_instantiate(dentry, inode); |
| @@ -2071,14 +2062,14 @@ static int shmem_xattr_security_set(struct dentry *dentry, const char *name, | |||
| 2071 | size, flags); | 2062 | size, flags); |
| 2072 | } | 2063 | } |
| 2073 | 2064 | ||
| 2074 | static struct xattr_handler shmem_xattr_security_handler = { | 2065 | static const struct xattr_handler shmem_xattr_security_handler = { |
| 2075 | .prefix = XATTR_SECURITY_PREFIX, | 2066 | .prefix = XATTR_SECURITY_PREFIX, |
| 2076 | .list = shmem_xattr_security_list, | 2067 | .list = shmem_xattr_security_list, |
| 2077 | .get = shmem_xattr_security_get, | 2068 | .get = shmem_xattr_security_get, |
| 2078 | .set = shmem_xattr_security_set, | 2069 | .set = shmem_xattr_security_set, |
| 2079 | }; | 2070 | }; |
| 2080 | 2071 | ||
| 2081 | static struct xattr_handler *shmem_xattr_handlers[] = { | 2072 | static const struct xattr_handler *shmem_xattr_handlers[] = { |
| 2082 | &generic_acl_access_handler, | 2073 | &generic_acl_access_handler, |
| 2083 | &generic_acl_default_handler, | 2074 | &generic_acl_default_handler, |
| 2084 | &shmem_xattr_security_handler, | 2075 | &shmem_xattr_security_handler, |
| @@ -2366,7 +2357,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2366 | sb->s_flags |= MS_POSIXACL; | 2357 | sb->s_flags |= MS_POSIXACL; |
| 2367 | #endif | 2358 | #endif |
| 2368 | 2359 | ||
| 2369 | inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); | 2360 | inode = shmem_get_inode(sb, NULL, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); |
| 2370 | if (!inode) | 2361 | if (!inode) |
| 2371 | goto failed; | 2362 | goto failed; |
| 2372 | inode->i_uid = sbinfo->uid; | 2363 | inode->i_uid = sbinfo->uid; |
| @@ -2611,7 +2602,7 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user) | |||
| 2611 | 2602 | ||
| 2612 | #define shmem_vm_ops generic_file_vm_ops | 2603 | #define shmem_vm_ops generic_file_vm_ops |
| 2613 | #define shmem_file_operations ramfs_file_operations | 2604 | #define shmem_file_operations ramfs_file_operations |
| 2614 | #define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) | 2605 | #define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev) |
| 2615 | #define shmem_acct_size(flags, size) 0 | 2606 | #define shmem_acct_size(flags, size) 0 |
| 2616 | #define shmem_unacct_size(flags, size) do {} while (0) | 2607 | #define shmem_unacct_size(flags, size) do {} while (0) |
| 2617 | #define SHMEM_MAX_BYTES MAX_LFS_FILESIZE | 2608 | #define SHMEM_MAX_BYTES MAX_LFS_FILESIZE |
| @@ -2655,7 +2646,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags | |||
| 2655 | path.mnt = mntget(shm_mnt); | 2646 | path.mnt = mntget(shm_mnt); |
| 2656 | 2647 | ||
| 2657 | error = -ENOSPC; | 2648 | error = -ENOSPC; |
| 2658 | inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); | 2649 | inode = shmem_get_inode(root->d_sb, NULL, S_IFREG | S_IRWXUGO, 0, flags); |
| 2659 | if (!inode) | 2650 | if (!inode) |
| 2660 | goto put_dentry; | 2651 | goto put_dentry; |
| 2661 | 2652 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a03fd74602b..5c9f25ba1c9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -126,11 +126,6 @@ __setup("selinux=", selinux_enabled_setup); | |||
| 126 | int selinux_enabled = 1; | 126 | int selinux_enabled = 1; |
| 127 | #endif | 127 | #endif |
| 128 | 128 | ||
| 129 | /* Lists of inode and superblock security structures initialized | ||
| 130 | before the policy was loaded. */ | ||
| 131 | static LIST_HEAD(superblock_security_head); | ||
| 132 | static DEFINE_SPINLOCK(sb_security_lock); | ||
| 133 | |||
| 134 | static struct kmem_cache *sel_inode_cache; | 129 | static struct kmem_cache *sel_inode_cache; |
| 135 | 130 | ||
| 136 | /** | 131 | /** |
| @@ -266,7 +261,6 @@ static int superblock_alloc_security(struct super_block *sb) | |||
| 266 | return -ENOMEM; | 261 | return -ENOMEM; |
| 267 | 262 | ||
| 268 | mutex_init(&sbsec->lock); | 263 | mutex_init(&sbsec->lock); |
| 269 | INIT_LIST_HEAD(&sbsec->list); | ||
| 270 | INIT_LIST_HEAD(&sbsec->isec_head); | 264 | INIT_LIST_HEAD(&sbsec->isec_head); |
| 271 | spin_lock_init(&sbsec->isec_lock); | 265 | spin_lock_init(&sbsec->isec_lock); |
| 272 | sbsec->sb = sb; | 266 | sbsec->sb = sb; |
| @@ -281,12 +275,6 @@ static int superblock_alloc_security(struct super_block *sb) | |||
| 281 | static void superblock_free_security(struct super_block *sb) | 275 | static void superblock_free_security(struct super_block *sb) |
| 282 | { | 276 | { |
| 283 | struct superblock_security_struct *sbsec = sb->s_security; | 277 | struct superblock_security_struct *sbsec = sb->s_security; |
| 284 | |||
| 285 | spin_lock(&sb_security_lock); | ||
| 286 | if (!list_empty(&sbsec->list)) | ||
| 287 | list_del_init(&sbsec->list); | ||
| 288 | spin_unlock(&sb_security_lock); | ||
| 289 | |||
| 290 | sb->s_security = NULL; | 278 | sb->s_security = NULL; |
| 291 | kfree(sbsec); | 279 | kfree(sbsec); |
| 292 | } | 280 | } |
| @@ -612,10 +600,6 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 612 | /* Defer initialization until selinux_complete_init, | 600 | /* Defer initialization until selinux_complete_init, |
| 613 | after the initial policy is loaded and the security | 601 | after the initial policy is loaded and the security |
| 614 | server is ready to handle calls. */ | 602 | server is ready to handle calls. */ |
| 615 | spin_lock(&sb_security_lock); | ||
| 616 | if (list_empty(&sbsec->list)) | ||
| 617 | list_add(&sbsec->list, &superblock_security_head); | ||
| 618 | spin_unlock(&sb_security_lock); | ||
| 619 | goto out; | 603 | goto out; |
| 620 | } | 604 | } |
| 621 | rc = -EINVAL; | 605 | rc = -EINVAL; |
| @@ -806,16 +790,10 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
| 806 | 790 | ||
| 807 | /* | 791 | /* |
| 808 | * if the parent was able to be mounted it clearly had no special lsm | 792 | * if the parent was able to be mounted it clearly had no special lsm |
| 809 | * mount options. thus we can safely put this sb on the list and deal | 793 | * mount options. thus we can safely deal with this superblock later |
| 810 | * with it later | ||
| 811 | */ | 794 | */ |
| 812 | if (!ss_initialized) { | 795 | if (!ss_initialized) |
| 813 | spin_lock(&sb_security_lock); | ||
| 814 | if (list_empty(&newsbsec->list)) | ||
| 815 | list_add(&newsbsec->list, &superblock_security_head); | ||
| 816 | spin_unlock(&sb_security_lock); | ||
| 817 | return; | 796 | return; |
| 818 | } | ||
| 819 | 797 | ||
| 820 | /* how can we clone if the old one wasn't set up?? */ | 798 | /* how can we clone if the old one wasn't set up?? */ |
| 821 | BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); | 799 | BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); |
| @@ -5680,35 +5658,18 @@ static __init int selinux_init(void) | |||
| 5680 | return 0; | 5658 | return 0; |
| 5681 | } | 5659 | } |
| 5682 | 5660 | ||
| 5661 | static void delayed_superblock_init(struct super_block *sb, void *unused) | ||
| 5662 | { | ||
| 5663 | superblock_doinit(sb, NULL); | ||
| 5664 | } | ||
| 5665 | |||
| 5683 | void selinux_complete_init(void) | 5666 | void selinux_complete_init(void) |
| 5684 | { | 5667 | { |
| 5685 | printk(KERN_DEBUG "SELinux: Completing initialization.\n"); | 5668 | printk(KERN_DEBUG "SELinux: Completing initialization.\n"); |
| 5686 | 5669 | ||
| 5687 | /* Set up any superblocks initialized prior to the policy load. */ | 5670 | /* Set up any superblocks initialized prior to the policy load. */ |
| 5688 | printk(KERN_DEBUG "SELinux: Setting up existing superblocks.\n"); | 5671 | printk(KERN_DEBUG "SELinux: Setting up existing superblocks.\n"); |
| 5689 | spin_lock(&sb_lock); | 5672 | iterate_supers(delayed_superblock_init, NULL); |
| 5690 | spin_lock(&sb_security_lock); | ||
| 5691 | next_sb: | ||
| 5692 | if (!list_empty(&superblock_security_head)) { | ||
| 5693 | struct superblock_security_struct *sbsec = | ||
| 5694 | list_entry(superblock_security_head.next, | ||
| 5695 | struct superblock_security_struct, | ||
| 5696 | list); | ||
| 5697 | struct super_block *sb = sbsec->sb; | ||
| 5698 | sb->s_count++; | ||
| 5699 | spin_unlock(&sb_security_lock); | ||
| 5700 | spin_unlock(&sb_lock); | ||
| 5701 | down_read(&sb->s_umount); | ||
| 5702 | if (sb->s_root) | ||
| 5703 | superblock_doinit(sb, NULL); | ||
| 5704 | drop_super(sb); | ||
| 5705 | spin_lock(&sb_lock); | ||
| 5706 | spin_lock(&sb_security_lock); | ||
| 5707 | list_del_init(&sbsec->list); | ||
| 5708 | goto next_sb; | ||
| 5709 | } | ||
| 5710 | spin_unlock(&sb_security_lock); | ||
| 5711 | spin_unlock(&sb_lock); | ||
| 5712 | } | 5673 | } |
| 5713 | 5674 | ||
| 5714 | /* SELinux requires early initialization in order to label | 5675 | /* SELinux requires early initialization in order to label |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index c4e062336ef..26c7eee1c30 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
| @@ -55,7 +55,6 @@ struct file_security_struct { | |||
| 55 | 55 | ||
| 56 | struct superblock_security_struct { | 56 | struct superblock_security_struct { |
| 57 | struct super_block *sb; /* back pointer to sb object */ | 57 | struct super_block *sb; /* back pointer to sb object */ |
| 58 | struct list_head list; /* list of superblock_security_struct */ | ||
| 59 | u32 sid; /* SID of file system superblock */ | 58 | u32 sid; /* SID of file system superblock */ |
| 60 | u32 def_sid; /* default SID for labeling */ | 59 | u32 def_sid; /* default SID for labeling */ |
| 61 | u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ | 60 | u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ |
