/*ARGSUSED*/ int zfs_umount(struct super_block *sb) { zfs_sb_t *zsb = sb->s_fs_info; objset_t *os; arc_remove_prune_callback(zsb->z_arc_prune); VERIFY(zfs_sb_teardown(zsb, B_TRUE) == 0); os = zsb->z_os; bdi_destroy(sb->s_bdi); /* * z_os will be NULL if there was an error in * attempting to reopen zsb. */ if (os != NULL) { /* * Unset the objset user_ptr. */ mutex_enter(&os->os_user_ptr_lock); dmu_objset_set_user(os, NULL); mutex_exit(&os->os_user_ptr_lock); /* * Finally release the objset */ dmu_objset_disown(os, zsb); } zfs_sb_free(zsb); return (0); }
/** * blk_release_queue: - release a &struct request_queue when it is no longer needed * @kobj: the kobj belonging to the request queue to be released * * Description: * blk_release_queue is the pair to blk_init_queue() or * blk_queue_make_request(). It should be called when a request queue is * being released; typically when a block device is being de-registered. * Currently, its primary task it to free all the &struct request * structures that were allocated to the queue and the queue itself. * * Note: * The low level driver must have finished any outstanding requests first * via blk_cleanup_queue(). **/ static void blk_release_queue(struct kobject *kobj) { struct request_queue *q = container_of(kobj, struct request_queue, kobj); blkcg_exit_queue(q); if (q->elevator) { spin_lock_irq(q->queue_lock); ioc_clear_queue(q); spin_unlock_irq(q->queue_lock); elevator_exit(q->elevator); } blk_exit_rl(&q->root_rl); if (q->queue_tags) __blk_queue_free_tags(q); kfree(q->flush_rq); blk_trace_shutdown(q); bdi_destroy(&q->backing_dev_info); ida_simple_remove(&blk_queue_ida, q->id); call_rcu(&q->rcu_head, blk_free_queue_rcu); }
static void ncp_put_super(struct super_block *sb) { struct ncp_server *server = NCP_SBP(sb); ncp_lock_server(server); ncp_disconnect(server); ncp_unlock_server(server); ncp_stop_tasks(server); #ifdef CONFIG_NCPFS_NLS /* unload the NLS charsets */ unload_nls(server->nls_vol); unload_nls(server->nls_io); #endif /* CONFIG_NCPFS_NLS */ mutex_destroy(&server->rcv.creq_mutex); mutex_destroy(&server->root_setup_lock); mutex_destroy(&server->mutex); if (server->info_filp) fput(server->info_filp); fput(server->ncp_filp); kill_pid(server->m.wdog_pid, SIGTERM, 1); put_pid(server->m.wdog_pid); bdi_destroy(&server->bdi); kfree(server->priv.data); kfree(server->auth.object_name); vfree(server->rxbuf); vfree(server->txbuf); vfree(server->packet); sb->s_fs_info = NULL; kfree(server); }
static void ncp_put_super(struct super_block *sb) { struct ncp_server *server = NCP_SBP(sb); ncp_lock_server(server); ncp_disconnect(server); ncp_unlock_server(server); ncp_stop_tasks(server); mutex_destroy(&server->rcv.creq_mutex); mutex_destroy(&server->root_setup_lock); mutex_destroy(&server->mutex); if (server->info_sock) sockfd_put(server->info_sock); sockfd_put(server->ncp_sock); kill_pid(server->m.wdog_pid, SIGTERM, 1); put_pid(server->m.wdog_pid); bdi_destroy(&server->bdi); kfree(server->priv.data); kfree(server->auth.object_name); vfree(server->rxbuf); vfree(server->txbuf); vfree(server->packet); call_rcu(&server->rcu, delayed_free); }
/* * This function is called when the vfs is freeing the superblock. We just * need to free our own part. */ static void exofs_put_super(struct super_block *sb) { int num_pend; struct exofs_sb_info *sbi = sb->s_fs_info; if (sb->s_dirt) exofs_write_super(sb); /* make sure there are no pending commands */ for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0; num_pend = atomic_read(&sbi->s_curr_pending)) { wait_queue_head_t wq; init_waitqueue_head(&wq); wait_event_timeout(wq, (atomic_read(&sbi->s_curr_pending) == 0), msecs_to_jiffies(100)); } _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], sbi->layout.s_pid); bdi_destroy(&sbi->bdi); exofs_free_sbi(sbi); sb->s_fs_info = NULL; }
static void cifs_put_super(struct super_block *sb) { int rc = 0; struct cifs_sb_info *cifs_sb; cFYI(1, "In cifs_put_super"); cifs_sb = CIFS_SB(sb); if (cifs_sb == NULL) { cFYI(1, "Empty cifs superblock info passed to unmount"); return; } rc = cifs_umount(sb, cifs_sb); if (rc) cERROR(1, "cifs_umount failed with return code %d", rc); if (cifs_sb->mountdata) { kfree(cifs_sb->mountdata); cifs_sb->mountdata = NULL; } unload_nls(cifs_sb->local_nls); bdi_destroy(&cifs_sb->bdi); kfree(cifs_sb); }
static void smb_put_super(struct super_block *sb) { struct smb_sb_info *server = SMB_SB(sb); lock_kernel(); smb_lock_server(server); server->state = CONN_INVALID; smbiod_unregister_server(server); smb_close_socket(server); if (server->conn_pid) kill_pid(server->conn_pid, SIGTERM, 1); bdi_destroy(&server->bdi); kfree(server->ops); smb_unload_nls(server); sb->s_fs_info = NULL; smb_unlock_server(server); put_pid(server->conn_pid); kfree(server); unlock_kernel(); }
/** * blk_cleanup_queue: - release a &struct request_queue when it is no longer needed * @kobj: the kobj belonging of the request queue to be released * * Description: * blk_cleanup_queue is the pair to blk_init_queue() or * blk_queue_make_request(). It should be called when a request queue is * being released; typically when a block device is being de-registered. * Currently, its primary task it to free all the &struct request * structures that were allocated to the queue and the queue itself. * * Caveat: * Hopefully the low level driver will have finished any * outstanding requests first... **/ static void blk_release_queue(struct kobject *kobj) { struct request_queue *q = container_of(kobj, struct request_queue, kobj); struct request_list *rl = &q->rq; blk_sync_queue(q); if (q->elevator) elevator_exit(q->elevator); blk_throtl_exit(q); if (rl->rq_pool) mempool_destroy(rl->rq_pool); if (q->queue_tags) __blk_queue_free_tags(q); blk_throtl_release(q); blk_trace_shutdown(q); bdi_destroy(&q->backing_dev_info); kmem_cache_free(blk_requestq_cachep, q); }
/** * blk_cleanup_queue: - release a &struct request_queue when it is no longer needed * @kobj: the kobj belonging of the request queue to be released * * Description: * blk_cleanup_queue is the pair to blk_init_queue() or * blk_queue_make_request(). It should be called when a request queue is * being released; typically when a block device is being de-registered. * Currently, its primary task it to free all the &struct request * structures that were allocated to the queue and the queue itself. * * Caveat: * Hopefully the low level driver will have finished any * outstanding requests first... **/ static void blk_release_queue(struct kobject *kobj) { struct request_queue *q = container_of(kobj, struct request_queue, kobj); struct request_list *rl = &q->rq; blk_sync_queue(q); if (q->elevator) { spin_lock_irq(q->queue_lock); ioc_clear_queue(q); spin_unlock_irq(q->queue_lock); elevator_exit(q->elevator); } blk_throtl_exit(q); if (rl->rq_pool) mempool_destroy(rl->rq_pool); if (q->queue_tags) __blk_queue_free_tags(q); blk_throtl_release(q); blk_trace_shutdown(q); bdi_destroy(&q->backing_dev_info); ida_simple_remove(&blk_queue_ida, q->id); kmem_cache_free(blk_requestq_cachep, q); }
void fuse_conn_put(struct fuse_conn *fc) { if (atomic_dec_and_test(&fc->count)) { if (fc->destroy_req) fuse_request_free(fc->destroy_req); mutex_destroy(&fc->inst_mutex); bdi_destroy(&fc->bdi); kfree(fc); } }
static void __exit exit_dlmfs_fs(void) { unregister_filesystem(&dlmfs_fs_type); flush_workqueue(user_dlm_worker); destroy_workqueue(user_dlm_worker); kmem_cache_destroy(dlmfs_inode_cache); bdi_destroy(&dlmfs_backing_dev_info); }
static void coda_put_super(struct super_block *sb) { struct venus_comm *vcp = coda_vcp(sb); mutex_lock(&vcp->vc_mutex); bdi_destroy(&vcp->bdi); vcp->vc_sb = NULL; sb->s_fs_info = NULL; mutex_unlock(&vcp->vc_mutex); printk("Coda: Bye bye.\n"); }
int __init init_rootfs(void) { int err; err = bdi_init(&ramfs_backing_dev_info); if (err) return err; err = register_filesystem(&rootfs_fs_type); if (err) bdi_destroy(&ramfs_backing_dev_info); return err; }
static void __exit exit_dlmfs_fs(void) { unregister_filesystem(&dlmfs_fs_type); flush_workqueue(user_dlm_worker); destroy_workqueue(user_dlm_worker); /* * Make sure all delayed rcu free inodes are flushed before we * destroy cache. */ rcu_barrier(); kmem_cache_destroy(dlmfs_inode_cache); bdi_destroy(&dlmfs_backing_dev_info); }
int __init init_ramfs_fs(void) { static unsigned long once; int err; if (test_and_set_bit(0, &once)) return 0; err = bdi_init(&ramfs_backing_dev_info); if (err) return err; err = register_filesystem(&ramfs_fs_type); if (err) bdi_destroy(&ramfs_backing_dev_info); return err; }
/* * For use from filesystems to quickly init and register a bdi associated * with dirty writeback */ int bdi_setup_and_register(struct backing_dev_info *bdi, char *name) { int err; bdi->name = name; bdi->capabilities = 0; err = bdi_init(bdi); if (err) return err; err = bdi_register(bdi, NULL, "%.28s-%ld", name, atomic_long_inc_return(&bdi_seq)); if (err) { bdi_destroy(bdi); return err; } return 0; }
static int __init init_dlmfs_fs(void) { int status; int cleanup_inode = 0, cleanup_worker = 0; dlmfs_print_version(); status = bdi_init(&dlmfs_backing_dev_info); if (status) return status; dlmfs_inode_cache = kmem_cache_create("dlmfs_inode_cache", sizeof(struct dlmfs_inode_private), 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), dlmfs_init_once); if (!dlmfs_inode_cache) { status = -ENOMEM; goto bail; } cleanup_inode = 1; user_dlm_worker = create_singlethread_workqueue("user_dlm"); if (!user_dlm_worker) { status = -ENOMEM; goto bail; } cleanup_worker = 1; user_dlm_set_locking_protocol(); status = register_filesystem(&dlmfs_fs_type); bail: if (status) { if (cleanup_inode) kmem_cache_destroy(dlmfs_inode_cache); if (cleanup_worker) destroy_workqueue(user_dlm_worker); bdi_destroy(&dlmfs_backing_dev_info); } else printk("OCFS2 User DLM kernel interface loaded\n"); return status; }
/* * destroy a volume record */ void afs_put_volume(struct afs_volume *volume) { struct afs_vlocation *vlocation; int loop; if (!volume) return; _enter("%p", volume); ASSERTCMP(atomic_read(&volume->usage), >, 0); vlocation = volume->vlocation; /* to prevent a race, the decrement and the dequeue must be effectively * atomic */ down_write(&vlocation->cell->vl_sem); if (likely(!atomic_dec_and_test(&volume->usage))) { up_write(&vlocation->cell->vl_sem); _leave(""); return; } vlocation->vols[volume->type] = NULL; up_write(&vlocation->cell->vl_sem); /* finish cleaning up the volume */ #ifdef CONFIG_AFS_FSCACHE fscache_relinquish_cookie(volume->cache, 0); #endif afs_put_vlocation(vlocation); for (loop = volume->nservers - 1; loop >= 0; loop--) afs_put_server(volume->servers[loop]); bdi_destroy(&volume->bdi); kfree(volume); _leave(" [destroyed]"); }
static void fuse_put_super(struct super_block *sb) { struct fuse_conn *fc = get_fuse_conn_super(sb); fuse_send_destroy(fc); spin_lock(&fc->lock); fc->connected = 0; fc->blocked = 0; spin_unlock(&fc->lock); /* Flush all readers on this fs */ kill_fasync(&fc->fasync, SIGIO, POLL_IN); wake_up_all(&fc->waitq); wake_up_all(&fc->blocked_waitq); wake_up_all(&fc->reserved_req_waitq); mutex_lock(&fuse_mutex); list_del(&fc->entry); fuse_ctl_remove_conn(fc); mutex_unlock(&fuse_mutex); bdi_destroy(&fc->bdi); fuse_conn_put(fc); }
/* afs_put_super * Called from unmount to release super_block. */ static void afs_put_super(struct super_block *sbp) { AFS_GLOCK(); AFS_STATCNT(afs_unmount); afs_globalVFS = 0; afs_globalVp = 0; afs_shutdown(); mntput(afs_cacheMnt); osi_linux_verify_alloced_memory(); #if defined(HAVE_LINUX_BDI_INIT) bdi_destroy(afs_backing_dev_info); #endif kfree(afs_backing_dev_info); AFS_GUNLOCK(); sbp->s_dev = 0; module_put(THIS_MODULE); }
/* afs_put_super * Called from unmount to release super_block. */ static void afs_put_super(struct super_block *sbp) { AFS_GLOCK(); AFS_STATCNT(afs_unmount); afs_globalVFS = 0; afs_globalVp = 0; osi_linux_free_inode_pages(); /* invalidate and release remaining AFS inodes. */ afs_shutdown(); mntput(afs_cacheMnt); osi_linux_verify_alloced_memory(); #if defined(HAVE_LINUX_BDI_INIT) bdi_destroy(afs_backing_dev_info); #endif osi_Free(afs_backing_dev_info, sizeof(struct backing_dev_info)); AFS_GUNLOCK(); sbp->s_dev = 0; module_put(THIS_MODULE); }
static int coda_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root = NULL; struct venus_comm *vc; struct CodaFid fid; int error; int idx; idx = get_device_index((struct coda_mount_data *) data); /* Ignore errors in data, for backward compatibility */ if(idx == -1) idx = 0; printk(KERN_INFO "coda_read_super: device index: %i\n", idx); vc = &coda_comms[idx]; mutex_lock(&vc->vc_mutex); if (!vc->vc_inuse) { printk("coda_read_super: No pseudo device\n"); error = -EINVAL; goto unlock_out; } if (vc->vc_sb) { printk("coda_read_super: Device already mounted\n"); error = -EBUSY; goto unlock_out; } error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); if (error) goto unlock_out; vc->vc_sb = sb; mutex_unlock(&vc->vc_mutex); sb->s_fs_info = vc; sb->s_flags |= MS_NOATIME; sb->s_blocksize = 4096; /* XXXXX what do we put here?? */ sb->s_blocksize_bits = 12; sb->s_magic = CODA_SUPER_MAGIC; sb->s_op = &coda_super_operations; sb->s_d_op = &coda_dentry_operations; sb->s_bdi = &vc->bdi; /* get root fid from Venus: this needs the root inode */ error = venus_rootfid(sb, &fid); if ( error ) { printk("coda_read_super: coda_get_rootfid failed with %d\n", error); goto error; } printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid)); /* make root inode */ error = coda_cnode_make(&root, &fid, sb); if ( error || !root ) { printk("Failure of coda_cnode_make for root: error %d\n", error); goto error; } printk("coda_read_super: rootinode is %ld dev %s\n", root->i_ino, root->i_sb->s_id); sb->s_root = d_make_root(root); if (!sb->s_root) { error = -EINVAL; goto error; } return 0; error: if (root) iput(root); mutex_lock(&vc->vc_mutex); bdi_destroy(&vc->bdi); vc->vc_sb = NULL; sb->s_fs_info = NULL; unlock_out: mutex_unlock(&vc->vc_mutex); return error; }
static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi, unsigned table_count) { struct exofs_sb_info *sbi = *psbi; struct osd_dev *fscb_od; struct osd_obj_id obj = {.partition = sbi->layout.s_pid, .id = EXOFS_DEVTABLE_ID}; struct exofs_device_table *dt; unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) + sizeof(*dt); unsigned numdevs, i; int ret; dt = kmalloc(table_bytes, GFP_KERNEL); if (unlikely(!dt)) { EXOFS_ERR("ERROR: allocating %x bytes for device table\n", table_bytes); return -ENOMEM; } fscb_od = sbi->layout.s_ods[0]; sbi->layout.s_ods[0] = NULL; sbi->layout.s_numdevs = 0; ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes); if (unlikely(ret)) { EXOFS_ERR("ERROR: reading device table\n"); goto out; } numdevs = le64_to_cpu(dt->dt_num_devices); if (unlikely(!numdevs)) { ret = -EINVAL; goto out; } WARN_ON(table_count != numdevs); ret = _read_and_match_data_map(sbi, numdevs, dt); if (unlikely(ret)) goto out; if (likely(numdevs > 1)) { unsigned size = numdevs * sizeof(sbi->layout.s_ods[0]); sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL); if (unlikely(!sbi)) { ret = -ENOMEM; goto out; } memset(&sbi->layout.s_ods[1], 0, size - sizeof(sbi->layout.s_ods[0])); *psbi = sbi; } for (i = 0; i < numdevs; i++) { struct exofs_fscb fscb; struct osd_dev_info odi; struct osd_dev *od; if (exofs_devs_2_odi(&dt->dt_dev_table[i], &odi)) { EXOFS_ERR("ERROR: Read all-zeros device entry\n"); ret = -EINVAL; goto out; } printk(KERN_NOTICE "Add device[%d]: osd_name-%s\n", i, odi.osdname); /* On all devices the device table is identical. The user can * specify any one of the participating devices on the command * line. We always keep them in device-table order. */ if (fscb_od && osduld_device_same(fscb_od, &odi)) { sbi->layout.s_ods[i] = fscb_od; ++sbi->layout.s_numdevs; fscb_od = NULL; continue; } od = osduld_info_lookup(&odi); if (unlikely(IS_ERR(od))) { ret = PTR_ERR(od); EXOFS_ERR("ERROR: device requested is not found " "osd_name-%s =>%d\n", odi.osdname, ret); goto out; } sbi->layout.s_ods[i] = od; ++sbi->layout.s_numdevs; /* Read the fscb of the other devices to make sure the FS * partition is there. */ ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, sizeof(fscb)); if (unlikely(ret)) { EXOFS_ERR("ERROR: Malformed participating device " "error reading fscb osd_name-%s\n", odi.osdname); goto out; } /* TODO: verify other information is correct and FS-uuid * matches. Benny what did you say about device table * generation and old devices? */ } out: kfree(dt); if (unlikely(!ret && fscb_od)) { EXOFS_ERR( "ERROR: Bad device-table container device not present\n"); osduld_put_device(fscb_od); ret = -EINVAL; } return ret; } /* * Read the superblock from the OSD and fill in the fields */ static int exofs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root; struct exofs_mountopt *opts = data; struct exofs_sb_info *sbi; /*extended info */ struct osd_dev *od; /* Master device */ struct exofs_fscb fscb; /*on-disk superblock info */ struct osd_obj_id obj; unsigned table_count; int ret; sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) return -ENOMEM; ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY); if (ret) goto free_bdi; /* use mount options to fill superblock */ od = osduld_path_lookup(opts->dev_name); if (IS_ERR(od)) { ret = PTR_ERR(od); goto free_sbi; } /* Default layout in case we do not have a device-table */ sbi->layout.stripe_unit = PAGE_SIZE; sbi->layout.mirrors_p1 = 1; sbi->layout.group_width = 1; sbi->layout.group_depth = -1; sbi->layout.group_count = 1; sbi->layout.s_ods[0] = od; sbi->layout.s_numdevs = 1; sbi->layout.s_pid = opts->pid; sbi->s_timeout = opts->timeout; /* fill in some other data by hand */ memset(sb->s_id, 0, sizeof(sb->s_id)); strcpy(sb->s_id, "exofs"); sb->s_blocksize = EXOFS_BLKSIZE; sb->s_blocksize_bits = EXOFS_BLKSHIFT; sb->s_maxbytes = MAX_LFS_FILESIZE; atomic_set(&sbi->s_curr_pending, 0); sb->s_bdev = NULL; sb->s_dev = 0; obj.partition = sbi->layout.s_pid; obj.id = EXOFS_SUPER_ID; exofs_make_credential(sbi->s_cred, &obj); ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, sizeof(fscb)); if (unlikely(ret)) goto free_sbi; sb->s_magic = le16_to_cpu(fscb.s_magic); sbi->s_nextid = le64_to_cpu(fscb.s_nextid); sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles); /* make sure what we read from the object store is correct */ if (sb->s_magic != EXOFS_SUPER_MAGIC) { if (!silent) EXOFS_ERR("ERROR: Bad magic value\n"); ret = -EINVAL; goto free_sbi; } if (le32_to_cpu(fscb.s_version) != EXOFS_FSCB_VER) { EXOFS_ERR("ERROR: Bad FSCB version expected-%d got-%d\n", EXOFS_FSCB_VER, le32_to_cpu(fscb.s_version)); ret = -EINVAL; goto free_sbi; } /* start generation numbers from a random point */ get_random_bytes(&sbi->s_next_generation, sizeof(u32)); spin_lock_init(&sbi->s_next_gen_lock); table_count = le64_to_cpu(fscb.s_dev_table_count); if (table_count) { ret = exofs_read_lookup_dev_table(&sbi, table_count); if (unlikely(ret)) goto free_sbi; } /* set up operation vectors */ sb->s_bdi = &sbi->bdi; sb->s_fs_info = sbi; sb->s_op = &exofs_sops; sb->s_export_op = &exofs_export_ops; root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF); if (IS_ERR(root)) { EXOFS_ERR("ERROR: exofs_iget failed\n"); ret = PTR_ERR(root); goto free_sbi; } sb->s_root = d_alloc_root(root); if (!sb->s_root) { iput(root); EXOFS_ERR("ERROR: get root inode failed\n"); ret = -ENOMEM; goto free_sbi; } if (!S_ISDIR(root->i_mode)) { dput(sb->s_root); sb->s_root = NULL; EXOFS_ERR("ERROR: corrupt root inode (mode = %hd)\n", root->i_mode); ret = -EINVAL; goto free_sbi; } _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0], sbi->layout.s_pid); return 0; free_sbi: bdi_destroy(&sbi->bdi); free_bdi: EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", opts->dev_name, sbi->layout.s_pid, ret); exofs_free_sbi(sbi); return ret; } /* * Set up the superblock (calls exofs_fill_super eventually) */ static struct dentry *exofs_mount(struct file_system_type *type, int flags, const char *dev_name, void *data) { struct exofs_mountopt opts; int ret; ret = parse_options(data, &opts); if (ret) return ERR_PTR(ret); opts.dev_name = dev_name; return mount_nodev(type, flags, &opts, exofs_fill_super); } /* * Return information about the file system state in the buffer. This is used * by the 'df' command, for example. */ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; struct exofs_sb_info *sbi = sb->s_fs_info; struct exofs_io_state *ios; struct osd_attr attrs[] = { ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS, OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)), ATTR_DEF(OSD_APAGE_PARTITION_INFORMATION, OSD_ATTR_PI_USED_CAPACITY, sizeof(__be64)), }; uint64_t capacity = ULLONG_MAX; uint64_t used = ULLONG_MAX; uint8_t cred_a[OSD_CAP_LEN]; int ret; ret = exofs_get_io_state(&sbi->layout, &ios); if (ret) { EXOFS_DBGMSG("exofs_get_io_state failed.\n"); return ret; } exofs_make_credential(cred_a, &ios->obj); ios->cred = sbi->s_cred; ios->in_attr = attrs; ios->in_attr_len = ARRAY_SIZE(attrs); ret = exofs_sbi_read(ios); if (unlikely(ret)) goto out; ret = extract_attr_from_ios(ios, &attrs[0]); if (likely(!ret)) { capacity = get_unaligned_be64(attrs[0].val_ptr); if (unlikely(!capacity)) capacity = ULLONG_MAX; } else EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n"); ret = extract_attr_from_ios(ios, &attrs[1]); if (likely(!ret)) used = get_unaligned_be64(attrs[1].val_ptr); else EXOFS_DBGMSG("exofs_statfs: get used-space failed.\n"); /* fill in the stats buffer */ buf->f_type = EXOFS_SUPER_MAGIC; buf->f_bsize = EXOFS_BLKSIZE; buf->f_blocks = capacity >> 9; buf->f_bfree = (capacity - used) >> 9; buf->f_bavail = buf->f_bfree; buf->f_files = sbi->s_numfiles; buf->f_ffree = EXOFS_MAX_ID - sbi->s_numfiles; buf->f_namelen = EXOFS_NAME_LEN; out: exofs_put_io_state(ios); return ret; } static const struct super_operations exofs_sops = { .alloc_inode = exofs_alloc_inode, .destroy_inode = exofs_destroy_inode, .write_inode = exofs_write_inode, .evict_inode = exofs_evict_inode, .put_super = exofs_put_super, .write_super = exofs_write_super, .sync_fs = exofs_sync_fs, .statfs = exofs_statfs, }; /****************************************************************************** * EXPORT OPERATIONS *****************************************************************************/ struct dentry *exofs_get_parent(struct dentry *child) { unsigned long ino = exofs_parent_ino(child); if (!ino) return NULL; return d_obtain_alias(exofs_iget(child->d_inode->i_sb, ino)); }
static int cifs_read_super(struct super_block *sb, struct smb_vol *volume_info, const char *devname, int silent) { struct inode *inode; struct cifs_sb_info *cifs_sb; int rc = 0; cifs_sb = CIFS_SB(sb); spin_lock_init(&cifs_sb->tlink_tree_lock); cifs_sb->tlink_tree = RB_ROOT; rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); if (rc) return rc; cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; rc = cifs_mount(sb, cifs_sb, volume_info, devname); if (rc) { if (!silent) cERROR(1, "cifs_mount failed w/return code = %d", rc); goto out_mount_failed; } sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_op = &cifs_super_ops; sb->s_bdi = &cifs_sb->bdi; sb->s_blocksize = CIFS_MAX_MSGSIZE; sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ inode = cifs_root_iget(sb); if (IS_ERR(inode)) { rc = PTR_ERR(inode); inode = NULL; goto out_no_root; } sb->s_root = d_alloc_root(inode); if (!sb->s_root) { rc = -ENOMEM; goto out_no_root; } /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */ if (cifs_sb_master_tcon(cifs_sb)->nocase) sb->s_d_op = &cifs_ci_dentry_ops; else sb->s_d_op = &cifs_dentry_ops; #ifdef CIFS_NFSD_EXPORT if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { cFYI(1, "export ops supported"); sb->s_export_op = &cifs_export_ops; } #endif /* CIFS_NFSD_EXPORT */ return 0; out_no_root: cERROR(1, "cifs_read_super: get root inode failed"); if (inode) iput(inode); cifs_umount(sb, cifs_sb); out_mount_failed: bdi_destroy(&cifs_sb->bdi); return rc; }
static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) { struct ncp_mount_data_kernel data; struct ncp_server *server; struct file *ncp_filp; struct inode *root_inode; struct inode *sock_inode; struct socket *sock; int error; int default_bufsize; #ifdef CONFIG_NCPFS_PACKET_SIGNING int options; #endif struct ncp_entry_info finfo; memset(&data, 0, sizeof(data)); server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL); if (!server) return -ENOMEM; sb->s_fs_info = server; error = -EFAULT; if (raw_data == NULL) goto out; switch (*(int*)raw_data) { case NCP_MOUNT_VERSION: { struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data; data.flags = md->flags; data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; data.mounted_uid = md->mounted_uid; data.wdog_pid = find_get_pid(md->wdog_pid); data.ncp_fd = md->ncp_fd; data.time_out = md->time_out; data.retry_count = md->retry_count; data.uid = md->uid; data.gid = md->gid; data.file_mode = md->file_mode; data.dir_mode = md->dir_mode; data.info_fd = -1; memcpy(data.mounted_vol, md->mounted_vol, NCP_VOLNAME_LEN+1); } break; case NCP_MOUNT_VERSION_V4: { struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data; data.flags = md->flags; data.mounted_uid = md->mounted_uid; data.wdog_pid = find_get_pid(md->wdog_pid); data.ncp_fd = md->ncp_fd; data.time_out = md->time_out; data.retry_count = md->retry_count; data.uid = md->uid; data.gid = md->gid; data.file_mode = md->file_mode; data.dir_mode = md->dir_mode; data.info_fd = -1; } break; default: error = -ECHRNG; if (memcmp(raw_data, "vers", 4) == 0) { error = ncp_parse_options(&data, raw_data); } if (error) goto out; break; } error = -EBADF; ncp_filp = fget(data.ncp_fd); if (!ncp_filp) goto out; error = -ENOTSOCK; sock_inode = ncp_filp->f_path.dentry->d_inode; if (!S_ISSOCK(sock_inode->i_mode)) goto out_fput; sock = SOCKET_I(sock_inode); if (!sock) goto out_fput; if (sock->type == SOCK_STREAM) default_bufsize = 0xF000; else default_bufsize = 1024; sb->s_flags |= MS_NODIRATIME; /* probably even noatime */ sb->s_maxbytes = 0xFFFFFFFFU; sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; sb->s_magic = NCP_SUPER_MAGIC; sb->s_op = &ncp_sops; sb->s_d_op = &ncp_dentry_operations; sb->s_bdi = &server->bdi; server = NCP_SBP(sb); memset(server, 0, sizeof(*server)); error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY); if (error) goto out_fput; server->ncp_filp = ncp_filp; server->ncp_sock = sock; if (data.info_fd != -1) { struct socket *info_sock; error = -EBADF; server->info_filp = fget(data.info_fd); if (!server->info_filp) goto out_bdi; error = -ENOTSOCK; sock_inode = server->info_filp->f_path.dentry->d_inode; if (!S_ISSOCK(sock_inode->i_mode)) goto out_fput2; info_sock = SOCKET_I(sock_inode); if (!info_sock) goto out_fput2; error = -EBADFD; if (info_sock->type != SOCK_STREAM) goto out_fput2; server->info_sock = info_sock; } /* server->lock = 0; */ mutex_init(&server->mutex); server->packet = NULL; /* server->buffer_size = 0; */ /* server->conn_status = 0; */ /* server->root_dentry = NULL; */ /* server->root_setuped = 0; */ mutex_init(&server->root_setup_lock); #ifdef CONFIG_NCPFS_PACKET_SIGNING /* server->sign_wanted = 0; */ /* server->sign_active = 0; */ #endif init_rwsem(&server->auth_rwsem); server->auth.auth_type = NCP_AUTH_NONE; /* server->auth.object_name_len = 0; */ /* server->auth.object_name = NULL; */ /* server->auth.object_type = 0; */ /* server->priv.len = 0; */ /* server->priv.data = NULL; */ server->m = data; /* Although anything producing this is buggy, it happens now because of PATH_MAX changes.. */ if (server->m.time_out < 1) { server->m.time_out = 10; printk(KERN_INFO "You need to recompile your ncpfs utils..\n"); } server->m.time_out = server->m.time_out * HZ / 100; server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG; server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR; #ifdef CONFIG_NCPFS_NLS /* load the default NLS charsets */ server->nls_vol = load_nls_default(); server->nls_io = load_nls_default(); #endif /* CONFIG_NCPFS_NLS */ atomic_set(&server->dentry_ttl, 0); /* no caching */ INIT_LIST_HEAD(&server->tx.requests); mutex_init(&server->rcv.creq_mutex); server->tx.creq = NULL; server->rcv.creq = NULL; init_timer(&server->timeout_tm); #undef NCP_PACKET_SIZE #define NCP_PACKET_SIZE 131072 error = -ENOMEM; server->packet_size = NCP_PACKET_SIZE; server->packet = vmalloc(NCP_PACKET_SIZE); if (server->packet == NULL) goto out_nls; server->txbuf = vmalloc(NCP_PACKET_SIZE); if (server->txbuf == NULL) goto out_packet; server->rxbuf = vmalloc(NCP_PACKET_SIZE); if (server->rxbuf == NULL) goto out_txbuf; lock_sock(sock->sk); server->data_ready = sock->sk->sk_data_ready; server->write_space = sock->sk->sk_write_space; server->error_report = sock->sk->sk_error_report; sock->sk->sk_user_data = server; sock->sk->sk_data_ready = ncp_tcp_data_ready; sock->sk->sk_error_report = ncp_tcp_error_report; if (sock->type == SOCK_STREAM) { server->rcv.ptr = (unsigned char*)&server->rcv.buf; server->rcv.len = 10; server->rcv.state = 0; INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc); INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc); sock->sk->sk_write_space = ncp_tcp_write_space; } else { INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc); INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc); server->timeout_tm.data = (unsigned long)server; server->timeout_tm.function = ncpdgram_timeout_call; } release_sock(sock->sk); ncp_lock_server(server); error = ncp_connect(server); ncp_unlock_server(server); if (error < 0) goto out_rxbuf; DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */ #ifdef CONFIG_NCPFS_PACKET_SIGNING if (ncp_negotiate_size_and_options(server, default_bufsize, NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0) { if (options != NCP_DEFAULT_OPTIONS) { if (ncp_negotiate_size_and_options(server, default_bufsize, options & 2, &(server->buffer_size), &options) != 0) { goto out_disconnect; } } ncp_lock_server(server); if (options & 2) server->sign_wanted = 1; ncp_unlock_server(server); } else #endif /* CONFIG_NCPFS_PACKET_SIGNING */ if (ncp_negotiate_buffersize(server, default_bufsize, &(server->buffer_size)) != 0) goto out_disconnect; DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size); memset(&finfo, 0, sizeof(finfo)); finfo.i.attributes = aDIR; finfo.i.dataStreamSize = 0; /* ignored */ finfo.i.dirEntNum = 0; finfo.i.DosDirNum = 0; #ifdef CONFIG_NCPFS_SMALLDOS finfo.i.NSCreator = NW_NS_DOS; #endif finfo.volume = NCP_NUMBER_OF_VOLUMES; /* set dates of mountpoint to Jan 1, 1986; 00:00 */ finfo.i.creationTime = finfo.i.modifyTime = cpu_to_le16(0x0000); finfo.i.creationDate = finfo.i.modifyDate = finfo.i.lastAccessDate = cpu_to_le16(0x0C21); finfo.i.nameLen = 0; finfo.i.entryName[0] = '\0'; finfo.opened = 0; finfo.ino = 2; /* tradition */ server->name_space[finfo.volume] = NW_NS_DOS; error = -ENOMEM; root_inode = ncp_iget(sb, &finfo); if (!root_inode) goto out_disconnect; DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber); sb->s_root = d_make_root(root_inode); if (!sb->s_root) goto out_disconnect; return 0; out_disconnect: ncp_lock_server(server); ncp_disconnect(server); ncp_unlock_server(server); out_rxbuf: ncp_stop_tasks(server); vfree(server->rxbuf); out_txbuf: vfree(server->txbuf); out_packet: vfree(server->packet); out_nls: #ifdef CONFIG_NCPFS_NLS unload_nls(server->nls_io); unload_nls(server->nls_vol); #endif mutex_destroy(&server->rcv.creq_mutex); mutex_destroy(&server->root_setup_lock); mutex_destroy(&server->mutex); out_fput2: if (server->info_filp) fput(server->info_filp); out_bdi: bdi_destroy(&server->bdi); out_fput: /* 23/12/1998 Marcin Dalecki <*****@*****.**>: * * The previously used put_filp(ncp_filp); was bogus, since * it doesn't perform proper unlocking. */ fput(ncp_filp); out: put_pid(data.wdog_pid); sb->s_fs_info = NULL; kfree(server); return error; }
/* * lookup a volume by name * - this can be one of the following: * "%[cell:]volume[.]" R/W volume * "#[cell:]volume[.]" R/O or R/W volume (rwparent=0), * or R/W (rwparent=1) volume * "%[cell:]volume.readonly" R/O volume * "#[cell:]volume.readonly" R/O volume * "%[cell:]volume.backup" Backup volume * "#[cell:]volume.backup" Backup volume * * The cell name is optional, and defaults to the current cell. * * See "The Rules of Mount Point Traversal" in Chapter 5 of the AFS SysAdmin * Guide * - Rule 1: Explicit type suffix forces access of that type or nothing * (no suffix, then use Rule 2 & 3) * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W * if not available * - Rule 3: If parent volume is R/W, then only mount R/W volume unless * explicitly told otherwise */ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) { struct afs_vlocation *vlocation = NULL; struct afs_volume *volume = NULL; struct afs_server *server = NULL; char srvtmask; int ret, loop; _enter("{%*.*s,%d}", params->volnamesz, params->volnamesz, params->volname, params->rwpath); /* lookup the volume location record */ vlocation = afs_vlocation_lookup(params->cell, params->key, params->volname, params->volnamesz); if (IS_ERR(vlocation)) { ret = PTR_ERR(vlocation); vlocation = NULL; goto error; } /* make the final decision on the type we want */ ret = -ENOMEDIUM; if (params->force && !(vlocation->vldb.vidmask & (1 << params->type))) goto error; srvtmask = 0; for (loop = 0; loop < vlocation->vldb.nservers; loop++) srvtmask |= vlocation->vldb.srvtmask[loop]; if (params->force) { if (!(srvtmask & (1 << params->type))) goto error; } else if (srvtmask & AFS_VOL_VTM_RO) { params->type = AFSVL_ROVOL; } else if (srvtmask & AFS_VOL_VTM_RW) { params->type = AFSVL_RWVOL; } else { goto error; } down_write(¶ms->cell->vl_sem); /* is the volume already active? */ if (vlocation->vols[params->type]) { /* yes - re-use it */ volume = vlocation->vols[params->type]; afs_get_volume(volume); goto success; } /* create a new volume record */ _debug("creating new volume record"); ret = -ENOMEM; volume = kzalloc(sizeof(struct afs_volume), GFP_KERNEL); if (!volume) goto error_up; atomic_set(&volume->usage, 1); volume->type = params->type; volume->type_force = params->force; volume->cell = params->cell; volume->vid = vlocation->vldb.vid[params->type]; ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY); if (ret) goto error_bdi; init_rwsem(&volume->server_sem); /* look up all the applicable server records */ for (loop = 0; loop < 8; loop++) { if (vlocation->vldb.srvtmask[loop] & (1 << volume->type)) { server = afs_lookup_server( volume->cell, &vlocation->vldb.servers[loop]); if (IS_ERR(server)) { ret = PTR_ERR(server); goto error_discard; } volume->servers[volume->nservers] = server; volume->nservers++; } } /* attach the cache and volume location */ #ifdef CONFIG_AFS_FSCACHE volume->cache = fscache_acquire_cookie(vlocation->cache, &afs_volume_cache_index_def, volume, true); #endif afs_get_vlocation(vlocation); volume->vlocation = vlocation; vlocation->vols[volume->type] = volume; success: _debug("kAFS selected %s volume %08x", afs_voltypes[volume->type], volume->vid); up_write(¶ms->cell->vl_sem); afs_put_vlocation(vlocation); _leave(" = %p", volume); return volume; /* clean up */ error_up: up_write(¶ms->cell->vl_sem); error: afs_put_vlocation(vlocation); _leave(" = %d", ret); return ERR_PTR(ret); error_discard: bdi_destroy(&volume->bdi); error_bdi: up_write(¶ms->cell->vl_sem); for (loop = volume->nservers - 1; loop >= 0; loop--) afs_put_server(volume->servers[loop]); kfree(volume); goto error; }
void sf_done_backing_dev(struct sf_glob_info *sf_g) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19, 0) bdi_destroy(&sf_g->bdi); /* includes bdi_unregister() */ #endif }
static int cifs_read_super(struct super_block *sb, void *data, const char *devname, int silent) { struct inode *inode; struct cifs_sb_info *cifs_sb; int rc = 0; /* BB should we make this contingent on mount parm? */ sb->s_flags |= MS_NODIRATIME | MS_NOATIME; sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); cifs_sb = CIFS_SB(sb); if (cifs_sb == NULL) return -ENOMEM; spin_lock_init(&cifs_sb->tlink_tree_lock); cifs_sb->tlink_tree = RB_ROOT; rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); if (rc) { kfree(cifs_sb); return rc; } cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; #ifdef CONFIG_CIFS_DFS_UPCALL /* copy mount params to sb for use in submounts */ /* BB: should we move this after the mount so we * do not have to do the copy on failed mounts? * BB: May be it is better to do simple copy before * complex operation (mount), and in case of fail * just exit instead of doing mount and attempting * undo it if this copy fails?*/ if (data) { int len = strlen(data); cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); if (cifs_sb->mountdata == NULL) { bdi_destroy(&cifs_sb->bdi); kfree(sb->s_fs_info); sb->s_fs_info = NULL; return -ENOMEM; } strncpy(cifs_sb->mountdata, data, len + 1); cifs_sb->mountdata[len] = '\0'; } #endif rc = cifs_mount(sb, cifs_sb, data, devname); if (rc) { if (!silent) cERROR(1, "cifs_mount failed w/return code = %d", rc); goto out_mount_failed; } sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_op = &cifs_super_ops; sb->s_bdi = &cifs_sb->bdi; sb->s_blocksize = CIFS_MAX_MSGSIZE; sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ inode = cifs_root_iget(sb, ROOT_I); if (IS_ERR(inode)) { rc = PTR_ERR(inode); inode = NULL; goto out_no_root; } sb->s_root = d_alloc_root(inode); if (!sb->s_root) { rc = -ENOMEM; goto out_no_root; } /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */ if (cifs_sb_master_tcon(cifs_sb)->nocase) sb->s_d_op = &cifs_ci_dentry_ops; else sb->s_d_op = &cifs_dentry_ops; #ifdef CONFIG_CIFS_EXPERIMENTAL if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { cFYI(1, "export ops supported"); sb->s_export_op = &cifs_export_ops; } #endif /* EXPERIMENTAL */ return 0; out_no_root: cERROR(1, "cifs_read_super: get root inode failed"); if (inode) iput(inode); cifs_umount(sb, cifs_sb); out_mount_failed: if (cifs_sb) { #ifdef CONFIG_CIFS_DFS_UPCALL if (cifs_sb->mountdata) { kfree(cifs_sb->mountdata); cifs_sb->mountdata = NULL; } #endif unload_nls(cifs_sb->local_nls); bdi_destroy(&cifs_sb->bdi); kfree(cifs_sb); } return rc; }
int afs_fill_super(struct super_block *sb, void *data, int silent) { int code = 0; #if defined(HAVE_LINUX_BDI_INIT) int bdi_init_done = 0; #endif AFS_GLOCK(); if (afs_was_mounted) { printf ("You must reload the AFS kernel extensions before remounting AFS.\n"); AFS_GUNLOCK(); return -EINVAL; } afs_was_mounted = 1; /* Set basics of super_block */ __module_get(THIS_MODULE); afs_globalVFS = sb; sb->s_flags |= MS_NOATIME; sb->s_blocksize = 1024; sb->s_blocksize_bits = 10; sb->s_magic = AFS_VFSMAGIC; sb->s_op = &afs_sops; /* Super block (vfs) ops */ #if defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP) sb->s_d_op = &afs_dentry_operations; #endif /* used for inodes backing_dev_info field, also */ afs_backing_dev_info = kzalloc(sizeof(struct backing_dev_info), GFP_NOFS); #if defined(HAVE_LINUX_BDI_INIT) code = bdi_init(afs_backing_dev_info); if (code) goto out; bdi_init_done = 1; #endif #if defined(STRUCT_BACKING_DEV_INFO_HAS_NAME) afs_backing_dev_info->name = "openafs"; #endif afs_backing_dev_info->ra_pages = 32; #if defined (STRUCT_SUPER_BLOCK_HAS_S_BDI) sb->s_bdi = afs_backing_dev_info; /* The name specified here will appear in the flushing thread name - flush-afs */ bdi_register(afs_backing_dev_info, NULL, "afs"); #endif #if !defined(AFS_NONFSTRANS) sb->s_export_op = &afs_export_ops; #endif #if defined(MAX_NON_LFS) #ifdef AFS_64BIT_CLIENT #if !defined(MAX_LFS_FILESIZE) #if BITS_PER_LONG==32 #define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) #elif BITS_PER_LONG==64 #define MAX_LFS_FILESIZE 0x7fffffffffffffff #endif #endif sb->s_maxbytes = MAX_LFS_FILESIZE; #else sb->s_maxbytes = MAX_NON_LFS; #endif #endif code = afs_root(sb); out: if (code) { afs_globalVFS = NULL; afs_FlushAllVCaches(); #if defined(HAVE_LINUX_BDI_INIT) if (bdi_init_done) bdi_destroy(afs_backing_dev_info); #endif kfree(afs_backing_dev_info); module_put(THIS_MODULE); } AFS_GUNLOCK(); return code ? -EINVAL : 0; }
static struct fuse_conn *new_conn(struct super_block *sb) { struct fuse_conn *fc; int err; fc = kzalloc(sizeof(*fc), GFP_KERNEL); if (fc) { spin_lock_init(&fc->lock); mutex_init(&fc->inst_mutex); atomic_set(&fc->count, 1); init_waitqueue_head(&fc->waitq); init_waitqueue_head(&fc->blocked_waitq); init_waitqueue_head(&fc->reserved_req_waitq); INIT_LIST_HEAD(&fc->pending); INIT_LIST_HEAD(&fc->processing); INIT_LIST_HEAD(&fc->io); INIT_LIST_HEAD(&fc->interrupts); INIT_LIST_HEAD(&fc->bg_queue); atomic_set(&fc->num_waiting, 0); fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; fc->bdi.unplug_io_fn = default_unplug_io_fn; /* fuse does it's own writeback accounting */ fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; fc->dev = sb->s_dev; err = bdi_init(&fc->bdi); if (err) goto error_kfree; if (sb->s_bdev) { err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", MAJOR(fc->dev), MINOR(fc->dev)); } else { err = bdi_register_dev(&fc->bdi, fc->dev); } if (err) goto error_bdi_destroy; /* * For a single fuse filesystem use max 1% of dirty + * writeback threshold. * * This gives about 1M of write buffer for memory maps on a * machine with 1G and 10% dirty_ratio, which should be more * than enough. * * Privileged users can raise it by writing to * * /sys/class/bdi/<bdi>/max_ratio */ bdi_set_max_ratio(&fc->bdi, 1); fc->reqctr = 0; fc->blocked = 1; fc->attr_version = 1; get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); } return fc; error_bdi_destroy: bdi_destroy(&fc->bdi); error_kfree: mutex_destroy(&fc->inst_mutex); kfree(fc); return NULL; }